azz0r
azz0r

Reputation: 3311

Backbone Marionette Collection Filtering

I am trying to allow users to search displayNames and emails in a collection.

So far my entire composite view looks like the code below. This renders and logs my var search, but I'm not sure how to use the collection.where and after the new Backbone.Collection, do I call render?

define(["marionette", "text!app/templates/bamboo/employees/collection.html", "app/collections/bamboo/employees",
  "app/views/bamboo/employees/item", "jquery"],
  function(Marionette, Template, Collection, Row, $) {
    "use strict"
    return Backbone.Marionette.CompositeView.extend({
      template: Template,
      itemView: Row,
      itemViewContainer: "ul",
      collectionEvents: {
        'sync': 'hideLoading'
      },
      events: {
        'keyup #filter-input': 'initialize'
      },
      initialize: function () {
        var search = $('#filter-input').val()

        if (typeof(search) != "undefined") {
          console.log(search)
          var filtered = //somehow search collection displayName and email by value search
          this.collection = new Backbone.Collection(filtered);
        } else {
          this.showLoading()
          this.collection = new Collection()
          return this.collection.fetch()
        }
      },
      showLoading: function() {
        this.$el.addClass('loading')
      },
      hideLoading: function() {
        this.$el.removeClass('loading')
      }
  })
})

Upvotes: 1

Views: 3640

Answers (2)

jridgewell
jridgewell

Reputation: 1058

I think this may be easier if you only instantiate a single instance of the collection, and then call functions on the models.

return Backbone.Marionette.CompositeView.extend({
    template: Template,
    itemView: Row,
    itemViewContainer: "ul",
    events: {
        'keyup #filter-input': 'filter'
    },
    initialize: function() {
       this.filter();
    },
    filter: function () {
        var search = $('#filter-input').val() || '';
        this.collection.invoke('set', 'filter', search);
    },
    // ...
});

Then, for your itemViews

Row = Backbone.Marionette.ItemView.extend({
    modelEvents: {
        "change filter": "filter"
    },
    filter: function(model, search) {
        if (model.shouldBeShown(search)) {
            this.$el.show();
        } else {
            this.$el.hide();
        }
    }
});

Upvotes: 1

KiT O
KiT O

Reputation: 867

You can get views from Marionette CollectionView and CompositeView with view.children._views.

With code like this :

_.each(colView.children._views,function(v){
  if(!condition){
     v.$el.hide();
  }
});

you can hide views in colView that has not condition (in your case condition could be v.model.get('type') == 'todo').

Upvotes: 2

Related Questions