web-dev-qa-db-fra.com

Obtenir la forme la plus proche d'un élément dans jQuery

J'ai ce script js/jquery que j'ai écrit pour vérifier toutes les boîtes aux lettres dans un formulaire. Cela fonctionne bien, mais cela coche toutes les cases à cocher figurant sur la page, quel que soit le wrapper de formulaire utilisé.

voici la fonction

function toggleCheck(state)
{   var checkboxes = jQuery("form input:checkbox");
if(state==true){checkboxes.prop('checked',true); }
if(state==false){ checkboxes.prop('checked',false); }
}

usage 

<a id="check" href="#" onclick="javascript:toggleCheck(true);" class="btn">Select All</a>
<a id="uncheck" href="#" onclick="javascript:toggleCheck(false);" class="btn">Deselect All</a>

Notez que cela fonctionne bien, mais mon problème est si j'ai 

 <form action="myaction-page">//some form elements and checkboxes </form>

et 

<form action="myaction-page-2">//some form elements and checkboxes </form>

et je clique sur le lien Tout cocher dans Form1, toutes les cases à cocher sont cochées, y compris celles de Form2.

Y a-t-il un moyen de les séparer sans introduire d'identifiants de formulaire ou de noms? .. C'est parce que je l'ai utilisé abondamment dans le code de production et que tout réécrire posera problème.

Toute aide est la bienvenue.

P.S il est intéressant de noter que les options Tout sélectionner et Tout désélectionner se trouvent dans les deux formulaires et que les deux formulaires se trouvent sur la même page.

10
jcobhams

En supposant que vos liens sélectionner/désélectionner sont à l'intérieur du formulaire, faites:

function toggleCheck(state,elem) {
    jQuery(elem).closest("form").find("input:checkbox").prop('checked', state);
}

Et changez votre lien JS en (en passant le paramètre vrai/faux approprié):

onclick="javascript:toggleCheck(false,this);"

Exemple jsFiddle

15
j08691

la méthode .closest fera ce que vous voulez.

sur clic:

onclick="toggleCheck.call(this,true);"

js:

function toggleCheck(state) {   
    var checkboxes = jQuery(this).closest("form").find("input:checkbox");
    checkboxes.prop('checked',state || false);
}
1
Kevin B

La réponse est: cela dépend de votre DOM. Si vos éléments <a> sont à l'intérieur du formulaire, vous pouvez utiliser $ .closest () :

function toggleCheck(state) {
    $(this)
        .closest("form")
        .find("input[type=checkbox]")
        .prop('checked', state);
}

J'ai légèrement modifié votre code pour améliorer la lisibilité et les performances (voir les notes complémentaires concernant le sélecteur de cases à cocher : ) et être plus "jQuery".

[edit] Après avoir lu les commentaires, j'ai réécrit la fonction, toujours en supposant que les éléments <a> sont à l'intérieur du <form>, cette fois aussi avec un jsFiddle de travail:

function toggleCheck(state) {
    $(document).find(event.target)
        .closest("form")
        .find("input[type=checkbox]")
        .prop('checked', state);
}

[edit2] Et pour compléter mon commentaire sur l'ordre des éléments ( jsFiddle ):

function toggleCheck(state) {
    var pos = $(document).find(event.target.localName + "." + event.target.className).index(event.target);
    var $form = $($(document).find("form").get(Math.floor(pos/2)));
    $form
        .find("input[type=checkbox]")
        .prop('checked', state)
}

[edit3] La dernière édition, je le promets. Cette fois, j'ignore le rappel par défaut et fais ma propre chose :

function toggleCheck(state) {
    // either write the s tate now in a variable for
    // the next callback
}

$(document).on("click", "a.btn", function(e) {
    var $ele = $(this);
    // or do some string exploration
    var toggle = $ele.attr("onclick").indexOf("true") > -1;

    var pos = $(document).find("a.btn").index($ele);
    var $form = $($(document).find("form").get(Math.floor(pos/2)));
    $form
        .find("input[type=checkbox]")
        .prop('checked', toggle);
});

Fonctionne sans rien toucher. Mais je ne voudrais pas utiliser ceci. ;-)

1
nietonfir

Vous pouvez également simplement appliquer une cible de données à vos ancres et à votre évaluation en fonction de l'action de vos éléments de formulaire:

... data-target='myaction-page' ...

... checkboxes[i].form.getAttribute( 'action' ) ...

Présenté en détail à ce sujet JSFiddle

0
Speedy