2009-02-02 7 views
1

J'ai un formulaire avec des milliers de cases à cocher, et quand on est coché, je veux cocher toutes les cases en dessous. Cela fonctionne:trouver un objet en Javascript

<html> 
<body> 
<form name="myform"> 
<input type="checkbox" name="box1" onClick="redrawboxes(this);">1<br> 
<input type="checkbox" name="box2" onClick="redrawboxes(this);">2<br> 
... 
</form> 
</body> 
</html> 
<script> 
function redrawboxes(obj){ 
    //check all boxes below 
    var foundit=false; 
    for (e=0; e<document.myform.elements.length; e++){ 
     if (foundit==false){ //search for checked obj 
      if(obj == document.myform.elements[e]){ 
       foundit=true; 
      } 
     }else{ //continuing below checked box 
      if(obj.checked){ //are we checking or unchecking 
        document.myform.elements[e].checked = true; 
      }else{ 
        document.myform.elements[e].checked = false; 
      } 
     } 
    } 
} 
</script> 

mais pour plus de quelques milliers de boîtes, IE est trop lent. (Firefox fonctionne bien.) Existe-t-il une meilleure façon de trouver la boîte d'origine en plus d'itérer dans toute la liste?

+0

Ma première question est qu'est-ce que tu fais avec des milliers de cases à cocher sur un formulaire? : P –

+0

C'était ma première pensée aussi ...: D –

+0

C'est en réalité un arbre, de milliers d'employés, divisé par département, discipline, position. Je permets la sélection par n'importe lequel de ces groupes ou individus. Dans l'arbre actuel, il ne sélectionne pas tout en dessous de la case cochée, il s'arrête quand il saute un niveau sur l'arbre. –

Répondre

4

Les deux suggestions de jQuery sont plutôt bonnes. Pour les querelles de DOM comme ça, vous devriez vraiment utiliser une bonne bibliothèque.

et le commentaire de la sagesse douteuse de mettre des milliers de cases à cocher sur un formulaire est aussi assez bon ...

Mais, hors chance que vous avez une bonne raison pour le faire, et vous ne pouvez pas utiliser jQuery ou similaire, voici une méthode de JS rapide, droite:

function redrawboxes(obj) 
{ 
    //check all boxes below  
    var next = obj; 
    while ((next = next.nextSibling)) 
    { 
     if (next.nodeName.toLowerCase() == "input" 
     && next.type.toLowerCase() == "checkbox") 
     next.checked = obj.checked; 
    } 
} 

testé dans FF3, FF3.1, IE6, Chrome 1, Chrome 2

+0

Peut-être que l'on devrait comparer tagName en utilisant une méthode insensible à la casse ou laisser la comparaison si on sait qu'il n'y a que des cases à cocher. (Comme le suggère la solution du demandeur.) –

+0

@gs: nextSibling va ramasser toutes sortes de nœuds, pas seulement les éléments HTML. Donc, même s'il n'y a que des champs de case à cocher sur le formulaire, nous devons toujours passer les nœuds de texte. – Shog9

+0

... quant à la comparaison des noms de tags, cela n'aura pas d'importance pour le HTML mais c'est probablement une bonne idée d'être en sécurité s'il est utilisé en XHTML - je le mettrai à jour. – Shog9

3

Je pourrais obtenir voté pour cela, mais essayez d'utiliser jquery. il a des sélecteurs optimisés pour cela.

2

Publicité à l'intérieur!

Si vous utilisez jQuery, vous pouvez essayer mon plugin pour rendre votre boucle asynchrone, cela permettra d'exécuter une longue boucle sans geler le navigateur.

http://mess.genezys.net/jquery/jquery.async.php

Si vous ne souhaitez pas utiliser jQuery, vous pouvez télécharger le plug-in et modifier le code pour vos propres besoins, il ne dépend pas vraiment de jQuery.

2

Vous pouvez lire le nom de la case sélectionnée comme ceci:

function redrawboxes(obj) { 
    var name = obj.name; 
    var state = obj.checked; 

    // get that index 
    var index = name.substr(3) * 1; // just to be sure it's a number 
    var length = document.myform.elements.length; 
    var allElements = document.myform.elements 

    // (un)check all elements below 
    for (var i = index; i < length; i++) { 
     allElements[i].checked = state; 
    } 
} 

Vous pourriez avoir accéléré votre code un peu en utilisant des variables locales et il y a un if -Déclaration qui peut être remplacé.

Éditer: En fait, cette erreur unique n'est pas une erreur car cette case spécifique a été (dé) vérifiée par l'utilisateur lui-même.

+0

Vous avez une erreur «off-by-one» (puisque sa numérotation commence par 1). Plus sérieusement, ce code ne vous permettra pas de décocher une case en cliquant dessus. Et il décoche chaque case au-dessus de celle sur laquelle vous avez cliqué. – Shog9

+0

L'off-by-one est mon erreur :) L'autre que j'ai corrigé il y a 7 minutes. Et merci pour le dernier, cette commande n'est pas nécessaire pour le code du tout, supprimé. –

+0

Beaucoup mieux - et légèrement plus rapide que le mien!:-) – Shog9

2

J'sais à quelle vitesse il est , mais vous pouvez essayer le jQuery-way, saisir jQ uery de www.jquery.com et insérez le code suivant sur la page:

$(function(){ 
    $("input:checkbox").click(function(){ 
     $(this).nextAll("input:checkbox").each(function(){ 
      this.checked = true; 
     }); 
    }); 
}); 
Questions connexes