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");
            
            // select child task under a task row until next task row is reached
            if ($(this).parent().hasClass('heading-row'))
            {
                if ($(this).parent().hasClass('selected'))
                {
                    $(this).parent().nextUntil(".heading-row" ).addClass("selected");
                    
                }else{
                    $(this).parent().nextUntil(".heading-row" ).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']");
           ...