Accessible, Touch-Friendly and Drag & Drop Html List with jQuery

Accessible, Touch-Friendly and Drag & Drop Html List with jQuery
File Size: 6.03 KB
Views Total:
Last Update:
Publish Date:
Official Website: Go to website
License: MIT
   

An extension for jQuery Sortable plugin which allows you to reorder an Html list by mouse, keyboard, touch, or drag & drop.

How to use it:

1. Include jQuery library and the jQuery sortable plugin at the bottom for fast page loading.

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="jquery-sortable-min.js"></script>

2. Create an Html list as follows.

<form id="sort-it">
  <ol>
    <li>This is item #1
      <label for="custom-number-1">New order:</label>
      <input id="custom-number-1" name="custom-number-1" type="number" min="1">
    </li>
    <li>This is item #2
      <label for="custom-number-2">New order:</label>
      <input id="custom-number-2" name="custom-number-2" type="number" min="1">
    </li>
    <li>This is item #3
      <label for="custom-number-3">New order:</label>
      <input id="custom-number-3" name="custom-number-3" type="number" min="1">
    </li>
    <li>This is item #4
      <label for="custom-number-4">New order:</label>
      <input id="custom-number-4" name="custom-number-4" type="number" min="1">
    </li>
    <li>This is item #5
      <label for="custom-number-5">New order:</label>
      <input id="custom-number-5" name="custom-number-5" type="number" min="1">
    </li>
  </ol>
  <input type="submit" id="manual-sort" name="manual-sort" value="Update">
</form>

3. Add CSS styles into the document.

/* prevent zoom in mobile */
#sort-it input { font-size: 1em; } 

#sort-it ol {
  /* list style is faked with number inputs */
  list-style: none;
  padding: 0;
}

#sort-it li {
  position: relative;
  min-height: 1em;
  cursor: move;
  padding: .5em .5em .5em 2.5em;
  background: #eee;
  border: 1px solid #ccc;
  margin: .25em 0;
  border-radius: .25em;
  max-width: 14em;
}

#sort-it li input {
  /* Move these to visually fake the ol numbers */
  position: absolute;
  width: 1.75em;
  left: .25em;
  top: .25em;
  border: 0;
  text-align: right;
  background: transparent
}

#sort-it li label {
  /* visually hidden offscreen so it still benefits screen readers */
  position: absolute;
  left: -9999px;
}

/* sortable plugin styles when dragged */

#sort-it .dragged {
  position: absolute;
  opacity: 0.5;
  z-index: 2000;
}

#sort-it li.placeholder {
  position: relative;
  background: purple;
}

4. Initialize the plugin.

$(function(){
$('#sort-it ol').sortable({
onDrop: function(item) {
$(item).removeClass("dragged").removeAttr("style");
$("body").removeClass("dragging");

getInitialOrder('#sort-it li');
}
});

getInitialOrder('#sort-it li');
 
$('#sort-it ol input[type="number"]').focus(function(){
$(this).select();
}).change(function(){
updateAllNumbers($(this), '#sort-it input');
}).keyup(function(){
updateAllNumbers($(this), '#sort-it input');
});

$('#sort-it').submit(function(e){
reorderItems('#sort-it li', '#sort-it ol');
e.preventDefault();
})

}); 

function getInitialOrder(obj){
var num = 1;
$(obj).each(function(){

$(this).find('input[type="number"]').val(num).attr('data-initial-value', num); 
num++;
});
$(obj).find('input[type="number"]').attr('max', $(obj).length); //give it an html5 max attr based on num of objects
}

function updateAllNumbers(currObj, targets){
var delta = currObj.val() - currObj.attr('data-initial-value'), //if positive, the object went down in order. If negative, it went up.
c = parseInt(currObj.val(), 10), //value just entered by user
cI = parseInt(currObj.attr('data-initial-value'), 10), //original object val before change
top = $(targets).length;

if(c > top){
currObj.val(top);
}else if(c < 1){
currObj.val(1);
}

$(targets).not($(currObj)).each(function(){ 
var v = parseInt($(this).val(), 10);

if (v >= c && v < cI && delta < 0){ 
$(this).val(v + 1);
} else if (v <= c && v > cI && delta > 0){ 
$(this).val(v - 1);
}
}).promise().done(function(){

$(targets).each(function(){
if($(this).val() !== ""){
$(this).attr('data-initial-value', $(this).val());
}
});
});
}

function reorderItems(things, parent){
for(var i = 1; i <= $(things).length; i++){
$(things).each(function(){
var x = parseInt($(this).find('input').val(), 10);
if(x === i){
$(this).appendTo(parent);
}
});
}
}

This awesome jQuery plugin is developed by thebarrytone. For more Advanced Usages, please check the demo page or visit the official website.