Drag ng sort: reruns in AngularJS?

Is it easy to use jQuery.sortable ng-repeat elements in AngularJS?




It would be great if the reordering of elements was automatically propagated to order them back to the original array. I'm afraid that the two systems will fight. Is there a better way to do this?

+59
javascript angularjs jquery-ui-sortable
Sep 08 2018-11-18T00:
source share
5 answers

Angular UI has a sortable directive. Click here to demonstrate.

Code located in ui-sortable using:

 <ul ui-sortable ng-model="items"> <li ng-repeat="item in items">{{ item }}</li> </ul> 
+74
Aug 12 '12 at 16:50
source share

I tried to do the same and came up with the following solution:

 angular.directive("my:sortable", function(expression, compiledElement){ return function(linkElement){ var scope = this; linkElement.sortable( { placeholder: "ui-state-highlight", opacity: 0.8, update: function(event, ui) { var model = scope.$tryEval(expression); var newModel = []; var items = []; linkElement.children().each(function() { var item = $(this); // get old item index var oldIndex = item.attr("ng:repeat-index"); if(oldIndex) { // new model in new order newModel.push(model[oldIndex]); // items in original order items[oldIndex] = item; // and remove item.detach(); } }); // restore original dom order, so angular does not get confused linkElement.append.apply(linkElement,items); // clear old list model.length = 0; // add elements in new order model.push.apply(model, newModel); // presto scope.$eval(); // Notify event handler var onSortExpression = linkElement.attr("my:onsort"); if(onSortExpression) { scope.$tryEval(onSortExpression, linkElement); } } }); }; }); 

Used as follows:

 <ol id="todoList" my:sortable="todos" my:onsort="onSort()"> 

It seems to work quite well. The trick is to undo the DOM manipulation done by sorting before updating the model, otherwise agular will desynchronize with the DOM.

Notification of changes works through the expression my: onsort, which can call controller methods.

I created a JsFiddle based on the angular todo tutorial to show how it works: http://jsfiddle.net/M8YnR/180/

+12
Jan 24 2018-12-21T00:
source share

Here is how I do it with angular v0.10.6. Here is jsfiddle

 angular.directive("my:sortable", function(expression, compiledElement){ // add my:sortable-index to children so we know the index in the model compiledElement.children().attr("my:sortable-index","{{$index}}"); return function(linkElement){ var scope = this; linkElement.sortable({ placeholder: "placeholder", opacity: 0.8, axis: "y", update: function(event, ui) { // get model var model = scope.$apply(expression); // remember its length var modelLength = model.length; // rember html nodes var items = []; // loop through items in new order linkElement.children().each(function(index) { var item = $(this); // get old item index var oldIndex = parseInt(item.attr("my:sortable-index"), 10); // add item to the end of model model.push(model[oldIndex]); if(item.attr("my:sortable-index")) { // items in original order to restore dom items[oldIndex] = item; // and remove item from dom item.detach(); } }); model.splice(0, modelLength); // restore original dom order, so angular does not get confused linkElement.append.apply(linkElement,items); // notify angular of the change scope.$digest(); } }); }; }); 
+10
Feb 17 '12 at 16:09
source share

Here is my implementation of the Angular.js sortable directive without jquery.ui:

+5
May 10 '14 at 15:14
source share

you can go for the ng-sortable directive, which is lightweight and doesn't use jquery. here's a link ng-sortable drag and drop items

Demo for ng sorting

0
Feb 01 '16 at 7:29
source share



All Articles