Search code examples
javascriptjqueryhtmlhtml-listsdraggable

How to drag and drop HTML list items in a form and change their hidden input field values


I have been looking around for a comprehensive 'easy-to-understand' solution to this problem, but haven't been able to find anything. My knowledge of JavaScript is limited, so please be easy on me! :)

<form name="xyz" action="/scripts/change-position.php">
    <ul>
        <li draggable="true">Item A <input type="hidden" name="position" value="1"></li>
        <li draggable="true">Item B <input type="hidden" name="position" value="2"></li>
        <li draggable="true">Item C <input type="hidden" name="position" value="3"></li> 
    </ul>
    <input type="submit" value="Save new order">
</form>
  1. how do I make my list items sortable?
  2. how do I update the value of each li's hidden input field to reflect the new order?
  3. I am already using jQuery on the page where I need to insert the form, so pure JavaScript of jQuery would be preferable.
  4. not a must, but the solution should ideally work on mobile devices.

Thanks in advance for any help!


Solution

  • You are Welcome, jQueryUI sortable. I use update event to change position value of hidden inputs. Update event is triggered when the user stopped sorting and the DOM position has changed.

    Update

    added jqueryui-touch-punch to support touch events

    $(document).ready(function(){
      var list = $('#mySortable'),
          updatePosition = function() {
            list.children().each(function(i, e){
              $(this).children('input[type="hidden"]').val(++i);
            });
          };
    
      list.sortable({
        placeholder: "ui-state-highlight",
        update: updatePosition
      });
    });
    ul{
      list-style-type: none;
      padding-left: 0;
    }
    li,
    .ui-state-highlight {
      font-size: 16px;
      line-height: 18px;
      border: 1px solid #999;
      padding: 0.5em 1em;
      margin-bottom: 0.25em;
    	box-sizing: border-box;
    	height: 2.5em;
    	max-width: 100%;
      background-color: #fff;
    }
    
    .ui-state-highlight{
    	display: block;
      background-color: #999;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui-touch-punch/0.2.3/jquery.ui.touch-punch.min.js"></script>
    
    
    <form name="xyz" action="/scripts/change-position.php">
        <ul id="mySortable">
            <li draggable="true">Item A <input type="hidden" name="position" value="1"></li>
            <li draggable="true">Item B <input type="hidden" name="position" value="2"></li>
            <li draggable="true">Item C <input type="hidden" name="position" value="3"></li> 
        </ul>
        <input type="submit" value="Save new order">
    </form>