ui-sortable icon indicating copy to clipboard operation
ui-sortable copied to clipboard

ng-repeat-start and ng-repeat-end cause wonky behaviour in indexes

Open shinkathe opened this issue 11 years ago • 11 comments

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.

shinkathe avatar Nov 27 '13 15:11 shinkathe

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.

thgreasi avatar Nov 28 '13 20:11 thgreasi

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.

Siecje avatar Jun 12 '14 17:06 Siecje

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

thgreasi avatar Jun 12 '14 17:06 thgreasi

It would be a very nice enhancement to have. I am assuming this will never happen though ;-(

RC1245 avatar Mar 18 '15 17:03 RC1245

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 .

thgreasi avatar Mar 18 '15 18:03 thgreasi

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.

PhiLhoSoft avatar Oct 15 '15 12:10 PhiLhoSoft

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.

jgr3go avatar Feb 09 '16 00:02 jgr3go

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 avatar Mar 18 '16 12:03 funzeye

@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.

jgr3go avatar Mar 18 '16 15:03 jgr3go

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.

larbijirari avatar Jun 15 '16 10:06 larbijirari

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/

sravan50 avatar Aug 23 '18 13:08 sravan50