2013-01-04 4 views
4

J'essaye de construire un contrôle multi-sélection à deux niveaux en utilisant ULs emboîtables et jqueryUI sélectionnable.jqueryui sélectionnable avec des listes imbriquées - sélectionner/désélectionner un parent devrait sélectionner/désélectionner tous ses enfants

Actuellement, je restreins les sélections au niveau enfant, mais ce que je veux vraiment, c'est être capable de sélectionner un parent LI et d'avoir toutes ses sélections Child LIs aussi. Pour aller plus loin, je voudrais être en mesure de sélectionner tous les LI Child et d'avoir leur Parent sélectionné. Tout ce qui est inférieur à tous les LI Child sélectionnés entraînerait la non sélection du Parent.

Le balisage de base:

<ul id="theParentList"> 
    <li>Parent 1 
     <ul> 
      <li>Child 1.1</li> 
      <li>Child 1.2</li> 
     </ul> 
    </li> 
    <li>Parent 2 
     <ul> 
      <li>Child 2.1</li> 
      <li>Child 2.2</li> 
     </ul> 
    </li> 
</ul> 

et le javascript actuel:

$('#theParentList').selectable({filter: 'li li'}); 

Comment pourrais-je accomplir la première partie: la sélection d'un parent choisit l'ensemble de ses enfants?

Merci!

MISE À JOUR:
Je l'ai plus de ce concept actuellement:
Sélection d'un parent choisit l'ensemble de ses enfants;
désélection un enfant désélectionner est parent

Ce qui ne fonctionne toujours pas: Sélection tous les enfants d'un parent doit choisir le parent

Voici ce que j'ai, à ce moment:

Markup:

<ul id="theParentList"> 
    <li class="level-1"> 
     <div>Parent 1</div> 
     <ul class="level-2"> 
      <li><div>Child 1.1</div></li> 
      <li><div>Child 1.2</div></li> 
     </ul> 
    </li> 
    <li class="level-1"><div>Parent 2</div> 
     <ul class="level-2"> 
      <li><div>Child 2.1</div></li> 
      <li><div>Child 2.2</div></li> 
     </ul> 
    </li> 
</ul> 

et les js:

function SelectSelectableElement (selectableContainer, elementsToSelect){ 
     $(elementsToSelect).not(".ui-selected").addClass("ui-selecting"); 
    } 

    function handleSelected(){}; 

    function handleSelection (El){ 
     if($(El).parent().hasClass('level-1')){ 
      var ch = $(El).parent().find('.level-2 .ui-selectee'); 
      SelectSelectableElement('#theParentList', ch); 
     }else{ 
      //this is a level-2 item 
      //if El and all of it's level-2 siblings are selected, then also select their level-1 parent 
     } 
    }; 

    function handleUnselected (El){ 
     if($(El).parent().hasClass('level-1')){ 
      //unselect all of it's children 
      $(El).parent().children().each(function(){ 
       $(this).find('.ui-selectee').removeClass('ui-selected').addClass('ui-unselected'); 
      }); 
     }else{ 
      //this is a level-2 item, so we need to deselect its level-1 parent 
      $(El).parents('li.level-1').find(">:first-child").removeClass('ui-selected'); 
     } 
    }; 

    $('#theParentList').selectable({ 
     filter: 'li div', 
     selecting: function(event, ui){ 
      handleSelection(ui.selecting); 
     }, 
     selected: function(event, ui) { 
      handleSelected(ui.selected); 
     }, 
     unselected: function(event, ui) { 
      handleUnselected(ui.unselected); 
     }   
    }); 

est ici un violon: http://jsfiddle.net/JUvTD/

Répondre

1

Signalant une réponse à ma propre question, au cas où quelqu'un d'autre a besoin aider avec le même

La sélection d'un parent sélectionnera l'ensemble de ses enfants Sélection tous les enfants choisir leur parent désélectionnant un parent désélectionnera l'ensemble de ses enfants déselectionner un enfant aussi déselectionner est parent

est ici un violon de travail: http://jsfiddle.net/QvqCE/1/

et le javascript

$('#theParentList').selectable({ 
     filter: 'li div', 
     selecting: function (event, ui) { 
      if ($(ui.selecting).parent().hasClass('level-1')) { 
       //this is a level-1 item, so select all of it's children 
       var ch = $(ui.selecting).parent().find('.level-2 .ui-selectee'); 
       $(ch).not(".ui-selected").addClass("ui-selecting"); 
      } else { 
       //this is a level-2 item, so check to see if all of it's siblings are also selected 
       var sibs = $(ui.selecting).parent().siblings().find('.ui-selectee'); 
       var notSelected = 0; 
       for (var i = 0; i < sibs.length; i++) { 
        if ($(sibs[i]).hasClass('ui-selected') || $(sibs[i]).hasClass('ui-selecting')) { 
         notSelected = notSelected 
        } else { 
         notSelected = notSelected + 1; 
        } 
       } 
       if (notSelected === 0) { //all siblings are selected, so select their level-1 parent as well 
        $(ui.selecting).parent().parent().parent().find('>:first-child').not(".ui-selected").addClass("ui-selecting"); 
       } 
       //otherwise, just select as usual 
      } 
     }, 
     unselected: function (event, ui) { 
      if ($(ui.unselected).parent().hasClass('level-1')) { 
       //unselect all of it's children 
       $(ui.unselected).parent().children().each(function() { 
        $(this).find('.ui-selectee').removeClass('ui-selected').addClass('ui-unselected'); 
       }); 
      } else { 
       //this is a level-2 item, so we need to deselect its level-1 parent 
       $(ui.unselected).parents('li.level-1').find(">:first-child").removeClass('ui-selected'); 
      } 
     } 
    }); 
0

En plus de la réponse de rolfsf, au cas où vous voulez comportement légèrement différent qui lie le parent et l'enfant ensemble:

  1. Si tous les enfants sont toujours sélectionnés, la le parent reste sélectionné.et

  2. Si un enfant est décochée, décochez la case parent ainsi,

vous pouvez ajouter cette fonction de rappel dans l'initialisation du widget sélectionnable:

unselecting: function (event, ui) { 
      if ($(ui.unselecting).parent().hasClass('level-1')) { 
       //if all children still selected, don't deselect this 
       var sibs = $(ui.unselecting).next().find('.ui-selectee'); 
       if (sibs.length > 0) { 
        var notSelected = 0; 
        for (var i = 0; i < sibs.length; i++) { 
         if ($(sibs[i]).hasClass('ui-selected') || $(sibs[i]).hasClass('ui-selecting')) { 
          notSelected = notSelected; 
         } else { 
          notSelected = notSelected + 1; 
         } 
        } 
        if (notSelected === 0) { //all children still selected, so keep their level-1 parent selected as well 
         $(ui.unselecting).addClass("ui-selecting"); 
        } 
       } 

      } else { 
       //if unselecting a child, unselect parent as well 
       $(ui.unselecting).parent().parent().prev().removeClass('ui-selected').removeClass("ui-selecting"); 
      } 

     } 

Voir la jsFiddle ici : http://jsfiddle.net/gav9q/

+0

sympa @rocketegg! Je ne vois pas comment le comportement est différent, cependant. Est-ce que vous vous fiez au contexte/à la hiérarchie plutôt qu'à la classe? – rolfsf

Questions connexes