I have a page which shows all Stories. I have added a filter form where you can select a priority and then the page should only show the stories with that priority. This is the form:
<form name="filter_form">
<select name="prio" class="form-control">
<option value=1>High</option>
<option value=2>Medium</option>
<option value=3>Low</option>
</select>
<button type="submit" class="btn btn-default">Filter</button>
</form>
This is the code to show all stories:
<div class="stories">
{{#each stories}}
{{> storyItem}}
{{/each}}
</div>
And this is the form handler:
Template.storiesList.events({
'submit form': function(e) {
e.preventDefault();
var prio = $(e.target).find('[name=prio]').val();
var stories = Stories.find({prio: prio});
return stories;
}
});
I guess it isn't this easy to just do a find query and return the results, because nothing happens at the moment. What am I doing wrong here?
You need to define stories as a reactive helper. Then you can use a Session variable to link the event to the list:
Template.storiesList.helpers({
'stories': function() {
return Stories.find({prio: Session.get('prio')});
}
});
Template.storiesList.events({
'submit form': function(e) {
e.preventDefault();
var prio = parseInt($(e.target).find('[name=prio]').val());
Session.set('prio'), prio);
}
});
Related
I've been around this all day and i can't figure why my each cycle is not working. I'm trying to create a dropdown with some countries.
Helper
Template.register.helpers({
countries: function(){
return Country.find({ });
},
});
View, template register
<select id="country-select">
<option disabled="disabled" selected="selected">Please Select</option>
{{#each countries}}
<option value={{ name }}>{{ name }}</option>
{{/each}}
</select>
I have records in the country collection
meteor:PRIMARY> db.country.find({ }).count() ->
4
The only options that the dropwdown displays is the placeholder.
I'm using mongol this is a country record
Try this...
<option disabled selected>Please select</option>
{{#each countries}}
<option>{{name}}</option>
{{/each}}
It works here
Try
return Country.find().fetch()
in the helper
Thanks
Hope it helps
"The solution that worked for me is by calling the 'material_select' function after the options data has been loaded.
Template.[name].rendered = function() { this.autorun(function() { var optionsCursor = OptionsList.find().count(); if(optionsCursor > 0){ $('select').material_select(); } }); };"
from https://github.com/Dogfalo/materialize/issues/1469
I'm trying to study Meteor with a simple example to populate two dropdowns where one is a list of fruit and another one is the color according to the fruit chosen:
collection (ProductList):
a = new Array();
a.push({color:"orange"});
a.push({color:"red"});
ProductList.insert({ product: "Orange", a });
a = new Array();
a.push({color:"green"});
a.push({color:"red"});
ProductList.insert({ product: "Apple", a });
a = new Array();
a.push({color:"green"});
a.push({color:"yellow"})
ProductList.insert({ product: "Banana", a });
html (dropdown menu):
<template name="prodlist">
<select id="category-select">
<option disabled="disabled" selected="selected">Please Select</option>
{{#each prodlist}}
<option value="{{this}}">{{this}}</option>
{{/each}}
</select>
</template>
js:
Template.prodlist.events({
"change #category-select": function (event, template) {
var category_prod = $(event.currentTarget).val();
//this return the correct element selected in the dropdown(i.e Orange Apple Banana)
console.log("category : " + category_prod);
var productID = ProductList.findOne({product: category_prod })._id
console.log("current ID: " + productID);
}
});
Please see the ****** above for my first question This has been solved by chrisklaussner. Code updated.
Also I'm trying to feed the ._id (saved to productID) found to the second dropdown:
html:
<template name="colorlist">
<select id="category-select">
<option disabled="disabled" selected="selected">colors</option>
{{#each colorlist}}
<option value="{{this}}">{{this}}</option>
{{/each}}
</select>
</template>
js:
Template.colorlist.helpers({
colorlist: function () {
const ans = productID.get();
const product = ProductList.findOne({ _id: ans});
if (product) {
return product.a.map(function (doc) {
return doc.color;
});
}
}
});
Please see the ****** above for my second question This has been resolved.
EDIT: This question has been resolved and the Original post contains the correct answer
You have a mistake in the findOne calls. The first parameter (where you pass {}) is the selector that specifies what you want to fetch. The second one is for options.
For example, ProductList.findOne({ product: category_prod })._id should give you the right product ID. In your case, the selector {} matches all products in the collection and findOne returns the first of them. That's why you always get the same ID.
I'm having issues finding a way to update the UI AFTER adding to a collection. So in the example below after you click the button and add to the collection an additional input is added to the DOM. All good, but i'd like to find a way to target the new input element and preferably give it focus in addition to CSS. Unfortunately I can't find any info that helps solve this AFTER the DOM's been updated. Any ideas? Thanks
<body>
{{> myTemplate}}
</body>
<template name="myTemplate">
{{#each myCollection}}
<input type="text" value="{{name}}"><br>
{{/each}}
<br>
<button>Click</button><input type="text" value="test" name="testBox">
</template>
test = new Meteor.Collection("test");
if (Meteor.isClient) {
Template.myTemplate.rendered = function()
{
console.log("rendered");
this.$('input').focus()
}
Template.myTemplate.helpers({
'myCollection' : function(){
var testCollection = test.find({});
console.log("helpers");
return testCollection;
}
});
Template.myTemplate.events({
'click button': function(event){
event.preventDefault();
var val = $('[name="testBox"]').val();
console.log("events");
return test.insert({name: val});
}
});
}
Turn what you're adding into a template and call that template's rendered to set the needed css or do whatever transforms are needed.
HTML:
<body>
{{> myTemplate}}
</body>
<template name="item">
<input type="text" value="{{name}}"><br>
</template>
<template name="myTemplate">
{{#each myCollection}}
{{> item this}}
{{/each}}
<br>
<button>Click</button><input type="text" value="test" name="testBox">
</template>
JS:
test = new Meteor.Collection("test");
if (Meteor.isClient) {
Template.myTemplate.onRendered(function() {
console.log("rendered");
this.$('input').focus()
});
Template.myTemplate.helpers({
'myCollection' : function(){
var testCollection = test.find({});
console.log("helpers");
return testCollection;
}
});
Template.myTemplate.events({
'click button': function(event){
event.preventDefault();
var val = $('[name="testBox"]').val();
console.log("events");
test.insert({name: val});
}
});
Template.item.onRendered(function() {
this.$('input').focus();
}
}
On a side note, you should use onRendered instead of rendered as the latter has been deprecated for the former.
Do it inside of your myCollection helper function. Use jquery to target the last input in your template and focus it, add css. Meteor's template helpers are reactive computations based on the DOMs usage of their reactive variables, so it will run each time the DOM updates based on your collection.
I am trying to run the query shown below through a server method, unfortunately the data inside the array returned by this query is not displayed in my template, what am I missing / doing wrong here?
/server/methods.js
Meteor.methods({
'getCategoriesEx': function () {
return Categories.find({children: {$size: 0}},{sort: {name: 1}}).fetch();
}
});
/client/categories.js
Template.Categories.rendered = function() {
};
Template.Categories.helpers({
categories: function() {
Meteor.call('getCategoriesEx', function(error, list){
if(error)
return alert(error.reason);
return list;
});
}
})
/client/categories.html
<div class="col_half">
<label for="categories"> categories </label>
<select id="categories" name="categories" class="sm-form-control">
<option value="">-- Select One --</option>
{{#each categories}}
<option value="{{_id}}">{{name}}</option>
{{/each}}
</select>
</div>
Data returned by the query:
[Object, Object, Object, Object]
0: Object
_id: "Pwmd9wFTf8zs8nbWn"children: Array[0]title: "A1"__proto__: Object
1: Object
2: Object
3: Object
You are not using a reactive data source in your helper. Restructure it to use client side reactive mini mongo queries by publishing your data.
So something like this:
Server:
Meteor.publish("categories", function() { return Categories.find(); }
Client:
Template.Categories.created = function() {
Meteor.subscribe("categories");
};
Template.Categories.helpers({
categories: function() {
return Categories.find({children: {$size: 0}},{sort: {name: 1}});
}
})
Chris's answer is the standard way to do things, however you've specifically stated that you're trying to use a method so I assume there's a reason for that.
The problem is that your helper is returning nothing at the point that it's called (it called the method and returns immediately). At the point that your callback is called back there's nothing to return the data to.
One solution would be to update a reactive variable instead. For example, using the Sessions object.
Also note that helpers can be called frequently. You probably don't really want to be calling the server method each time an helper is called. A better place to put that would be the rendered code. So (untested):
Template.Categories.rendered = function() {
Meteor.call('getCategoriesEx', function(error, list){
if(error)
alert(error.reason);
Session.set('categories', list);
});
}
Template.Categories.helpers({
categoriesResult: function() {
return Session.get('categories')
})
and
<div class="col_half">
<label for="categories"> categories </label>
<select id="categories" name="categories" class="sm-form-control">
<option value="">-- Select One --</option>
{{#each categoriesList}}
<option value="{{_id}}">{{name}}</option>
{{/each}}
</select>
</div>
I need some help with meteor. I've template with select options:
<select id="collapseFour" class="form-control collapse">
{{#each examNum}}
<option>{{this}}</option>
{{/each}}
</select>
And I've helper that helps me in creating list of exam numbers:
Template.adminLayout.helpers({
examNum: function() {
var number = [];
for(var i=1;i<=50;i++){
number[i] = i;
}
return number;
}
});
I need to make page redirect to the specified exam page, when I choose one of the options. Like onchange, or href in a tag element. I know that it can be solved with helpers, so tried this:
Template.adminLayout.helpers({
'change [type=select]': function(e,t){
// page redirect
},
});
But it doesn't work. What can choose the problem, any help will be appreciated!
Already solved, just in case if somebody needs. Here is the template:
<select id="collapseFour" name="examNo" class="form-control collapse">
{{#each examNum}}
<option value="{{this}}">{{this}}</option>
{{/each}}
</select>
Js file:
Template.adminLayout.events({
'change #collapseFour': function(event, template) {
no = template.find('[name=examNo]').value;
Router.go('adminExamPage', {no: no});
}
});
And router.js:
this.route('adminExamPage',{
path: '/coordinator/exam/:no',
layoutTemplate: 'adminLayout'
});