JSFiddle - React, Tailwind, and code Playground
by Jason Davis
HTML
<div id="project_tasks" class="tasks_block sortable list ui-sortable" style="display: block;">
<!-- TASK HEADING ROW -->
<div id="task_11" class="heading-row task_row">
<span class="handle" title="Drag and Drop to Reorder Tasks"></span>
<input name="sort_order_11" id="sort_order_11" class="sort_order" size="15" type="hidden" value="1">
<input name="heading_11" id="heading_11" class="heading" size="15" type="hidden" value="1">
<input name="name_11" id="name_11" class="task-heading name" size="45" type="text" value="List Heading 1" placeholder="Type a Project Task List Heading Here..." style="cursor: auto; ">
<br style="clear:both;">
</div>
<!-- Regular TASK ROW -->
<div id="task_12" class="task_row">
<span class="handle" title="Drag and Drop to Reorder Tasks"></span>
<input name="sort_order_12" id="sort_order_12" class="sort_order" size="15" type="hidden" value="2">
<div class="task-name-wrap">
<input class="name" name="name_12" id="name_12" placeholder="Name:" size="45" type="text" value="Task record 2">
</div>
<br style="clear:both;">
</div>
<div id="task_12" class="task_row">
<span class="handle" title="Drag and Drop to Reorder Tasks"></span>
<input name="sort_order_12" id="sort_order_12" class="sort_order" size="15" type="hidden" value="2">
<div class="task-name-wrap">
<input class="name" name="name_12" id="name_12" placeholder="Name:" size="45" type="text" value="Task record 3">
</div>
<br style="clear:both;">
</div>
<div id="task_12" class="task_row">
<span class="handle" title="Drag and Drop to Reorder Tasks"></span>
<input name="sort_order_12" id="sort_order_12" class="sort_order" size="15" type="hidden" value="2">
<div class="task-name-wrap">
<input class="name" name="name_12" id="name_12" placeholder="Name:" size="45"...
CSS
.sprite, .handle, .trash-icon, .insert-arrow-icon {
background-image: url('http://i.imgur.com/TZjcCte.png');
background-repeat: no-repeat;
overflow: hidden;
}
.handle {
cursor: move;
display: inline-block;
position: relative;
margin: 1px 0 10px 6px;
top: 13px;
width: 13px;
height: 14px;
background-position: 0px -268px;
}
.task-name-wrap, .task-description-wrap, .task-status-wrap, .task-priority-wrap, .task-type-wrap, .task-tools-wrap {
position: relative;
display: inline-block;
margin: 10px 6px 0 0;
vertical-align: top !important;
line-height: 20px;
vertical-align: middle;
}
.task_row input {
margin: 0px 0 10px 7px;
height: 20px;
font-size: 14px;
border-color: #E1E6E9;
}
.name {
padding-left: 4px;
}
input, select {
border-color: #94C1E8;
background-color: #FFF;
}
input, select, textarea, button, .button {
border: 1px solid;
}
input[type=text], input[type=password], textarea {
width: auto;
}
.heading {
background: #808080;
color: #000;
text-align: center;
width: 100%;
z-index: 9999;
/* border-bottom: 2px solid #4E8CCF; */
}
.heading-row{
background: #464657;
}
#project_tasks > .task_row.selected {
background-color: #DFEBFF !important;
}
/*Drag and Drop*/
.sortable a:focus {
outline-offset: 0px;
}
.sortable-dragging
.ui-sortable-dragging{
border: 1px solid #e8e8e8;
}
.sortable-placeholder,
.ui-sortable-placeholder,
.tasks_block > div.ui-state-highlight {
border: 1px dashed #CCC;
background: #fcfcfc !important;
height:auto;
min-height: 60px;
padding: 0px;
margin:8px;
}
.tasks_block > div.ui-state-highlight:after {
content: "Drop Task Here";
text-align: center;
padding: 48px;
line-height: 55px;
font-size: 26px;
color: #C7C7C7;
}
JavaScript
jQuery( document ).ready(function() {
// Handle Project Task Drag and Drop Sorting on Task Edit Screen.
$("#project_tasks").on('click', '.handle', function (e) {
if (e.ctrlKey || e.metaKey) {
$(this).parent().toggleClass("selected");
} else {
$(this).parent().addClass("selected").siblings().removeClass('selected');
}
}).sortable({
handle: '.handle',
placeholder: 'ui-state-highlight',
delay: 150, //Needed to prevent accidental drag when trying to select
revert: 0,
helper: function (e, item) {
var helper = $('<div/>');
if (!item.hasClass('selected')) {
item.addClass('selected').siblings().removeClass('selected');
}
var elements = item.parent().children('.selected').clone();
item.data('multidrag', elements).siblings('.selected').remove();
return helper.append(elements);
},
stop: function (e, info) {
info.item.after(info.item.data('multidrag')).remove();
$('.selected').removeClass('selected');
updateSortOrderNumbers();
}
});
function updateSortOrderNumbers(){
showTaskUnSavedChangesHeaderBar();
jQuery('.sortable div.task_row').each(function(idx) {
var inputField = jQuery(this).find("[id^='sort_order']");
jQuery(inputField).val(idx+1);
});
}
});