sergey.sergeyd2016
sergey.sergeyd2016

Reputation: 83

how to filter models?

Please help fix the script. jsfiddle

I make simply filter for collection of models. Every model have field 'title'. Page consists of: list of titles and searchfield.

User entered letters in searchfield, but list of titles is not filtered. It problem

models and collection:

APP.NewsModel = Backbone.Model.extend({
  defaults:{
    "title": ""
  }
});  

APP.NewsModelsCollection = Backbone.Collection.extend({
  model: APP.NewsModel,

  search : function(letters){ console.log(letters)
    if(letters == "") return this;

    var pattern = new RegExp(letters,"gi");
    return _(this.filter(function(data) {
        return pattern.test(data.get("title"));
    }));
  }  
});

views:

APP.Filter = Backbone.View.extend({  

  initialize: function() {   
    var self = this;

    this.collection = new APP.NewsModelsCollection();  

    var model1 = new APP.NewsModel({title: 'qwerty'}),
        model2 = new APP.NewsModel({title: 'qwddez'}),
        model3 = new APP.NewsModel({title: 'zxxc'});

    this.collection.add(model1);
    this.collection.add(model2);
    this.collection.add(model3);

    this.render();

    $('#filterTitleField').on('keyup', function() { self.search() });
  },    

  render: function () {   
    this._createNewsUnits();
    return this;
  },

  search: function(e){  console.log('search')
    var letters = $("#filterTitleField").val();
    this.collection.search(letters);
    console.log(this.collection.models)
    this._createNewsUnits();
  },    

  _createNewsUnits: function () {  
    $('#newsList').html('');

    this.collection.each(function (news) {    
      var news = new APP.News({model: news});    
      $('#newsList').append(news.render().el);
    }, this);
  } 

});


APP.News = Backbone.View.extend({  

  initialize: function(model) {   
    this.model = model.model;
  },

  className: 'news',

  template: _.template($('#newsUnitTpl').html()),

  render: function () {  
    this.$el.html(this.template({title: this.model.get('title')}));   
    return this;
  }

});

Upvotes: 1

Views: 39

Answers (1)

Sushanth --
Sushanth --

Reputation: 55750

You will need to have - one base collection - which holds list of all the models. - filtered collection - which holds the filtered collection.

The problem with your code is that you are trying to mutate the original collection, due to which the original collection will be lost. i have included the files which will requires changes the way you expect. Also double check your regex.

NewsModelCollection

search: function(letters) {
    console.log(letters)
    if (letters == "") {
        return this.models;
    }

    var pattern = new RegExp(letters, "gi");
    var filtered = this.filter(function(model) {

      //return pattern.test(model.get("title"));
      return model.get('title').indexOf(letters) > -1;
    });
    debugger;
    return filtered;
  }

Filter

initialize: function() {
    var self = this;

    this.collection = new APP.NewsModelsCollection();

    var model1 = new APP.NewsModel({
        title: 'qwerty'
      }),
      model2 = new APP.NewsModel({
        title: 'qwddez'
      }),
      model3 = new APP.NewsModel({
        title: 'zxxc'
      });

    this.collection.add(model1);
    this.collection.add(model2);
    this.collection.add(model3);

    // Add the models to the filtered collection
    this.filteredCollection = new APP.NewsModelsCollection(this.collection.toJSON());

    this.render();

    $('#filterTitleField').on('keyup', function() {
      self.search()
    });
  },
  search: function(e) {
    console.log('search')
    var letters = $("#filterTitleField").val();
    var filteredArray = this.collection.search(letters);
    // reset your original filtered collection
    // with newly retured models
    this.filteredCollection.reset(filteredArray);
    console.log(this.filteredCollection.models);
    this._createNewsUnits();
  },

  _createNewsUnits: function() {
    $('#newsList').html('');

    // Use the filtered collection
    // and render each item
    this.filteredCollection.each(function(news) {
      var news = new APP.News({
        model: news
      });
      $('#newsList').append(news.render().el);
    }, this);
  }

jsFiddle

Upvotes: 1

Related Questions