2

I have an existing array of elements, example:

arr=[{name:1,data:xyz},{name:2,data:abc},{name:3, data:lmn}; {name:4,data:opq}]

This items are populated according to their name on UI. Example: 1 2 3 4 5

I have implemented Sortable of jQuery. Instead of creating a new array, I wish to update the exiting array arr according to the new position of the elements after the user has done performing the drag & drop operation on the above elements.

User can move elements present inside the array arr and cannot introduce any dragged object from outside the 1 2 3 4 5 elements' list, example: 2 can be moved to 5 or 1 can be moved to 3 etc etc.

Elements HTML:

<ul class= "tree-list">
 <li class="li_class"><span class="span_class"> 1 </span></li>
 <li class="li_class"><span class="span_class"> 2 </span></li>
 <li class="li_class"><span class="span_class"> 3 </span></li>
 <li class="li_class"><span class="span_class"> 4 </span></li>
 <li class="li_class"><span class="span_class"> 5 </span></li>
</ul>

jQuery:

 $(function() {
            var data = $(".tree-list").sortable({
              delay: 150,
              axis: "y",
      
            update: function(event, ui) {
                var index = ui.item.index();
                console.log("Moved to new position: " + index);
                var children = $('ul.tree-list').children()
                // What to do here
           
            })
     
            $( ".tree-list" ).disableSelection();
        });

Array created dynamically:

someFunc(data){
    let htmlString= " <ul class =\"tree-list\" "
    for (let i=0; i<data.length; i++){
        if(typeof(item) === "string"){
          htmlString += "<li class=\" li_class \"" + item + "\">";
                                     }
        else if(typeof(item) === "object"){
          htmlString += "<li>";
          htmlString += "span class=\"span_class\""  
                                     }
           htmlString += "</li>"
                                   }
       }
htmlString += "</ul>";
return (htmlString);

}
2
  • Are the li and span elements created from the array? If so you can simplify the logic by adding the objects to the element's metadata and simply using map() to re-build the array in the correct order when each sort operation happens. Commented Jan 19, 2021 at 12:05
  • yes, they're created dynamically. Updated the code, could you please take a look. Commented Jan 19, 2021 at 12:33

1 Answer 1

4

I tried to recreate your example using initial array :

what I've done is , at first create data-previndex to store previous index on li position update using start srotable : ( credits to this answer )

then every update, call the array_move (credits to this answer ) which update element on the js array , depending on the previous and current index

See below working snippet :

$(function() {
  let arr = [{name:1,data:"xyz"}, {name:2,data:"abc"}, {name:3, data:"lmn"}, {name:4,data:"opq"}, {name:5,data:"stu"}]
  
  let $treeList = $(".tree-list");
  
  arr.forEach(element => {
    let liNode = `<li class="li_class"><span class="span_class"> ${element.name} </span></li>`
    $treeList.append(liNode);
  })
   
  var data = $(".tree-list").sortable({
    delay: 150,
    axis: "y",
    start: function(e, ui) {
        // creates a temporary attribute on the element with the old index
        // credits to this answer https://stackoverflow.com/questions/1601827/jquery-ui-sortable-how-to-determine-current-location-and-new-location-in-update
        $(this).attr('data-previndex', ui.item.index());
    },

    update: function(event, ui) {
      var newIndex = ui.item.index();
      var oldIndex = $(this).attr('data-previndex');
      
      
      var children = $('ul.tree-list').children()
      // What to do here
      arr = array_move(arr, oldIndex, newIndex);
      console.clear()
      console.log(JSON.stringify(arr));
    }
  });

  $(".tree-list").disableSelection();
});

function array_move(arr, old_index, new_index) {
    if (new_index >= arr.length) {
        var k = new_index - arr.length + 1;
        while (k--) {
            arr.push(undefined);
        }
    }
    arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
    return arr; 
};
@import url("https://code.jquery.com/ui/1.12.0/themes/smoothness/jquery-ui.css");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"></script>
<ul class="tree-list">
</ul>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.