Search code examples
meteormeteor-blaze

Meteor Striking out text in element when checked


I am learning Meteor and I am trying to check a box for a task and have in turn JQuery strike out the text when it is checked. I have helpers in place that show me data the way I want it to and also event handler so that when the inout is checked it updates the db.

What I want is to be able to test if the db says 'completed' and if so strike out the a tag text. I have written a helper to do that but am unsure of where in the template to put the helper. I also would like to know if at the time of checking the box and the db being updated does the template re- render when there is a change in the db.

Here is my code:

<template name="item">
<div class="left" style="border-bottom:1px solid lightslategray;border-radius:.2em;">
    <div class="left"><!--left-->
        <li>
            <input class="items js-checked" id="checked" type="checkbox">
        </li>
        <li>
            <a href="#" class=" items js-update-task-form js-complete">
                {{task}}
            </a>
        </li>

        <div class="clear"></div>
    </div>
    <div class=" right  "><!--right-->
        <li class="items"><span class="label-position due">{{due}}</span></li>
        <li><span class="label label-info items priority-position {{priority}}"
                  id="{{priority}}">{{priority}}</span></li>
        <li>
            <button type="button" class="label label-info  trash js-delete-task"><span
                    class="glyphicon glyphicon-remove"></span></button>
        </li>
    </div>
    <!--<div class="clear"></div>-->
</div>

And here is the helper for the template:

 items: function() {
    var priority = $("#priority_sorter").val();

    /// TODO fix so this can be sorted by 'completed' as well

    var priority_val = Session.get('priority');
    var user = Meteor.user()._id;
    /// Filter by Priority
    if (priority_val === "All Tasks") {
        //console.log("First IF priority set to ", priority_val);
        return Items.find();

    } else {
        //console.log("Else statement priority value is "+ priority_val+ ". With User ID "+ user);
        return Items.find({owner: user, "priority": priority_val}, {sort: {"created": -1}});
    }
},
isComplete: function(){
    var task = Items.thisId.checked;
    if(Items.thisId.checked === 'complete'){
        console.log("Checked confirmed for "+ task);
        $('.js-complete').wrap("<strike>");
    }
},

Solution

  • The "Meteor Way" to do this is as follows (with no need to use JQuery):

    First a very simple CSS

    .completed{
       text-decoration: line-through;
    }
    

    Then use the helper isComplete within the class attribute of the DOM element you want to strikeout.

    <template name="item">
      <div class="left" style="border-bottom:1px solid lightslategray;border-radius:.2em;">
        <div class="left"><!--left-->
          <li>
            <input class="items js-checked" id="checked" type="checkbox">
          </li>
          <li>
            <a href="#" class=" items {{isComplete}}">
              {{task}}
            </a>
          </li>
    
          <div class="clear"></div>
        </div>
        <div class=" right  "><!--right-->
          <li class="items">
            <span class="label-position due">{{due}}</span>
          </li>
          <li>
            <span class="label label-info items priority-position {{priority}}" id="{{priority}}">{{priority}}</span>
          </li>
          <li>
            <button type="button" class="label label-info  trash js-delete-task">
              <span class="glyphicon glyphicon-remove"></span>
            </button>
          </li>
        </div>
        <!--<div class="clear"></div>-->
      </div>
    </template>
    

    Then the make template helper return the class name for striking out text if task is completed:

    Template.item.helpers({
      isComplete: function(){
        // This would represent the current item being iterated over
        return this.checked ? 'completed' : '';
      }
    });
    

    This code is reactive, meaning it will update automatically when the underlying data changes.