Swapping elements in a list is a common task. But as a rule it is often made in a thorny way, especially if it’s Drag&Drop. And now I am going to tell you about a very easy and flexible way to do it using Marionette.js and jQuery UI Sortable.
Installing jQuery UI
We will need Sortable part only, so in order to save the traffic, I unchecked all the ticks for you here. You just need to download it.
Pay attention
We are using a reference to Marionette in the code below:
var Marionette = Backbone.Marionette;
Creating Behavior template with Marionette.Js
This functionality will be implemented with Behaviors.
Here’s the behavior code that will be responsible for sorting models inside the collection:
Behaviors.Sortable=Marionette.Behavior.extend({
onRender:function(){
var collection=this.view.collection // Close the collection
,items=this.view.children._views // Get the list of child elements
,view
;
for(var v in items){
view=items[v]
// Hook the element to the model by cid
view.$el.attr('data-backbone-cid',view.model.cid);
}
this.$el.sortable({ // Make the list sortable
axis: this.options.axis||false,
grid: this.options.grid||false,
containment: this.options.containment||false,
cursor: "move",
handle:this.options.handle||false,
revert: this.options.revert||false,
update: function( event, ui ) {
var model=collection.get(ui.item.data('backbone-cid'));
// Get an attached model
collection.remove(model,{silent:true});
// On the quiet remove it from the collection
collection.add(model,{at:ui.item.index(),silent:true});
//And sneakily add it to the necessary index
}
});
}
});
What is it?
It’s a behavior model that is made for CollectionView. It waits for onRender event and after that attaches each ItemView element to its model with the help of cid.
Then we let this list sort with the help of Drag&Drop using jQuery.
Sortable options
It is possible to pass different set of options for each type, you can read more about it in the jQuery UI documentation. Not all options are implemented in the above mentioned code, you can add your options if you want.
Sorting
When one of the elements is dragged we delete from the collection attached to it by cid model and add again by the necessary index. silent:true flag is required so that Marionette.js wouldn’t try to rearrange it all in its own way, it isn’t good at it.
Combine СollectionView and Behavior
Now let's try it in action
var IView=Marionette.ItemView.extend({// Create new ItemView
template:'#item-template'
})
var CView=Marionette.CollectionView.extend({// Create CollectionView
itemView:IView,
behaviors: {// here’s all the magic works
Sortable:{// Apply Sortable behavior for this type.
//As an example I passed a containment parameter
containment:'parent' // Now we can drag elements inside the father caddy.
}
}
});
And now with the help of just one line behaviors: {Sortable:{}} you can add Drag&Drop sorting of the CollectionView.
How to save it to the server?
I don’t know in what way the order of sorting is kept on your server, but with the help of the above mentioned approach you can pass the order in any format.
I use MongoDB, so without special problems with the help of сollection.toJSON() send it to the server Node.JS and save it as is. You can send to the sever an ordered array of id, which you can get with the help of
collection.pluck('id');
That's it!
Hope this article helped you.
Please leave your comments and tell me what you would like to read about.