26

I wanted to have the functionality of rearranging rows in a table (sorting rows using drag and drop). And the index of the row arrangement should also change in the model.

How can I do something similar to this : http://jsfiddle.net/tzYbU/1162/ using Angular Directive?

I am generating table as :

<table id="sort" class="table table-striped table-bordered">
  <thead>
    <tr>
      <th class="header-color-green"></th>
      <th ng-repeat="titles in Rules.Titles">{{titles.title}}</th>
    </tr>
  </thead>
  <tbody ng-repeat="rule in Rules.data">
    <tr>
      <td class="center"><span>{{rule.ruleSeq}}</span></td>
      <td ng-repeat="data in rule.ruleData">{{statusArr[data.value]}}</td>
    </tr>
  </tbody>
</table>
Mel
  • 5,837
  • 10
  • 37
  • 42
Sushrut
  • 1,541
  • 1
  • 12
  • 16

6 Answers6

48

I did it. See my code below.

HTML

<div ng:controller="controller">
    <table style="width:auto;" class="table table-bordered">
        <thead>
            <tr>
                <th>Index</th>
                <th>Count</th>
            </tr>
        </thead>
        <tbody ui:sortable ng:model="list">
            <tr ng:repeat="item in list" class="item" style="cursor: move;">
                <td>{{$index}}</td>
                <td>{{item}}</td>
            </tr>
        </tbody>{{list}}
        <hr>
</div>

Directive (JS)

var myapp = angular.module('myapp', ['ui']);

myapp.controller('controller', function ($scope) {
    $scope.list = ["one", "two", "thre", "four", "five", "six"];
});

angular.bootstrap(document, ['myapp']);
Max
  • 846
  • 1
  • 9
  • 26
Sushrut
  • 1,541
  • 1
  • 12
  • 16
  • Putting the ng:model on the ui:sortable seems to be the key to keeping the index in the model in sync with the DOM sorted order. Thanks! – Stephen Kaiser Oct 12 '13 at 01:26
  • 11
    Any idea how to handle this without jQuery with pure Angular.js? – Pavel Nikolov Jan 20 '14 at 09:22
  • Thank you a lot for this. Just so great that nobody ever happens to mention, it's not JUST the UL/LI-structure that the sortable works with! Just spent a whole lot of hours trying to fix my HTML to work with UL/LI-layout instead of tables, since there are not very good jquery plugin alternatives for column-dragging and ended up scrapping it. – Hachi Apr 17 '14 at 07:38
  • 1
    @Sushrut You should note in your answer that this answer relies on the use of jQuery UI and is not a pure Angular or Javascript solution. – hitautodestruct Jan 05 '15 at 14:41
  • How can i get the selected and dragged item index and value? The scenario is user1, user2, user3, user4 Move user4 to user2 how can i get these values changed? – Sankar Oct 14 '17 at 09:52
  • what does this line do "angular.bootstrap(document, ['myapp']);" – Naila Akbar Nov 21 '17 at 10:47
  • Thanks for this sexy solution using angularjs. Can you precise the library used for the 'ui' import please ? – bArraxas Mar 18 '19 at 15:49
11

There is another library: RubaXa/Sortable: https://github.com/RubaXa/Sortable

It is for modern browsers and without jQuery dependency. Included is a angular directive. I'm going to check it out now.

You get good touch support additionally.

Thomas
  • 2,127
  • 1
  • 32
  • 45
  • 1
    It doesn't look like this supports tables. – tavnab Jan 22 '16 at 03:09
  • 3
    Seems to work for me. Make sure to put the directive on the TBODY element > http://jsbin.com/gebirenoje/1/edit?html,js,output – What-About-Bob Apr 06 '16 at 13:26
  • Looks like a solid solution without jQuery dependency. Check out their web site, they have plenty of examples there as well: https://rubaxa.github.io/Sortable/ – user1438038 Jul 06 '17 at 16:04
5

AngularJS was not really built for the manipulation of DOM elements, rather to extend the HTML of a page.

See this question and this Wikipedia entry.

For DOM manipulation, jQuery/mootools/etc will suite you just fine (hint: the example in your jsFiddle link).

You could probably use AngularJS to keep track of the ordering of your elements to update your model. I'm not sure how to do this using directives, but the following code may be useful

var MyController = function($scope, $http) {
    $scope.rules = [...];
    ...

}

var updateRules = function(rule, position) {
    //We need the scope
    var scope = angular.element($(/*controller_element*/)).scope(); //controller_element would be the element with ng-controller='MyController'

    //Update scope.rules
}

Then when you reorder the list, simply call updateRules() with the changed rule and its new position in the model.

Community
  • 1
  • 1
johnnynotsolucky
  • 540
  • 3
  • 16
  • 1
    yes i agree, it has to be done by some DOM manipulator like jQuery, but i want it to have the same jQuery function to be inside a angular directive. – Sushrut Sep 04 '13 at 13:35
  • 1
    Unfortunately, my knowledge of AngularJS is _very_ minimal, however, [this page](http://henriquat.re/directives/advanced-directives-combining-angular-with-existing-components-and-jquery/angularAndJquery.html) has some code which combines AngularJS with jQuery datepicker. There is a working example too. I'm sure, with a few modifications, it would be possible to combine the jQuery Sortable widget instead. – johnnynotsolucky Sep 04 '13 at 13:55
2

Anyone else who wants something like this but not understanding the accepted answer. Here is a directive UI.Sortable for AngularJS that allows you to sort an array/ table rows with drag & drop.

Requirements

JQuery v3.1+ (for jQuery v1.x & v2.x use v0.14.x versions)
JQueryUI v1.12+
AngularJS v1.2+

Usage

Load the script file: sortable.js in your application: (you can find this sortable.js from here

<script type="text/javascript" src="modules/directives/sortable/src/sortable.js"></script>

make sure you have included JQuery, AngularJs and JQueryUI js files in order before this sortable file Add the sortable module as a dependency to your application module:

 var myAppModule = angular.module('MyApp', ['ui.sortable'])

Apply the directive to your form elements:

<ul ui-sortable ng-model="items">
  <li ng-repeat="item in items">{{ item }}</li>
</ul>

Developing Notes:

  1. ng-model is required, so that the directive knows which model to update.
  2. ui-sortable element should contain only one ng-repeat
  3. Filters that manipulate the model (like filter, orderBy, limitTo,...) should be applied in the controller instead of the ng-repeat

3rd point is very Important as it took almost an hour to understand why my sorting was not working?? It was because of orderBy in html and that was resetting the sorting again.

For more understanding you can check the detail here.

Naila Akbar
  • 3,033
  • 4
  • 34
  • 76
1

If I understand you correctly, you want to be able to sort the rows? If so, use UI-Sortable: GitHub Demo: codepen.io/thgreasi/pen/jlkhr

ionat
  • 1,979
  • 1
  • 16
  • 15
1

Along with RubaXa/Sortable there is one more angularjs library avilable that is angular-ui-tree. Along with drag and drop we can arrange elements in a tree structure and we can add and delete elements (nodes)

Please see the this link for examples

http://angular-ui-tree.github.io/angular-ui-tree/#/basic-example .

Please see this for github

https://github.com/angular-ui-tree/angular-ui-tree.

Ramesh Papaganti
  • 7,311
  • 3
  • 31
  • 36