Search code examples
javascriptmeteormeteor-blazespacebars

ng-repeat + filter like feature in Meteor Blaze/Spacebars


I am from AngularJS background, recently start learning Meteor.

In AngularJS, I may have something like:

<div ng-repeat="person in persons | filter:search">
   <h4>{{person.name}}</h4>
   <b>{{person.age}}</b>
</div>

search object can be bound (2-way bound) to HTML textbox. Whenever the textbox changed, the filter will be automatically updated.

How to do so in Meteor?


Solution

  • I am not familiar with AngularJS, but here is an example of how you would accomplish this with Meteor.

    This example shows a list of persons, along with an HTML number input that you can use to filter by age the displayed list.

    client/views/persons/persons.html

    <template name="persons">
      <input class="age" type="number" value="{{filter}}">
      <ul>
        {{#each personsFiltered}}
          {{> person}}
        {{/each}}
      </ul>
    </template>
    
    <template name="person">
      <li>{{name}} is {{age}}</li>
    </template>
    

    client/views/persons/persons.js

    // dummy collection for testing purpose, living only in the client
    // (not backed by a real server-side persistent collection)
    Persons=new Mongo.Collection(null);
    
    // dummy dataset
    Persons.insert({
      name:"Alice",
      age:25
    });
    Persons.insert({
      name:"Bob",
      age:35
    });
    Persons.insert({
      name:"Charlie",
      age:18
    });
    
    // on create, initialize our filter as a ReactiveVar
    // need to meteor add reactive-var to use this
    Template.persons.created=function(){
      this.filter=new ReactiveVar(20);
    };
    
    Template.persons.helpers({
      // value of the filter to initialize the HTML input
      filter:function(){
        return Template.instance().filter.get();
      },
      // reactively return the persons who are older than the input value
      personsFiltered:function(){
        return Persons.find({
          age:{
            $gt:Template.instance().filter.get()
          }
        });
      }
    });
    
    // bind the value of the input to the underlying filter
    Template.persons.events({
      "input .age":function(event,template){
        var currentValue=template.find(".age").valueAsNumber;
        template.filter.set(currentValue);
      }
    });