Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly set checkbox checked attribute from reactive data source on render

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!

like image 798
Chad Kruse Avatar asked May 02 '14 20:05

Chad Kruse


People also ask

How to use checked or defaultchecked attribute in checkbox input in react?

In this article, we will know how to use checked or defaultChecked attribute in checkbox input in React.js. The checked attribute can be used with a checkbox or RadioButton element. Step 1: Create a React application using the following command. Step 2: After creating your project folder i.e. foldername, move to it using the following command.

What is the checked attribute in <input>?

When present, it specifies that an <input> element should be pre-selected (checked) when the page loads. The checked attribute can be used with <input type="checkbox"> and <input type="radio">. The checked attribute can also be set after the page load, with a JavaScript.

What is the difference between true and false checkbox values?

true|false. Specifies whether a checkbox should be checked or not. true - The checkbox is checked. false - Default. The checkbox is not checked.

What is the checked property in HTML?

Definition and Usage. The checked property sets or returns the checked state of a checkbox. This property reflects the HTML checked attribute.


2 Answers

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.

like image 122
Bernát Avatar answered Nov 15 '22 10:11

Bernát


Found a potential solution: Upon render, I loop though all the checkboxes and apply "checked" according to how the corresponding session variable is set. Doesn't feel all that elegant though.

settings.js

Template.settings.rendered = function () {
  $(":checkbox").each(function(){
    console.log(this.id);
    if (Session.get(this.id, true)) {
      $(this).prop("checked", true);
    }
   });
};
like image 28
Chad Kruse Avatar answered Nov 15 '22 10:11

Chad Kruse