I have multiple checkboxes whose checked attributes represent boolean values in a collection. My code properly tracks the click event on the checkboxes and updates the values in the collection. However, when the page first loads, and when the user navigates away from the page, the checked attribute does not get set properly, despite the session and collection values being correct.
The html
<input type="checkbox" id="feedEmailSubscribe" checked={{isChecked}}>
Helper JS
Template.layout.isChecked = function () {
var id = $this.id;
return Session.get(id) ? "checked" : "";
};
I first pull down the collection and set a session variable for the checkbox via an 'invites' route
// invites
this.route('invites', {
path: ':_id/invited-guest/VIP',
waitOn : function () {
return Meteor.subscribe('guests', this.params._id);
},
data: function () {
Session.set('guestId', this.params._id)
return Guests.findOne({_id: this.params._id});
},
action : function () {
var q = Guests.findOne({_id: this.params._id});
if (this.ready()) {
Session.set('guestName', q.name);
Session.set('feedEmailSubscribe', q.feedEmailSubscribe);
//...I then redirect the user
}
},
});
I can verify the Sessions get set. Here is what I have for the settings route (where the checkbox exists)
// settings page
this.route('settings', {
path: '/settings',
waitOn : function () {
return Meteor.subscribe('guests', Session.get('guestId'));
},
data: function () {
return Guests.findOne({_id: Session.get('guestId')});
},
action: function () {
if (this.ready())
this.render();
},
onAfterAction: function() {
setPageTitle('Settings');
}
});
I can verify the Session exists and that it properly changes once clicked after page render. I suspect I'm either not using Blaze correctly as briefly discussed in the Blaze wiki, or I've got something wrong in my iron-router setup?
Thanks in advance for the help!
In the helper, your line
return Session.get(id) ? "checked" : "";
should be changed to
return Session.get(id) ? "checked" : false;
This is because the empty string generates the empty html attribute checked=""
. An empty boolean attribute represents a true value according to HTML spec. You have to omit the attribute in order to have a false value, this can be achieved by returning false
, null
or undefined
, according to the Meteor documentation as Bozhao referred.
Don't be surprised because the resulting code doesn't show up as an attribute. Blaze uses the element.checked
JavaScript attribute and not the checked
HTML attribute to actually set the checkedness. The HTML attribute only specifies the default value, and has no meaning once the user or a JS code has changed the checkedness. Blaze treats such specially the input value
, input checked
, textarea value
and option selected
attributes.