0

Using Marionette and Coffeescript.

I am working on allowing users to check a box on a view's model and then change one attribute on all checked models (like you can do in Gmail, for example).

Right now I am planning on setting the id of the checkbox to the id of the model, and grabbing the ID's of all checked boxes using jQuery and updating one model at a time, perhaps through a function on the collection that receives the array of ID's and the attribute to change.

My question is: is there a particularly neat 'Backbone way' of doing this? Or any suggestions along those lines? Forgive the generality, I am not too good at knowing the backbone way and my google searching did not turn up much.

edit

So I ended up doing it like the following. I also have a selectAll and deselectAll on the view which checks/unchecks all the checkboxes. I didn't update the models to reflect checked or unchecked because it seemed unnecessary since the checked status isn't presisted for any reason and it seems like mass updating models on a selectAll or deselectAll is unnecessary work. And the ID of the checkbox is the ID of the model for that view.

collection:

class MyCollection extends Backbone.Collection
  model: MyModel
....
  batchSave: (ids, attrs) ->
    for id in ids
      @get(id).save attrs, patch: true

in view:

class MyComposite extends Marionette.CompositeView
  events:
    'click .batch-attribute a' : 'attributeSelected'

  prioritySelected: (e) ->
    e.preventDefault()
    ids = $('.edit-select:checked').map( -> @id ).get()
    attr = {attr: e.currentTarget.dataset.value}
    @collection.batchSave ids, attr
jacob.mccrumb
  • 681
  • 5
  • 18
  • What is the relation between checked model and other models..? Does the other models belong to same collection..? – T J Dec 22 '15 at 15:58
  • Yes, all models are in the same collection. Think of emails in a gmail inbox, you can seleect multiple an archive them all. – jacob.mccrumb Dec 22 '15 at 16:05

1 Answers1

0

Ideally you'll have a collection view and a bunch of item Views as shown below:

var Checks = Backbone.Collection.extend({});
var checks = new Checks([{}, {}, {}]);
var CheckView = Backbone.View.extend({
  initialize: function() {
    this.render();
  },
  events: {
    'click input': 'check'
  },
  render: function() {
    this.$el.append('<input type="checkbox">').appendTo('body');
  },
  check: function(event) {
    this.model.set('selected ', $(event.target).is(':checked'));
  }
});
checks.each(function(model) {
  new CheckView({
    model: model
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.3/backbone-min.js"></script>

Each item view is responsible for marking it's model as selected. Later you can simply find the selected models from collection view like this.collection.where({selected:true});

T J
  • 42,762
  • 13
  • 83
  • 138
  • Thanks, right now I am leaving the "checked" status on the views, because it seems faster to select/deselect multiple input boxes rather than updating each model (i.e. if someone wanted to "select all" or "deselect all". I'll update the question with the code I ended up with in case anyone has suggestions to better it. If not, I'll accept your answer since it also works! – jacob.mccrumb Dec 22 '15 at 18:27
  • @jacob.m hmm.. I suggested model because you can use the collection methods like `this.collection.where({selected:true});`, you can still use `_.where()` with other things... whatever works for you.. ;) – T J Dec 22 '15 at 18:33
  • @T J Makes sense, the only reason I didn't go this way was I was to lazy to check and uncheck my models... I might switch over though! – jacob.mccrumb Dec 22 '15 at 18:58