ui-sortable
ui-sortable copied to clipboard
ng-repeat-start and ng-repeat-end cause wonky behaviour in indexes
Using ng-repeat start and ng-repeat-end to repeat say, two TR-elements inside a table, and then using sorting on that tbody-element, causes the index that ui-sortable uses to be doubled.
So inside the callbacks.stop() function, where ui.item.sortable.dropindex is checked, it reports a value that is double the real value. And for every TR element added, this value is multiplied.
I have something like this:
<tbody ui-sortable="sortableOptions" ng-model="test">
<tr ng-repeat-start="result in test">
<td ng-bind="name"></td>
</tr>
<tr ng-repeat-end>
<td ng-bind="name"></td>
</tr>
</tbody>
And, dragging and dropping those tbody-elements cause the sorting to fail, because the index is wrong.
This is not currently in the use cases of the sortable directive. I suppose it would be nice to have as an enhancement. Angular 1.2 changed lots of things for this directive, that have to be fixed first. I would suggest you to use the classic ngRepeat directive (aren't they equivalent?), if thats not a huge pain for you.
I believe this is the issue I am having.
http://plnkr.co/edit/6XlQLBZwG7UrhINQYwAm?p=preview
In the bottom table I can't actually change the order of the items only add empty rows. I can re-order in the top table.
Thanks for providing an example but using ng-repeat-start and ng-repeat-end is not supported and this issue is marked as PR's welcome
.
README
clearly states that:
ui-sortable element should only contain one ng-repeat and not any other elements
It would be a very nice enhancement to have. I am assuming this will never happen though ;-(
In order for this to work, we should:
- check if ng-repeat-start/end is used
- figure out how many elements are created by each model item
- multi-select them and add them in a helper element (like what ui-sortable-multiselection does)
- do the math and update the ng-model appropriately
In my mind this is a wontfix, since such an implementation would add a lot more code and drastically increase the complexity. I would prefer to just simply wrap my elements with an extra div (or whatever is appropriate).
On Wed, Mar 18, 2015, 19:49 RC1245 [email protected] wrote:
It would be a very nice enhancement to have. I am assuming this will never happen though ;-(
— Reply to this email directly or view it on GitHub https://github.com/angular-ui/ui-sortable/issues/64#issuecomment-83088287 .
For the record, I found the issue by trying to use the library on a dl / dt / dd structure:
<dl ui-sortable ng-model="work.list">
<dt class="original" ng-repeat-start="item in work.list">{{item.name}}</dt>
<dd class="translation" ng-repeat-end>{{item.value}}</dd>
</dl>
I found out it didn't work because ui-sortable moved the dt (for example) and not the dd with it. I understand the limitation, I report this mostly in case somebody is puzzling over the same problem.
A workaround, for anyone else having this issue, is to use multiple tbody's, combined with ng-repeat-start if you're already repeating tbody's. In the end the final solution to this for me was:
<table>
<thead>
<tr> ...... </tr>
</thead>
<tbody ng-repeat-start="item in list">
<tr> ...... </tr>
</tbody>
<tbody ng-repeat-end ui-sortable ng-model="item.sublist">
<tr ng-repeat="subitem in item.sublist" > ..... </tr>
</tbody>
</table>
This should work (as far as I can see) in all scenarios that need repeats on tables.
Hi @jgr3go One thing I noticed using your solution is that if I have, for example, two sublists with two items in each - If I drag an item from position 2 to 1 in the second sublist, the two items in the first sublist also switch around even though I havent touched them. Have you seen this issue also? It's like UI Sortable cannot differenciate between both sublists. Oddly , if I switch an item from position 2 to 1 (or vice versa) in the first sublist the second sublist items dont move.
@funzeye you might just need a track by
. If you have a unique identifier, best to track by that, but otherwise ng-repeat="item in sublist track by $index"
should probably do it.
Hello , i faced this problem also, the solution is to put ng-repeat in <tbody... level and put the ui-sortable on <table... level here is an example: http://jsfiddle.net/larox/u4g79t1r/1/
hop it will works, cheers.
Hi, i know it is very late reply. but it may help come people. I updated using laroox solution. in this example it is possible to drag drop nested levels table rows. http://jsfiddle.net/u4g79t1r/81/