SORTABLE NICE

by bizamajig

HTML

<div class="sortable-list-wrapper">
  <ol class="sortable-list-container sortable--level-1" data-sortable_connect_with=".sortable--level-1">
      <li class="sortable-list-item">
          <span class="handle pull-xs-left"></span>
          <div>
            <a class="pull-xs-left" href="#">Group One</a>
            <span class="pull-xs-left expander">-</span>
          </div>
          <ol class="sortable-list-container sortable--level-2" data-sortable_connect_with=".sortable--level-2">
              <li class="sortable-list-item">
                  <span class="handle pull-xs-left"></span>
                  <div>
                    <a class="pull-xs-left" href="#">Item1 in group one</a>
                    <span class="pull-xs-left expander no-childrens">-</span>
                  </div>
              </li>
              <li class="sortable-list-item">
                  <span class="handle pull-xs-left"></span>
                  <div>
                    <a class="pull-xs-left" href="#">Item1 in group one</a>
                    <span class="pull-xs-left expander no-childrens">-</span>
                  </div>
              </li>
              <li class="sortable-list-item">
                  <span class="handle pull-xs-left"></span>
                  <div>
                    <a class="pull-xs-left" href="#">Item1 in group one</a>
                    <span class="pull-xs-left expander no-childrens">-</span>
                  </div>
              </li>
          </ol>
      </li>
      <li class="sortable-list-item">
          <span class="handle pull-xs-left"></span>
          <div>
            <a class="pull-xs-left" href="#">Group 2</a>
            <span class="pull-xs-left expander">-</span>
          </div>
          <ol class="sortable-list-container sortable--level-2" data-sortable_connect_with=".sortable--level-2">
              <li class="sortable-list-item">
                  <span class="handle pull-xs-left"></span>
                  <div>
         ...

CSS

body {
  position: relative;
  margin: 0;
  padding: 0 0 50px;
  min-height: 100%;
  font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  font-size: 15px;
  color: #666;
  background-color: #f1f1f3;
  -webkit-font-smoothing: antialiased;
}
ol {
  min-height: 5px; /* !IMPORTANT - SORTABLE - SO WE HAVE AN EMPTY, BUT SPACIOUS LIST TO RECEIVE NEW ITEMS WHEN SORTING */
}
li { cursor: pointer; }

h1 > small {
  display: inline-block;
  font-size: 16px;
  vertical-align: middle;
}

h1 > small > a {
  padding: 5px 8px;
  color: #fff;
  background-color: #44c4e7;
  -webkit-transition: all 0.25s ease-in-out;
  -moz-transition: all 0.25s ease-in-out;
  -ms-transition: all 0.25s ease-in-out;
  -o-transition: all 0.25s ease-in-out;
  transition: all 0.25s ease-in-out;
}

h1 > small > a:hover {
  color: #fff;
  text-decoration: none;
  background-color: #19a0c5;
}

a {
  color: #44c4e7;
  -webkit-transition: all 0.25s ease-in-out;
  -moz-transition: all 0.25s ease-in-out;
  -ms-transition: all 0.25s ease-in-out;
  -o-transition: all 0.25s ease-in-out;
  transition: all 0.25s ease-in-out;
  text-decoration: none;
}

a:hover,
a:focus {
  text-decoration: none;
  color: #19a0c5;
  font-weight: 700;
}
.pull-xs-left { float: left;}
.sortable-list-wrapper {
  margin: 30px auto;
  max-width: 800px;
}

.sortable-list-container {
  margin: 0;
  padding: 0;
  list-style: none;
}

.sortable-list-container li {
  position: relative;
  display: block;
  margin: 7px 0;
  font-size: 14px;
}

.sortable-list-container li > div {
  display: block;
  margin: 0;
  padding: 10px 10px 10px 35px;
  background-color: #fff;
  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .10);
  box-shadow: 0 1px 1px rgba(0, 0, 0, .10);
}

.sortable-list-container li > div:after {
  display: block;
  clear: both;
  content: '';
}

.sortable-list-container li > div > input {
  position: absolute;
  top: 10px;
  left: 35px;
  border: none;
  outline: none;
  display:...

JavaScript

var input__sortable_connect_with__level_1 = $( '.sortable-list-container.sortable--level-1' ).data( 'sortable_connect_with' )		|| '',
    input__sortable_connect_with__level_2 = $( '.sortable-list-container.sortable--level-2' ).data( 'sortable_connect_with' )		|| '';

$( '.sortable--level-1' ).sortable({
//
//	containment OR connectWith is required, not both
//
		containment: '.sortable-list-wrapper', 		// CHILD AS ROOT RESTRICT, PARENT INTO CHILD RESTRICT
		connectWith: input__sortable_connect_with__level_1, // '.sortable--level-1' CHILD AS ROOT RESTRICT, PARENT INTO CHILD RESTRICT
});

$( '.sortable--level-2' ).sortable({
	connectWith: input__sortable_connect_with__level_2 // '.sortable--level-2' NEST INTO SIBLING LEVEL/LEVEL-2 SUBGROUPS ONLY
});

$( '.sortable-list-container li > div > .expander' ).on( 'click', function( e ) {
	var $element = $(this);
/*
	$element.text( function( i, text ) {
    return text === "-" ? "+" : "-";
  });
*/
  if ( $element.hasClass( 'open' ) ) {
	  $element.removeClass( 'open' ).addClass( 'closed' );
    $element.text( "+" );
  }
  if ( $element.hasClass( 'closed' ) ) {
	  $(this).removeClass( 'closed' ).addClass( 'open' );
    $element.text( "-" );
  }
	$(this).parent().parent().find( 'ol' ).slideToggle( 250 );
});