Meteor IF statement should be firing - meteor

I'm stumped as to why part of my code isn't displaying when the session variable is set to true. When the user selects a certain option from the dropdown, based on the value, it changes the warmerselected to TRUE. I have tracked this in the console, and it works just fine.
Here is my code:
HTML:
<div class="item">
<div class="ui label">Product Type:</div>
<select id="ProductType" name="ProductType">
{{#each ProductTypes}}
<option value="{{ProductTypeAbbrev}}">{{ProductTypeName}}</option>
{{/each}}
</select>
</div>
{{#if warmerselected}}
<div class="item">
<div class="ui label">Name:</div>
<input type="text" name="ProductName" placeholder="Enter Product Name">
</div>
{{/if}}
JS:
Session.setDefault("warmerselected", false);
Template.addProduct.events({
'change #ProductType': function (e) {
var selitem = $("#ProductType").val();
if(selitem == "WA") {
Session.set("warmerselected",true)
}else {
Session.set("warmerselected",false);
}
}
});

Template.addProduct.helpers({
warmerselected: function(){
return Session.get("warmerselected");
}
});
Session isn't meant to be helper in HTML, you have to create one

Related

meteor onRendered not called

I’m trying to have a reactive bootstrap selectpicker but I have a weird behaviour:
An event has to change the options of the select but it works only after the first event which is not working because the app doesn’t go into the onRendered part…
This is the onRendered part:
var renderTimeout = false;
Template.printerselect.onRendered( function(){
if (renderTimeout !== false) {
Meteor.clearTimeout(renderTimeout);
}
renderTimeout = Meteor.setTimeout(function() {
$('#printerName').selectpicker("refresh");
renderTimeout = false;
}, 10);
});
Template.printerSetupForm.onRendered( function(){
$('.selectpicker').selectpicker();
});
here, the templates :
<div class="col-lg-3 col-md-4 col-xs-12 form-group">
<label>COMPANY</label>
<select id="printerCompany" class="form-control selectpicker" name="printer[company]">
<option selected="true" disabled="disabled" value={{company}}>
Please Select A Printer Company
</option>
{{#each Companies}}
<option value="{{company}}" {{printerCompanySelected company}}> {{company}}</option>
{{/each}}
</select>
</div>
<div class="col-lg-3 col-md-4 col-xs-12 form-group">
<label>PRINTER NAME</label>
<select id="printerName" class="form-control selectpicker" name="printer[name]">
<option selected="true" disabled="disabled" value={{name}}>
Please Select A Printer
</option>
{{#each Names}}
<!--<option value="{{name}}" {{printerNameSelected name}}>
{{name}}
</option>-->
{{>printerselect}}
{{/each}}
</select>
</div>
<template name="printerselect">
<option value="{{name}}"> {{name}} </option>
</template>
The refresh is called when the page is rendered.
Then I change the company which changes some Session variables and reactively to change the name select options but the refresh is not called so that doesn’t come to the onrendered part.
But when I change again the company it’s working, the onRendered part is called.
Weird thing is that even if this is not displaying the right names, when i’m choosing a name which doesn’t match with the company, the select chooses the right one.
Sorry for my english in advance, I did my best.
Thanks you in advance !
EDIT: Names helper :
Names: () => {
company=Session.get('printer').company;
if(typeof company!='undefined') {
return Printers.find({company: company}).fetch();
} else {
return Printers.find().fetch();
}
}
I set the Session variable 'printers' with an empty field. When I select a company, it's now working but without company, I don't get any printers because I don't have to test company with 'undefined' but with empty field.
So I changed to test with empty field and it isn't working anymore...
So weird that a test could cancel a onRendered, this must be an issue with the Mongo stuff.
I will continue to search on it.

Meteor: No context for #each loop event handlers

I'm using an #each loop with an unmanaged local collection to generate a sequence of input fields for a form. However, when I try to use this._id in the event handler it is undefined. In fact, the context being passed to the event handler is for the window. Any help to find what is going wrong and how I should be getting the proper context as this within my event handler is much appreciated.
The code is:
<h4 class="page-header">Children on this account</h4>
{{#each children}}
<div id={{_id}} class="form-group col-md-12 child-form-instance">
<div class="form-group col-sm-5 col-xs-12">
<input type="text" name="childFirstName" class="form-control" placeholder="Child's First Name">
</div>
<div class="form-group col-sm-5 col-xs-10">
<input type="text" name="childLastName" class="form-control" placeholder="Child's Last Name" value="{{_id}}">
</div>
<div class="form-group col-xs-2">
<button type="button" class="btn btn-danger remove-child" aria-label="remove child">
<span class="glyphicon glyphicon-trash"></span>
</button>
</div>
</div>
{{/each}}
<div class="form-group">
<input type="button" id="addChild" class="btn btn-success" value="Add child">
</div>
and the js:
var children = new Mongo.Collection(null);
Template.signup.onRendered( () => {
Modules.client.signupValidateSubmit({
form: "#signup",
template: Template.instance()
});
children.remove({});
children.insert({}); //create one empty child
});
Template.signup.events({
'submit form': ( event ) => event.preventDefault(),
'click #addChild': () => {
children.insert({});
console.log(children.find().fetch());
},
'click .remove-child': () => {
console.log(this);
}
});
Template.signup.helpers({
children () {
return children.find();
}
});
Everything is working fine with the addChild button, and the _ids are getting properly assigned in the DOM, but the remove-child class is logging the window context.
You are using ES6 arrow functions which will lexically bind this with the parent scope. As a consequence, you don't get the scope of children.
In order to solve the issue, just change the template event to:
Template.signup.events({
// ...
'click .remove-child': function (event, template) {
console.log(this);
}
// ...
});

filter collection on dropdownlist change

i'm trying to filter my collection on dropdownlist change , here's my code in the template manager
Template.postsList.events({
"change .typeselection": function(e, t){
console.log("drop changed");
return Session.set("type", $("[name=type]").val());
}
});
here's my template code :
<template name="postsList">
<select name="type" id="type" value="" placeholder="type the adress" class="form-control typeselection">
<option value="Restaurant">Restaurant</option>
<option value="Hotel">Hotel</option>
<option value="Shop">Shop</option>
</select>
<div class="posts">
{{#each postsWithRank}}
{{> postItem}}
{{/each}}
{{#if nextPath}}
<a class="load-more" href="{{nextPath}}">Load more</a>
{{else}}
{{#unless ready}}
{{> spinner}}
{{/unless}}
{{/if}}
</div>
</template>
From my understanding,this code works for you
//on dropdown change we are setting the new value in session
Template.postsList.events({
"change .typeselection": function(e, t){
console.log("drop changed");
Session.set("type", $("[name=type]").val());//no need to return anything here
}
});
//whenever the session variabe changes this code will re run
Template.postsList.helpers({
"postsWithRank": function(){
//assuming you have type field in your collection and you want filter on that field
return Posts.find({"type":Session.get("type")});
}
});
//so this code will display the selected relative data
{{#each postsWithRank}}
{{> postItem}}
{{/each}}

Form validation in meteorjs

I am doing simple validation of inputs in meteorjs, after first tour it works, and every next time it doesn't work (until I reload the page) – it means error messages are not displayed.
//main.js//
Template.addMealForm.events({
'click #submitNewMeal': function (ev) {
ev.preventDefault();
var query = {
name: $("#name").val().trim(),
price: $("#price").val(),
calories: $("#calories").val(),
category: $("#category").val()
};
areInputsValid(query);
}
});
var areInputsValid = function (query) {
if ((query.name.length === 0) || (query.price.length === 0) || (query.calories.length === 0)) {
$("#warningLabel").addClass("di")
$(".warningLabel").text("All fields are required");
}
else if ((isNaN(query.price) === true) || (isNaN(query.calories) === true)) {
$("#warningLabel").addClass("di")
$(".warningLabel").text("To Price and Calories fields please enter a number");
}
else {
console.log('it works');
$('.dn').hide();
}
};
//main.html//
<template name="addMealForm">
<form role="form">
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control input_form" id="name" placeholder="Name of the meal">
</div>
<div class="form-group">
<label for="price">Price</label>
<input class="form-control input_form" id="price" placeholder="Price">
</div>
<div class="form-group">
<label for="calories">Calories</label>
<input class="form-control input_form" id="calories" placeholder="Calories">
</div>
<div id="warningLabel" class="form-group has-error dn">
<label class="control-label warningLabel"></label>
</div>
<button id="submitNewMeal" type="submit" class="btn btn-rimary">Add</button>
</form>
</template>
The problem is that you are calling $('.dn').hide() in the success case. Because #warningLabel has a class of dn it will not be displayed again on subsequent errors.
One solution is to add $('.dn').show() to the top of areInputsValid.
You already have Tracker as part of Meteor, so I put a little tutorial and JSfiddle together on how to use it to implement a typical form validation scenario.
http://bit.ly/meteor-form-validation-video
http://bit.ly/meteor-form-validation-fiddle

Adding an user field to a Meteor record?

Right now, my Posts model has a title and a content field:
client/client.js:
Meteor.subscribe('all-posts');
Template.posts.posts = function () {
return Posts.find({});
};
Template.posts.events({
'click input[type="button"]' : function () {
var title = document.getElementById('title');
var content = document.getElementById('content');
if (title.value === '') {
alert("Title can't be blank");
} else if (title.value.length < 5 ) {
alert("Title is too short!");
} else {
Posts.insert({
title: title.value,
content: content.value,
author: userId #this show displays the id of the current user
});
title.value = '';
content.value = '';
}
}
});
app.html:
<!--headder and body-->
<div class="span4">
{{#if currentUser}}
<h1>Posts</h1>
<label for="title">Title</label>
<input id="title" type="text" />
<label for="content">Content</label>
<textarea id="content" name="" rows="10" cols="30"></textarea>
<div class="form-actions">
<input type="button" value="Click" class="btn" />
</div>
{{/if}}
</div>
<div class="span6">
{{#each posts}}
<h3>{{title}}</h3>
<p>{{content}}</p>
<p>{{author}}</p>
{{/each}}
</div>
</div>
</div>
</template>
I tried adding an author field (already did meteor add accounts-password and accounts-login):
author: userId
But it just shows the id of the current user who is logged in.
I would like it to show the email of the author of the post instead.
How to accomplish that?
I think you can get the email with
Meteor.users.findOne(userId).emails[0];
#danielsvane is correct, but since your Post document's author field stores the _id of the author and not the email address, you'll need a template helper in order for the template to know how to get the email address. Try the following:
// html
...
<div class='span6'>
{{#each posts}}
{{> postDetail}}
{{/each}}
</div>
...
<template name="postDetail">
<h3>{{title}}</h3>
<p>{{content}}</p>
<p>{{authorEmail}}</p>
</template>
// javascript
Template.postDetail.helpers({
// assuming the `author` field is the one storing the userId of the author
authorEmail: function() { return Meteor.users.findOne(this.author).emails[0]; }
});
If it's always showing the current user and not the user who is the author of the post, then the problem lies in how you're setting the value of the userId variable in your event handler, which isn't code that you showed in your question.

Resources