jqueryjquery-uijquery-ui-sortablerepeaterjquery.repeater

jQuery.repeater doesn't work with jQuery Ui sortable


I am using jQuery.repater library for creating repeateble form. And i want sortable all repeateable fields with jQuery Ui Sortable library.

Everthing is ok but, when i sort repeatable fields, input name orders doesn't reindexing. As described here, it is possible with ready event.

Here is my code:

<form class="repeater">
    <div class="sortable" data-repeater-list="group-a">
      <div class="item" data-repeater-item>
        <input type="text" name="text-input" value="A"/>
        <input data-repeater-delete type="button" value="Delete"/>
      </div>
      <div class="item" data-repeater-item>
        <input type="text" name="text-input" value="B"/>
        <input data-repeater-delete type="button" value="Delete"/>
      </div>
    </div>
    <input data-repeater-create type="button" value="Add"/>
</form>

JS:

$(document).ready(function() {
  const form = $(".repeater");
  const sortable = $(".sortable").sortable({
    update: function() {
      console.log(form.serializeArray());
    }
  });

  $(".repeater").repeater({
    show: function() {
      $(this).slideDown();
    },
    hide: function(deleteElement) {
      if (confirm("Are you sure you want to delete this element?")) {
        $(this).slideUp(deleteElement);
      }
    },
    ready: function(setIndexes) {
      sortable.on("sortchange", setIndexes);
    }
  });
});

And live: https://stackblitz.com/edit/js-pbdssq?file=index.js


Solution

  • I have solved this problem that I have been waiting for the answer for a long time as follows:

    I called to repeater.repeater("setIndexes") the repeater at each sortable operation. Reference

    update: function() {
      myRepeater.repeater("setIndexes");
    }
    

    This makes it work correctly, but clicking the Add Button causes the problem of adding more than one element, so a change is required in the source code of jquery.repeater.js. Reference

    In jquery.repeater.js we have to make the following changes:

    Before:

    $filterNested($self.find('[data-repeater-create]'), fig.repeaters).click(function () {
        addItem();
    });
    

    After:

    $filterNested($self.find('[data-repeater-create]'), fig.repeaters).click(function (event) {
        addItem();
        event.stopImmediatePropagation();   
    });
    

    You can find the working sample at this link.

    It shouldn't break anything but I haven't done any exhaustive testing.