Filtering ListView in NativeScript

Here's how you filter a list.

<!-- demo.xml -->  
<Page navigatingTo="navigatingTo">  
  <StackLayout orientation="vertical">
    <TextField text="{{ filter }}" hint="Enter filter"/>
    <ListView items="{{ items }}" />
  </StackLayout>
</Page>  

This is a very basic page with a ListView component that is supposed to list string values and a TextField that we'll use for filtering purposes.

// demo.js
var DemoModel = require("./demo-model");

exports.navigatingTo = function(e) {  
  var page = e.object;
  page.bindingContext = new DemoModel();
};

In the controller we create an instance of the model (see below) and bind it to a pange.

// demo-model.js
var Observable = require("data/observable").Observable;  
var _ = require("lodash");

module.exports = function() {  
  var model = new Observable();

  model.allItems = [ "Jack", "John", "Mark", "Ashley" ];
  model.items    = _refilter();
  model.filter   = "";

  function _refilter() {
    var items = model.allItems;
    var filter = model.filter.trim();

    if (filter) {
      var regexp = new RegExp(filter, 'i');
      items = _.filter(items, function(i) {
        return i.match(regexp);
      });
    }

    return items;
  }

  model.on(Observable.propertyChangeEvent, function(e) {
    if (e.propertyName === "filter") model.set("items", _refilter());
  });

  return model;
};

Our model is an instance of Observable. In allItems we hold the original list, items property is what we actually render, and filter holds current filter string. The only function -- _refilter -- creates a new list out of the original basing on the current filter value. We call it initially, and every time the filter property changes.

Simple enough.

comments powered by Disqus