aviemet
aviemet

Reputation: 1663

Wrong checkboxes being checked in Meteor

I have a bizarre issue with Meteor and likely Blaze as well.

I have a guest list with names displayed in a table. The first cell has a checkbox which sets the arrived flag on the record. The layout then filters the names so as not to display arrived guests.

For some reason, when checking a checkbox, it will perform the correct action on that record (change the flag and hide the row), but also leave the next name's checkbox checked without affecting that record at all.

Here's how it looks before I click the topmost record: enter image description here

And after I click the topmost record: enter image description here

Here's the relevant code:

client/Names.js:

Template.Names.helpers({
    names(){
        let listId = FlowRouter.getParam("listId");
        var list = Lists.findOne({_id: listId});
        return Lists.findOne({_id: listId}).names;
    }
});

Template.Names.events({ 
    names(){
        const instance = Template.instance();

        let listId = FlowRouter.getParam("listId");
        var filter = Session.get('filterQuery');
        var list = Lists.findOne({_id: listId});
        var showArrivedGuests = instance.state.get('showArrivedGuests');

        if(filter !== "" || !showArrivedGuests){            
            var pattern = stringToTerms(filter);
            var regex = new RegExp(pattern, 'i');

            // Filter results by search terms
            list.names = _.filter(list.names, function(name){
                if(!showArrivedGuests && name.arrived) return false;
                return (regex.test(name.firstName.tokenize()) || regex.test(name.lastName.tokenize()));
            });
        }

        let names = _.sortBy(list.names, Session.get('sortNames').term);
        return Session.get('sortNames').descending ? names : names.reverse();
    },
});

Template:

{{#each names}}
    <tr class="{{#if arrived}}arrivedChecked{{/if}}">
        <td class="arrived">
            <input type="checkbox" class="arrivedChecker" checked="{{arrived}}" id="name{{id}}" />
        </td>
        <td class="f_name">{{firstName}}</td>
        <td class="l_name">{{lastName}}</td>
        <td class="plus">{{plus}}</td>
        <td class="actions">
            <a class="delete alert"><i class="fa fa-times"></i></a>
        </td>
    </tr>
{{/each}}

Here's a link to the app if anyone would like to play around. I don't want to go through the trouble of removing user account verification, so you would have to make an account, make a list, then add names manually.

EDIT:

In the template, arrived is a boolean value in each name object.

I stored each name in an array nested in the Lists object, which also means that I generate the id for names manually.

When I originally posted, I didn't want to make a gigantic post with all my code, so I just posted what I thought was relevant. I decided to put it on GitHub though, so here's the link.

EDIT 2:

I just noticed that my delete button is doing something similar, when it's clicked and a record is deleted, the following delete button stops working.

Checked in the inspector, it looks like the checkbox and the delete buttons aren't actually disappearing on re-render, even though the template should clearly be excluding them. They disappear when I check and uncheck the 'Show Arrived Guests' box, but not in reaction to user input for some reason.

Could it have something to do with attached events? Do event listeners continue to exist on these elements even after they've been re-rendered out of the page? If so, should I be listening to click events on the table and rely on bubbling to figure out the origin?

Upvotes: 0

Views: 136

Answers (1)

Sudheer Jami
Sudheer Jami

Reputation: 757

I think the issue is with the way you apply checked value.

<input type="checkbox" class="arrivedChecker" {{checkArrived}} id="name{{id}}" />

Helper:

checkArrived: function() {
   var check = this.arrived;
   return check ? "checked" : "";
}

Source: here

Upvotes: 0

Related Questions