Filter Collections using iron-router - meteor

I have a template rendering my Collection using {{#each Collection}}, I'm using iron-router to route this template like this:
Router.route('/home', function () {
this.render('home');
this.layout('header');
});
how can i use a "books" filter button so iron-router apply that filter to the subscription so i can only see the filtered version of my Collection like the following:
Collection.find({category: "books"});

There are a number of ways to approach this but one simple way would be to define a sub-route that takes a category as a parameter:
Router.route('/collections/:category',{
name: 'collections',
layoutTemplate: 'header',
data(){
return Collections.find({category: this.params.category});
}
});
Then your button code can just do Router.go('/collections/books') but you can now have multiple buttons each tied to different categories.

As suggested here https://guide.meteor.com/data-loading.html#organizing-subscriptions you can manage your subscription in Template and not in the route. So you can do:
import {ReactiveDict} from 'meteor/reactive-dict';
import {Template} from 'meteor/templating';
Template.home.onCreated(function(){
var that = this;
that.state = new ReactiveDict();
//that.state.set('selected-category',YOUR_DEFAULT_CATEGORY);
that.autorun(function(){
that.subscribe('subscription-name',that.state.get('selected-category'));
});
});
Template.home.events({
'click .js-category':function(e,tpl){
let category = tpl.$(e.currentTarget).data('category');
tpl.state.set('selected-category',category);
}
});
And in your Template:
<button type="button" data-category="books" class="js-category">Books</button>
Hope this will help you to find the right solution for your

Related

how to find document in mongodb with its id passed in textbox?

I am learning mongodb with meteor js so dont have much knowledge of both mongodb and meteor.
Below is the js code:
import { Template } from 'meteor/templating';
import { Dbs } from '../lib/collections.js';
import './main.html';
Template.body.helpers({
/*temp1:[
{text:'my data1'}'
{text:'my data1'}
]*/
dbs(){
return Dbs.find({'user_id':'p123'});
}
});
Basically i just want to pass user id in a textbox and based on it,i want to display the other details of user.In above code i am passing it manually and its working.anyone suggest me what should i do here ?
You can attach to the template instance a ReactiveVar that you will update with an event.
Then use it inside the helper, so the helper will re-execute everytime the value change:
Template.myTemplate.onCreated(function() {
this.currentTextBox = new ReactiveVar();
});
Template.myTemplate.events({
"keyup .js-my-textbox"(event, instance) {
// This event is executed when you type in an input with the class "js-my-textbox"
instance.currentTextBox.set(event.target.value);
},
});
Template.myTemplate.helpers({
dbs() {
const instance = Template.instance();
return Dbs.find({'user_id': instance.currentTextBox.get() });
},
});
EDIT:
Example of what could be the html part:
<template name="myTemplate">
<input type="text" placeholder="Search" class="js-my-textbox">
{{#each db in dbs}}
<-- Do what you want, example: -->
<p>{{db.myField}}</p>
{{/each}}
</template>
First You Create Event Function Template.body.events({}) to access text .Then store variable to use Meteor Session. Then Variable easily access helpers.If session changes variable will be changed.

Iron-router set notFoundTemplate when no data found in database

How can I set a layout when my data function returns null.
For example, in the route below, when chefs is null, I would like to render my 'notFound' template.
Router.route('/vendors/chefs/:_url', {
template: 'chefs',
data: function() {
var chefs = Chef_db.findOne({url: this.params._url});
return chefs;
}
});
Take a look at the notFoundTemplate in the documentation: https://github.com/iron-meteor/iron-router/blob/devel/Guide.md
You can apply it globally:
Router.plugin('dataNotFound', {notFoundTemplate: 'notFound'});
Or you can apply it to specific routes using the except/only options:
Router.plugin('dataNotFound', {
notFoundTemplate: 'NotFound',
except: ['server.route']
// or only: ['routeOne', 'routeTwo']
});
There's a built-in plugin for that. It's called dataNotFound. It's mentioned in the iron:router guide.

IronController Helpers not working

i am farely new to meteor, so it might be obvious.
I am trying to define some routes:
Router.route('/translations', {name:'translation.index'});
Router.route('/translations/:_id', {name:'translation.show'});
I also have defined a Controller which should define how to get the Data:
TranslationIndexController = RouteController.extend({
template: 'TranslationIndex',
data: function () {
return Translations.find();
},
sayHello: function(){
return 'hello';
}
});
I have some Collection that is just fetched and some random tempalte helper. My template looks like this:
<template name="TranslationIndex">
TestOutput:
{{sayHello}}
{{#each data}}
<li>askljdfh</li>
{{/each}}
</template>
But neither my hello nor my collection is shown. PS: I have checked if my collection contains data by using Translations.find().count() in the console.
You need to call the controller in your route, e.g.,
Router.route('/translations', {
name:'translation.index',
controller: TranslationIndexController
});
The data should then be available.

How to pass functions to capture events in custom component in Meteor with Blaze

I want to know how to bind/set template-passed-parameter-value to click event of an item in the template in Meteor.
I'm using Meteor 0.7.0.1 with Blaze UI package. My main idea is to build a re-usable custom components in Meteor with Blaze template engine.
I have the following component which is working fine at the moment but I want this to be more customizable and remove some dependencies.
This is my component template named postLinks
<template name="postLinks">
<div id="link-popover-wrapper" >
<ul class="link-popover">
{{#each linkOptions}}
<li><a tabindex="-1" class="link-action" id="link-{{value}}" href="#">{{label}}</a>
</li>
{{/each}}
</ul>
</div>
</template>
This postLinks component is used in the myPostItem helper.
Template.myPostItem.events({
'click .post-item-link-picker': function (evt, tmpl) {
var tmpPostId = this._id;
var tempData = {linkOptions:[{label:'Favorite', value : 'favorite'},{label:'Wish list', value : 'wishlist'},{label:'Later', value : 'later'}, {label:"Read", value:"read"}]};
var linkContent = Template.postLinks(tempData);
$(".item-link-picker").popover({
content: linkContent, html: true, placement: 'bottom', trigger: "manual",
template: "UI_POPOVER_TEMPLATE"});
$("#item-link-picker-"+tmpPostId).popover('show');
},
'click .link-action': function (evt, tmpl) {
//.... some code here to update link selection in db
}
});
Above code is working fine and I want to improve it to have following
Pass item click event externally to be bind to link-action like
After above two changes it will look like :
Template.myPostItem.events({
'click .post-item-link-picker': function (evt, tmpl) {
var tmpPostId = this._id;
var tempData = { itemClick:function(){}, linkOptions:[{label:'Favorite', value : 'favorite'},...]};
var linkContent = Template.postLinks(tempData);
$(".item-link-picker").popover({
content: linkContent, html: true, placement: 'bottom', trigger: "manual",
template: "UI_POPOVER_TEMPLATE"});
$("#item-link-picker-"+tmpPostId).popover('show');
}
});
I lack knowledge how/where to bind that passed event handling function to link-action elements in template or helper. I really appreciate if anybody could help to find a way to do that.
You go the other way around and use jQuery event triggering system, so
Template.myPostItem.events({
'click .link-action': function (evt, tmpl) {
$(evn.target).trigger('post-link-action', this /* extra data */);
},
});
This event can be easily catched in any parent template:
<template name="someOtherTamplate">
{{> myPostItem}}
</template>
Template.someOtherTemplate.events({
'post-link-action': function (evt, tmpl, extra) {
// the user of your component can define their custom behavior here
},
});
Please note that the event extra parameter will only be supported in the next Meteor release. Currently (0.8.0) it is included in the devel branch.

meteor app: how to properly use a button to influence the route

I'm working on a survey/wizard type of meteor application.
The interface will only have two navigation buttons, who's caption/value will be determined dynamically based on whatever step a given user is currently at.
My question is: what markup syntax should I use within each of these two button's definitions in order to direct the Iron Router to change the route. Another words, where in the button definition should I put this: this.redirect('/anotherpath') ?
If you have a button in your template. If you are using a hrefs check answer from f3rland.
html:
<button #id="mybutton>m<Button</button>
you can catch the buttonpress event with javascript
js
Template.myTemplate.events({
'click #myButton': function(event, template) {
event.preventDefault();
Router.go('anotherpath');
}
});
The router should look like:
Router.map(function() {
this.route('anotherpath', {
path: '/',
layoutTemplate: 'myLayout',
controller: myController
});
});
I suggest you to use Iron-Router pathFor helper in your template
{{buttonText}}
That will redirect the user to the corresponding page/template.
You should also take a look at new blaze pattern to define custom block helper
Edit:
You could also use a custom helper for dynamic route as mentioned here
UI.registerHelper("_foo", function fooHelper() {
var templateName = figureOutNameDynamically(this.context.criticalInfo);
return Template[templateName];
});
<template name="foo">
{{> _foo context=.. atts=this}}
</template>
you can do this/change the route by using the action option which will automatically cal this.render().
you can do it yourself by calling the action function but I guess it is better to use onBeforeAction/after hooks

Resources