Planetary Dev
Planetary Dev

Reputation: 51

Wrong rendering of input checkbox using metor/blaze and #each loop

We have a list with 3 entries (reactiveVar > array). By default the entry A will be checked.

[X] Test A
[ ] Test B
[ ] Test C

Now check all the other entries B and C.

After checking B and C it looks like this:

[X] Test A
[X] Test B
[X] Test C

Now we add a new default todo B1 between B and C by clicking the button "add B1". Normally this was done by an other user and we are using a mongo collection for the default-todos. To simplyfy this we are using a reactiveVar that produces the same probleme.

okay, after adding B1, the expected result should be:

[X] Test A
[X] Test B
[ ] Test B1
[X] Test C

BUT the entry B1 is also checked!!???? And I dont no why and how can i fix this.

[X] Test A
[X] Test B
[X] Test B1
[X] Test C

I've made a small repo to reproduce the problem. Please have a look at https://github.com/planetarydev/test-each-checkbox.git

and here is the template and helper function:

<template name="todos">
    <h2>Learn Meteor!</h2>
    <ul>
        {{#each todo in hTodos}}
            <li>
                <input type="checkbox" class="action-check" data-id="{{todo.id}}" checked={{hChecked todo.id}}>&nbsp;{{todo.description}}
            </li>
        {{/each}}
    </ul>
    <button class="add-todo">add B1</button>
</template>



import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';

import './main.html';

let tempChecked = {
    A: true
}

Template.todos.onCreated(function() {
  this.todos = new ReactiveVar([
      {id:'A', description:'Test A'},
      {id:'B', description:'Test B'},
      {id:'C', description:'Test C'}
  ]);
});

Template.todos.helpers({
  hChecked(id){
      var isChecked = (tempChecked[id] === true);
      console.log('isChecked:', id, isChecked);
      return isChecked;
  },

  hTodos(){
      return Template.instance().todos.get();
  }
});

Template.todos.events({
    'click .action-check': function(event, instance){
        var checked = $(event.target).is(':checked');
        var id = $(event.target).attr('data-id');
        console.log(id, checked);
        tempChecked[id] = checked;
    },

    'click .add-todo'(event, instance) {
        // add todo B1 between B and C
        instance.todos.set([
            {id:'A', description:'Test A'},
            {id:'B', description:'Test B'},
            {id:'B1', description:'Test B1'},
            {id:'C', description:'Test C'}
        ]);
    },
});

Have a look at the console-output the return value of the checkbox-helper for B1 is false.

isChecked: A true       <<-- By default A is checked
isChecked: B false
isChecked: C false
B true                  <<-- checking B
C true                  <<-- checking C

isChecked: C true       <<-- Click Button "add B1"
isChecked: A true
isChecked: B true
isChecked: B1 false     <<--- BUT, on the website the checkbox is checked

Upvotes: 0

Views: 168

Answers (1)

Michel Floyd
Michel Floyd

Reputation: 20227

The problem is that your tempChecked array is not reactive so the helper is not updating. I suggest that you keep the checked state inside your todos reactiveVar (simpler and cleaner) or make tempChecked itself reactive.

Upvotes: 1

Related Questions