2014-11-13 4 views
0

У меня есть список вариантов поиска, сгруппированных по их разделу и скомпонованных с помощью аккордеона. Пользователь расширяет раздел и перетаскивает свой выбор в «Сохраненный список». Эти поля сохраняются и используются для пользовательских столбцов таблиц на моем сайте. Все работает очень хорошо, за исключением нескольких второстепенных вещей.JQuery аккордеон + сортируемый. Отключить родительские группы от перетаскивания

  1. Я хочу заблокировать родителей (личный, образовательный, предметный), и только элементы li внутри перетаскиваются. Прямо сейчас пользователь может перетащить всю группу вверх, что нежелательно, потому что у меня есть предел полей, которые они могут искать. Перетаскивание целого раздела может превышать этот предел и разбивать мои таблицы.

  2. В IE после свертывания родительского элемента элементы li «blip» видны на секунду, прежде чем скрыть. Не большое дело, но может раздражать, особенно некоторые из моих привередливых пользователей :)

кодекса ниже. Для стилизации см. Fiddle моей настройки.

Я дошел до того места, где я не вижу леса для деревьев, поэтому, если бы я мог просто быть направлен в правильном направлении, это было бы очень признательно!

HTML:

<div class="demo"> 
    <div id="swaplist" style="height: 0;"></div> 
    <ul id="sortable2" class='saved'> 
     <div class="container" style="overflow:auto;"> 
      <div align='center'> 
       <h2>Saved List</h2> 

      </div> 
      <div class="group"></div> 
     </div> 
    </ul> 
    <br /> 
    <ul id="sortable1" class='available'> 
     <div align='center'> 
      <h2>Available Fields</h2> 

     </div> 
     <br /> 
     <div id="accordion" style="width:950px;"> 
      <div class="group"> 
       <h2><span class="text"><a href="#">Personal</a></span></h2> 

       <div class="container"> 
        <ul id="sortable1" class='available' style="width:850px;"> 
         <li class='ui-state-default'><b>First Name</b> 

          <br />Section: A</li> 
         <li class='ui-state-default'><b>Last Name</b> 

          <br />Section: A</li> 
         <li class='ui-state-default'><b>Date of Birth</b> 
          <br />Section: A</li> 
        </ul> 
       </div> 
      </div> 
      <br /> 
      <div class="group"> 
       <h2><span class="text"><a href="#">Education</a></span></h2> 

       <div class="container"> 
        <ul id="sortable1" class='available' style="width:850px;"> 
         <li class='ui-state-default'><b>Associate's</b> 

          <br />Section: B</li> 
         <li class='ui-state-default'><b>Bachelor's</b> 

          <br />Section: B</li> 
         <li class='ui-state-default'><b>Master's</b> 

          <br />Section: B</li> 
         <li class='ui-state-default'><b>Doctorate</b> 

          <br />Section: B</li> 
         <li class='ui-state-default'><b>Other</b> 

          <br />Section: B</li> 
        </ul> 
       </div> 
      </div> 
      <br /> 
      <div class="group"> 
       <h2><span class="text"><a href="#">Subject</a></span></h2> 

       <div class="container"> 
        <ul id="sortable1" class='available' style="width:850px;"> 
         <li class='ui-state-default'><b>Science</b> 

          <br />Section: C</li> 
         <li class='ui-state-default'><b>Business</b> 

          <br />Section: C</li> 
         <li class='ui-state-default'><b>Liberal Arts</b> 

          <br />Section: C</li> 
        </ul> 
       </div> 
      </div> 
      <br /> 
     </div> 
     <!-- End accordion --> 
    </ul> 
    <br clear="both" /> 
</div> 

JavaScript:

$(function() { 

    $("#accordion") 
     .accordion({ 
     active: false, 
     collapsible: true, 
     animate: false, 
     heightStyle: "content", 
     autoHeight: false, 
     header: "> div > h2" 
    }) 
     .sortable({ 
     axis: "y", 
     handle: "h2", 
     stop: function (event, ui) { 
      // IE doesn't register the blur when sorting 
      // so trigger focusout handlers to remove .ui-state-focus 
      ui.item.children("h2").triggerHandler("focusout"); 
     } 
    }); 


    $("ul.available").sortable({ 
     connectWith: "ul", 
     scroll: true, 
     helper: 'clone', //keeps children visible when pulling out of container 
     appendTo: '#swaplist' //temporarily stores children in hidden div 
    }); 

    $("ul.saved").sortable({ 
     connectWith: "ul", 
     receive: function (event, ui) { 

      if ($(this).children().length > 9) { 
       //ui.sender: will cancel the change. 
       //Useful in the 'receive' callback. 
       $(ui.sender).sortable('cancel'); 
      } 
     }, 
     items: "li[id!=nomove]", 
     update: function() { 
      var order = $(this).sortable("serialize") + '&action=update'; 
      $.post("ajax_file", order, function (theResponse) { 
       $("#info").html(theResponse); 
      }); 
     }, 
     helper: 'clone', //keeps children visible when pulling out of container 
     appendTo: '#swaplist' //temporarily stores children in hidden div 
    }); 

    $("#sortable1, #sortable2").disableSelection(); 
    $("#sortable1, #sortable2").disableSelection(); 
}); 

UPDATE:

Я обнаружил третью вещь мне нужно исправить. Мне нужно убедиться, что пользователь не выбирает повторяющиеся параметры. См. Ответ ниже.

ответ

1

Я понял, как запереть родителей! Это может быть не самый идеальный способ, но он работает. См. Полный Fiddle here.

Для # 1, я применил ответ на How to implement a button on a jQuery Sortable accordion header, чтобы заблокировать родителей на месте. Я сделал класс под названием «DontMove» и поместил их на <h2>, а затем установил его как вариант отмены во всех сортируемых, cancel: ".DontMove". Ниже приведен фрагмент для его реализации.



    $("#accordion") 
     .accordion({ 
     active: false, 
     collapsible: true, 
     animate: false, 
     heightStyle: "content", 
     autoHeight: false, 
     header: "> div > h2" 
    }) 
     .sortable({ 
     axis: "y", 
     handle: "h2", 
     cancel: ".DontMove", 
     stop: function (event, ui) { 
      ui.item.children("h2").triggerHandler("focusout"); 
     } 
    }); 

Для # 3 было решением благодаря prevent duplicated item in jQueryUI sortable.

Этот сниппет - вот что сделал трюк. Я поместил его в раздел получения.



    var id = ui.item.attr('id'); 
    var ele = $('#sortable2').find('li[id="'+id+'"]'); 
    if (ele.length != 1) { 
     $(ui.sender).sortable('cancel'); 
    } 

Проблема заключалась в том, что первоначально я не мог получить список текущих элементов в списке сохранён перед сортировкой функция приема будет увольнять и добавить новый элемент. Поэтому всякий раз, когда я проверю, существует ли уже добавленный элемент, он всегда будет отменен, так как он уже добавлен, что соответствует условию.

Вместо того, чтобы бороться с ним, я просто получил все элементы линии с одним и тем же идентификатором. Если было больше 1, то длина> 1, поэтому отмените падение. Я знаю, что не очень хорошая практика иметь дубликат идентификатора, но поскольку списки основаны на базе данных, есть шанс на это, и я хочу охватить все базы.

Насколько вопрос # 2, я не вижу, как это происходит в Firefox или Chrome, так что я собираюсь оставить его в покое, так как я был больше всего беспокоит # 1 и # 3.

+0

ЭТО решило мои часы разочарования. Благодаря! –

Смежные вопросы