Skip to content
Tim van den Eijnden edited this page Nov 4, 2015 · 8 revisions

What you will learn

  • Render filtered content
  • Bind the search box
  • Filter the products
  • Use more computed properties

Before you start

See the installation instructions. Use tag 5.0.0.

Render filtered content

  • Enter the command ember g controller products.
  • Open frontend/app/controllers/products.js.
  • Define a new property filteredContent that gets rendered by the products template (search capabilities will follow). This property will get updated when model changes:
  filteredContent: Ember.computed('model', function() {
    var products = this.model;

    return products;
  })
  • Open frontend/app/templates/products.hbs and update the {{each}} helper:
<div class='products'>
  {{#each filteredContent as |product|}}
    ...
  {{/each}}
</div>

Bind the search box

  • Open frontend/app/templates/application.hbs.
  • Bind the value of the Search input to a search property by changing:
<input type='text' class='form-control' placeholder='Search'>

into

{{input value=search class='form-control' placeholder='Search'}}

Since the application template is backed by the ApplicationController, the search property belongs to this controller. We need this however, in the ProductsController to filter the content.

  • Open frontend/app/controllers/products.js and add the following code:
export default Ember.Controller.extend({
  application: Ember.inject.controller(),
  ...
});

Filter the products

  • Open frontend/app/controllers/products.js and update the implementation for filteredContent to:
filteredContent: Ember.computed('model', 'application.search', function() {
  var products = this.model;
  products = products.filterBy('title', this.get('application.search'));
  return products;
})
  • In the browser, use the Ember Inspector to find a title to search for and try this out.

Functional, but not very useful. But if this is all you need, you're done. Let's make it better.

  • Update the implementation for filteredContent to:
filteredContent: Ember.computed('model', 'application.search', function() {
  var products = this.model,
      search = new RegExp(this.get('application.search'), 'i');

  products = products.filter(function(product) {
    var str = product.get('title') + product.get('description');
    return search.test(str);
  });
  return products;
})

Use more computed properties

  • In the app, select a product and search for a keyword that's not in the selected product.
  • Now edit the product so its title or description contains the keyword and save the changes. Notice that the search results are not updated.
  • Update the implementation for filteredContent to:
filteredContent: Ember.computed('model', 'application.search', '[email protected]', '[email protected]', function() {
    ...
})
  • Now repeat the first step.

Bonus: Refactor

Although the search keyword is used in only one place, we can make the code a little more readable by doing some refactoring.

  • Open frontend/app/controllers/products.js and update the code as follows:
export default Ember.Controller.extend({
  ...
  search: Ember.computed.alias('application.search'),
  filteredContent: Ember.computed('model', 'search', '[email protected]', '[email protected]', function() {
    var products = this.model,
        search = new RegExp(this.get('search'), 'i');

    products = products.filter(function(product) {
      var str = product.get('title') + product.get('description');
      return search.test(str);
    });
    return products;
  })
});
Clone this wiki locally