2010-09-03 5 views
3

J'ai une collection de div contenant des images ou des cases à cocher. Mon objectif final est d'avoir l'événement onclick sur la case à cocher également cocher toutes les cases précédentes.Les éléments traversants jQuery obtiennent tous les éléments précédents qui correspondent au sélecteur

Voici ma mise en page (créé dynamiquement afin id # 's peuvent changer en fonction des données de chargement de la page):

<div id="Main1"> 
     <div id="Secondary1"> 
     <div id="div1"> 
      <img id="section1" src="image1" alt="" /> 
      <span>Div 1 text</span> 
      </div> 
     <div id="div2"> 
      <img id="section2" src="image2" alt="" /> 
      <span>Div 2 text</span> 
      </div> 
     <div id="div3"> 
      <input type="checkbox" id="section3"> 
      Div 3 text 
      </input> 
     </div> 
     <div id="div4"> 
      <input type="checkbox" id="section4"> 
      Div 4 text 
      </input> 
     </div> 
     <div id="div5"> 
      <input type="checkbox" id="section5"> 
      Div 5 text 
      </input> 
     </div> 
     <div id="div6"> 
      <input type="checkbox" id="section6"> 
      Div 6 text 
      </input> 
     </div> 
     </div> 
    </div> 

Je veux être en mesure de vérifier la Section5 et avoir auto cochez les cases précédentes.

Le code que je l'ai utilisé, ce qui produit des résultats sporadiques est ci-dessous:

$('input[id^=section]').click(function() { 
    if($(this).attr('checked')) { 
     var slide = $(this).attr('id').replace('section', ''); 
     $(this).replaceWith('<img src="images/ajax-loader.gif" id="loader" alt="" />'); //replace checkbox with loader animation 
     $.ajax({ 
      type: 'POST', 
      url: 'URL to AJAX page', 
      data: '{ data for ajax call }', 
      contentType: 'application/json; charset=utf-8', 
      dataType: 'json', 
      success: function() { 
       $('#loader').parents('div[id^=Secondary]').children('div[id^=section]').each(function() { 
        if($(this).children('input[id^=section]').attr('id') != undefined) { 
          if($(this).children('input[id^=section]').attr('id').replace('section', '') < slide) { 
          $(this).children('input[id^=section]').replaceWith('<img src="images/checkmark.gif" alt="" />'); 
         } 
        } 
       }); 
      }, 
      error: function() { 
        //handle errors 
      } 
     }); 
    } 
}); 

Il me semble que je vais sur ce inefficacement, je l'avais essayé .prev() et .prevAll() mais sans succès. Cependant, j'aurais pu les utiliser incorrectement aussi. Toute aide est appréciée.

Répondre

3

Essayez ceci:http://jsfiddle.net/kgc4M/

if(this.checked) { 
    $(this).closest('div').prevAll('div:has(:checkbox)') 
         .find(':checkbox').attr('checked','checked'); 

} 

EDIT: A partir de votre commentaire, vous souhaitez utiliser .replaceWith() pour remplacer la case avec une image, mais réutiliser l'ID de la case à cocher.

Essayez ceci:

if(this.checked) { 
    $(this).closest('div').prevAll('div:has(:checkbox)') 
       .find(':checkbox') 
       .replaceWith(function() { 
         return "<img src='/some/path.jpg' id='" + this.id + "' />"; 
       }).remove(); 
} 

Notez que je suis aussi appeler unbind() les cases à cocher remplacé, puisque je ne pense pas replaceWith() nettoiera que pour vous. Je vérifierai bien cependant.

EDIT: semble que .replaceWith() supprime les événements et les données, mais garde une entrée dans jQuery.cache pour les éléments supprimés. Pour être complet, je me suis débarrassé de unbind() mais ajouté .remove() à la fin, ce qui les supprime complètement du cache.

+0

Parfait! Merci pour votre réponse rapide. 1 question de plus, est-il possible d'extraire aussi l'identifiant de l'élément? Je remplace les cases à cocher par des images et je veux donner à l'image le même identifiant que la case à cocher. En utilisant votre snippet et en substituant .attr ('checked', 'checked') avec .replaceWith() à la place, mais je voudrais tirer l'ID de l'élément remplacé dynamiquement. Est-ce possible? – jon3laze

+0

@jon - Oui. Si vous utilisez jQuery 1.4 ou une version ultérieure, vous pouvez passer une fonction à '.replaceWith()' qui renvoie la chaîne HTML en tant que remplacement. Dans la fonction, vous pouvez utiliser ceci.id' pour référencer l'identifiant de la case à cocher. Je vais mettre à jour avec un exemple. – user113716

+0

Génial! Merci encore, cela a aidé une tonne. – jon3laze

0

.prev() et .prevAll() sélectionnez les frères et sœurs. Même si les cases à cocher sont au même niveau de l'arborescence DOM, elles ne sont pas des frères et sœurs. Les frères et sœurs doivent partager le même parent immédiat. Ces cases à cocher sont plus comme des cousins.

Essayez quelque chose comme ça dans votre événement click:

if(this.checked) { 
     $(this).parent().prevAll().children(':checkbox').attr('checked', 'checked'); 
} 

Voici une démo: http://jsfiddle.net/dTK6n/

Questions connexes