Cochez les cases HTML non cochées

303

J'ai un tas de cases à cocher qui sont cochées par défaut. Mes utilisateurs décocheront probablement quelques-unes (le cas échéant) des cases à cocher et laisseront le reste coché.

Existe-t-il un moyen de faire en sorte que le formulaire POSTE les cases à cocher qui ne sont pas cochées, plutôt que celles qui sont cochées?

reach4thelasers
la source

Réponses:

217

Ajoutez une entrée masquée pour la case à cocher avec un ID différent:

<input id='testName' type='checkbox' value='Yes' name='testName'>
<input id='testNameHidden' type='hidden' value='No' name='testName'>

Avant de soumettre le formulaire, désactivez l'entrée masquée en fonction de la condition cochée:

if(document.getElementById("testName").checked) {
    document.getElementById('testNameHidden').disabled = true;
}
vishnu
la source
58
Si vous optez pour une solution basée sur le balisage comme celle-ci, il est probablement préférable de placer l'entrée masquée en premier, pour de nombreuses autres réponses. Si vous utilisez PHP, vous pouvez alors supprimer la dépendance javascript, car seule la dernière valeur est utilisée.
Ben
12
gamov, vous vous trompez, les étiquettes sont attachées aux entrées en fonction de l'attribut id, et non de l'attribut name
Justin Emery
14
Difficile à croire que les auteurs l'ont conçu de cette façon. Pourquoi ne pas envoyer tous les champs d'entrée avec une valeur par défaut pour ceux qui ne sont pas vérifiés :( Ce serait une solution beaucoup plus claire que d'avoir à implémenter certains champs cachés "hack". Il devait être clair que cela allait être nécessaire et ils ont dû voir cela à l'avance.
Srneczek
34
Cela semble tellement hacky.
EralpB
65
Suis-je le seul à penser que la conception sous-jacente de l' checkboxélément est terrible? Ils sont un contrôle binaire, ils doivent envoyer des valeurs binaires.
alexw
474

La solution que j'aimais le plus jusqu'à présent est de mettre une entrée cachée avec le même nom que la case à cocher qui pourrait ne pas être cochée. Je pense que cela fonctionne de sorte que si la case n'est pas cochée, l'entrée cachée est toujours réussie et envoyée au serveur, mais si la case est cochée, elle remplacera l'entrée cachée avant elle. De cette façon, vous n'avez pas à garder une trace des valeurs dans les données publiées qui devraient provenir des cases à cocher.

<form>
  <input type='hidden' value='0' name='selfdestruct'>
  <input type='checkbox' value='1' name='selfdestruct'>
</form>
Sam
la source
3
Maintenant que j'ai relu la question, il semble que ce ne soit pas vraiment ce que vous vouliez. Cependant, je suis arrivé à cette question lorsque j'essayais de trouver cette réponse, alors cela pourrait peut-être être utile à quelqu'un d'autre.
Sam
2
.NET est différent, voir plutôt stackoverflow.com/questions/7600817/…
KCD
121
Il convient de noter que si vous cochez la case, le navigateur enverra à la fois les valeurs masquées et les cases à cocher. Cette solution repose alors sur la gestion par le serveur de la variable post avec ces 2 valeurs. S'il ne prend que la dernière valeur (par exemple PHP), votre code fonctionnera comme prévu. Cependant, certains serveurs gèrent cela différemment, certains choisissent la première valeur, tandis que d'autres placent les deux valeurs dans une liste / tableau.
Michael Ekoka
1
Cette réponse repose sur l'hypothèse que vous pouvez relayer sur une seule des deux entrées nommées égales qui seront envoyées au serveur - je ne comprends pas pourquoi cela a reçu autant de votes positifs?
Muleskinner
7
@sam ne sais pas d'où vous vient cette idée? Lorsque deux contrôles ou plus sont nommés de la même manière, les deux seront envoyés au serveur lors de la soumission (pour les cases à cocher cependant, uniquement si cochées) - la façon dont ils sont gérés sur le serveur dépend de l'implémentation côté serveur. Si vous ne me croyez pas, vous pouvez le constater par vous-même en surveillant le trafic à l'aide d'un outil comme le violoneux.
Muleskinner
75

Je l'ai résolu en utilisant du JavaScript vanille:

<input type="hidden" name="checkboxName" value="0"><input type="checkbox" onclick="this.previousSibling.value=1-this.previousSibling.value">

Attention à ne pas avoir d'espaces ni de sauts de ligne entre ces deux éléments d'entrée!

Vous pouvez utiliser this.previousSibling.previousSiblingpour obtenir des éléments "supérieurs".

Avec PHP, vous pouvez vérifier le champ caché nommé pour 0 (non défini) ou 1 (défini).

Marcel Ennix
la source
Pourquoi ne pouvez-vous pas avoir d'espaces ou de sauts de ligne entre les deux éléments?
Michael Potter
@MichaelPotter: this.previousSibling aura des espaces en tant que frère, donc cela ne fonctionne pas.
Marcel Ennix
4
Oh, c'est PARFAIT! Il résout le problème de la publication de plusieurs ensembles de champs avec des champs nommés en double. Aucune des autres solutions ne le fait. En utilisant la méthode de Marcel, vos champs publiés auront des tableaux de longueur égale. Donc, ce scénario: <fieldset name='fs1'> <input type="text" name="somefield[]"> <input type="checkbox" name="live[]"> </fieldset> <fieldset name='fs2'> <input type="text" name="somefield[]"> <input type="checkbox" name="live[]"> </fieldset>* Supposons qu'il y avait de nouvelles lignes là-bas. Ils ne semblent pas travailler dans des blocs de code de mini-balisage
Brian Layman
1
Ce devrait être la réponse acceptée. Il fonctionne avec des tableaux (ex / name = "soup []")
jdavid05
2
Vous pouvez utiliser à la previousElementSiblingplace de previousSibling. Il est pris en charge presque partout et ignore les nœuds de texte.
MarSoft
23

Mon préféré est d'ajouter un champ caché avec le même nom qui sera utilisé si la case n'est pas cochée. Mais la solution n'est pas aussi simple qu'il y paraît.

Si vous ajoutez ce code:

<form>
  <input type='hidden' value='0' name='selfdestruct'>
  <input type='checkbox' value='1' name='selfdestruct'>
</form>

Le navigateur ne se souciera pas vraiment de ce que vous faites ici. Le navigateur enverra les deux paramètres au serveur et le serveur devra décider quoi en faire.

PHP, par exemple, prend la dernière valeur comme celle à utiliser (voir: Position faisant autorité des clés de requête HTTP GET en double )

Mais d'autres systèmes avec lesquels j'ai travaillé (basés sur Java) font le chemin - ils ne vous offrent que la première valeur. .NET au lieu de cela vous donnera un tableau avec les deux éléments à la place

J'essaierai de tester cela avec node.js, Python et Perl à un moment donné.

SimonSimCity
la source
2
ruby et node.js prendront tous deux la dernière valeur de tout champ de formulaire dupliqué. Les méthodes auxiliaires de Ruby on Rails construisent des cases à cocher de cette façon pour cette raison.
nzifnab
7
Juste pour arrondir cela - cela est basé sur une attaque appelée HTTP Parameter Pollution et a été analysé par OWASP: owasp.org/images/b/ba/AppsecEU09_CarettoniDiPaola_v0.8.pdf (page 9) où vous pouvez trouver une liste de 20 systèmes systèmes et voir comment ils gèrent cela.
SimonSimCity
1
Les servlets Java vous donnent tout, tant que vous appelezrequest.getParameterValues
mauhiz
20

Une technique courante consiste à transporter une variable cachée avec chaque case à cocher.

<input type="checkbox" name="mycheckbox" />
<input type="hidden" name="mycheckbox.hidden"/>

Côté serveur, nous détectons d'abord la liste des variables cachées et pour chacune des variables cachées, nous essayons de voir si l'entrée de case à cocher correspondante est soumise ou non dans les données du formulaire.

L'algorithme côté serveur ressemblerait probablement à:

for input in form data such that input.name endswith .hidden
  checkboxName = input.name.rstrip('.hidden')
  if chceckbName is not in form, user has unchecked this checkbox

Ce qui précède ne répond pas exactement à la question, mais fournit un autre moyen d'obtenir des fonctionnalités similaires.

Shailesh Kumar
la source
20

vous n'avez pas besoin de créer un champ caché pour toutes les cases à cocher, il suffit de copier mon code. elle changera la valeur de la case à cocher si elle n'est pas cochée, la valueaffectera 0et si la case à cocher est cochée, affectez-la valueà1

$("form").submit(function () {

    var this_master = $(this);

    this_master.find('input[type="checkbox"]').each( function () {
        var checkbox_this = $(this);


        if( checkbox_this.is(":checked") == true ) {
            checkbox_this.attr('value','1');
        } else {
            checkbox_this.prop('checked',true);
            //DONT' ITS JUST CHECK THE CHECKBOX TO SUBMIT FORM DATA    
            checkbox_this.attr('value','0');
        }
    })
})
Rameez SOOMRO
la source
1
Cette solution fonctionne bien et plus élégamment que polluer Dom avec des champs cachés.
Prasad Paranjape
9
Cela provoque la case à cocher temporairement pendant que le formulaire est soumis. C'est déroutant (au mieux) pour l'utilisateur.
Mark Fraser
12
$('input[type=checkbox]').on("change",function(){
    var target = $(this).parent().find('input[type=hidden]').val();
    if(target == 0)
    {
        target = 1;
    }
    else
    {
        target = 0;
    }
    $(this).parent().find('input[type=hidden]').val(target);
});

<p>
    <input type="checkbox" />
    <input type="hidden" name="test_checkbox[]" value="0" />
</p>
<p>
    <input type="checkbox" />
    <input type="hidden" name="test_checkbox[]" value="0" />
</p>
<p>
    <input type="checkbox" />
    <input type="hidden" name="test_checkbox[]" value="0" />
</p>

Si vous omettez le nom de la case à cocher, elle ne sera pas transmise. Seul le tableau test_checkbox.

Jeremy
la source
1
Très bonne solution, mais dans mon cas, le live () ne fonctionne pas, j'ai donc utilisé la méthode on (): $ ('input [type = checkbox]'). On ("change", function () {...}) ;
Massa
4
LIVE est obsolète. Ne l'utilisez plus sur les réponses dans le stackoverflow. Amem.
Ismael du
Cette réponse est vraiment la meilleure .. Elle fonctionne comme prévu. Même pour la case à cocher de groupe.
Alemoh Rapheal Baja
11

Vous pouvez faire du Javascript dans l'événement d'envoi du formulaire. C'est tout ce que vous pouvez faire, il n'y a aucun moyen d'amener les navigateurs à le faire eux-mêmes. Cela signifie également que votre formulaire sera rompu pour les utilisateurs sans Javascript. Mieux vaut savoir sur le serveur quelles cases il y a, donc vous pouvez en déduire que celles qui sont absentes des valeurs de formulaire publiées ( $_POSTen PHP) ne sont pas cochées.

Bart van Heukelom
la source
2
depuis php 4.1, vous pouvez également utiliser $ _REQUEST php.net/manual/en/reserved.variables.request.php
Karl Adler
$_REQUESTest une bonne pratique car elle permet une certaine réutilisation du code si votre script prend en charge les deux méthodes.
annulation le
9

Je ferais en fait ce qui suit.

Avoir mon champ de saisie caché avec le même nom avec la case à cocher

<input type="hidden" name="checkbox_name[]" value="0" />
<input type="checkbox" name="checkbox_name[]" value="1" />

puis quand je poste, je supprime tout d'abord les valeurs en double ramassées dans le tableau $ _POST, après avoir affiché chacune des valeurs uniques.

  $posted = array_unique($_POST['checkbox_name']);
  foreach($posted as $value){
    print $value;
  }

Je l'ai obtenu d'un post supprimer les valeurs en double du tableau

desw
la source
À quoi sert le [] sur la valeur du champ de nom?
Michael Potter
@MichaelPotter Il en est ainsi lorsque le message est envoyé à PHP, il lira le nom `checkbox_name []
Twister1002
@ Twister1002, je pense que vous avez décrit le but de l'attribut name, pas le but d'ajouter [] sur le nom. J'ai fait une recherche sur le Web et il semble que certaines personnes le fassent avec les noms: nom de groupe [nom d'élément] pour regrouper les champs, mais je n'ai pas trouvé d'explication pour [] vide.
Michael Potter
1
@MichaelPotter Désolé, je pensais avoir terminé cette déclaration. Mais apparemment non. Permettez-moi de refaire ça. Lorsqu'il est envoyé à php, le processeur PHP le lira comme un tableau. Ainsi, avec chaque nom, checkbox_name[]chaque valeur sera entrée dans un tableau que vous pourrez ensuite extraire. Ex: $_POST['checkbox_name'][0]et ainsi de suite avec l'incrément du nombre de champs portant le même nom. Un autre exemple est que si vous aviez trois champs nommés, field_name[]vous pouvez obtenir la deuxième valeur de field_namelike $_POST['field_name'][1]. Son objectif peut être étonnant si vous avez plusieurs champs du même nom.
Twister1002
8

"J'ai opté pour l'approche serveur. Semble fonctionner correctement - merci. - reach4thelasers 1 déc. 09 à 15:19" Je voudrais le recommander du propriétaire. Comme cité: la solution javascript dépend de la façon dont le gestionnaire de serveur (je ne l'ai pas vérifié)

tel que

if(!isset($_POST["checkbox"]) or empty($_POST["checkbox"])) $_POST["checkbox"]="something";
N Zhang
la source
8

Je sais que cette question a 3 ans mais j'ai trouvé une solution qui, je pense, fonctionne plutôt bien.

Vous pouvez vérifier si la variable $ _POST est affectée et l'enregistrer dans une variable.

$value = isset($_POST['checkboxname'] ? 'YES' : 'NO';

la fonction isset () vérifie si la variable $ _POST est affectée. Par logique, s'il n'est pas attribué, la case n'est pas cochée.

Riley Stadel
la source
C'est beaucoup mieux, car la réponse la plus populaire est une terrible solution pour les lecteurs d'écran.
Kevin Waterson
7

La plupart des réponses ici nécessitent l'utilisation de JavaScript ou de contrôles d'entrée en double. Parfois, cela doit être entièrement géré côté serveur.

Je crois que la clé (prévue) pour résoudre ce problème commun est le contrôle d'entrée de soumission du formulaire.

Pour interpréter et gérer avec succès les valeurs non cochées des cases à cocher, vous devez connaître les éléments suivants:

  1. Les noms des cases à cocher
  2. Le nom de l'élément d'entrée de soumission du formulaire

En vérifiant si le formulaire a été soumis (une valeur est affectée à l'élément d'entrée de soumission), toute valeur de case à cocher non cochée peut être supposée .

Par exemple:

<form name="form" method="post">
  <input name="value1" type="checkbox" value="1">Checkbox One<br/>
  <input name="value2" type="checkbox" value="1" checked="checked">Checkbox Two<br/>
  <input name="value3" type="checkbox" value="1">Checkbox Three<br/>
  <input name="submit" type="submit" value="Submit">
</form>

Lors de l'utilisation de PHP, il est assez simple de détecter les cases à cocher.

<?php

$checkboxNames = array('value1', 'value2', 'value3');

// Persisted (previous) checkbox state may be loaded 
// from storage, such as the user's session or a database.
$checkboxesThatAreChecked = array(); 

// Only process if the form was actually submitted.
// This provides an opportunity to update the user's 
// session data, or to persist the new state of the data.

if (!empty($_POST['submit'])) {
    foreach ($checkboxNames as $checkboxName) {
        if (!empty($_POST[$checkboxName])) {
            $checkboxesThatAreChecked[] = $checkboxName;
        }
    }
    // The new state of the checkboxes can be persisted 
    // in session or database by inspecting the values 
    // in $checkboxesThatAreChecked.
    print_r($checkboxesThatAreChecked);
}

?>

Les données initiales pourraient être chargées à chaque chargement de page, mais ne devraient être modifiées que si le formulaire a été soumis. Étant donné que les noms des cases à cocher sont connus à l'avance, ils peuvent être parcourus et inspectés individuellement, de sorte que l'absence de leurs valeurs individuelles indique qu'ils ne sont pas vérifiés.

Werner
la source
6

J'ai d'abord essayé la version de Sam. Bonne idée, mais cela fait qu'il y a plusieurs éléments dans le formulaire avec le même nom. Si vous utilisez un javascript qui trouve des éléments en fonction du nom, il renverra désormais un tableau d'éléments.

J'ai travaillé sur l'idée de Shailesh en PHP, ça marche pour moi. Voici mon code:

/ * Supprimez les champs '.hidden' si l'original est présent, utilisez la valeur '.hidden' sinon. * /
foreach ($ _POST ['frmmain'] as $ field_name => $ value)
{
    // Ne regarde que les éléments se terminant par '.hidden'
    if (! substr ($ field_name, -strlen ('. hidden'))) {
        Pause;
    }

    // récupère le nom sans '.hidden'
    $ real_name = substr ($ key, strlen ($ field_name) - strlen ('. hidden'));

    // Créer un champ d'origine 'faux' avec la valeur dans '.hidden' si un original n'existe pas
    if (! array_key_exists ($ real_name, $ POST_copy)) {
        $ _POST [$ real_name] = $ valeur;
    }

    // Supprimer l'élément '.hidden'
    unset ($ _ POST [$ field_name]);
}
Wouter
la source
6

J'aime aussi la solution que vous venez de publier un champ de saisie supplémentaire, en utilisant JavaScript me semble un peu hacky.

En fonction de ce que vous utilisez pour votre backend dépendra de l'entrée qui va en premier.

Pour un serveur principal où la première occurrence est utilisée (JSP), vous devez procéder comme suit.

  <input type="checkbox" value="1" name="checkbox_1"/>
  <input type="hidden" value="0" name="checkbox_1"/>


Pour un serveur principal où la dernière occurrence est utilisée (PHP, Rails), vous devez procéder comme suit.

  <input type="hidden" value="0" name="checkbox_1"/>
  <input type="checkbox" value="1" name="checkbox_1"/>


Pour un serveur principal où toutes les occurrences sont stockées dans un type de données de liste ( [], array). (Python / Zope)

Vous pouvez publier dans l'ordre que vous souhaitez, il vous suffit d'essayer d'obtenir la valeur de l'entrée avec l' checkboxattribut type. Donc, le premier index de la liste si la case à cocher était avant l'élément caché et le dernier index si la case à cocher était après l'élément caché.


Pour un serveur principal où toutes les occurrences sont concaténées avec une virgule (ASP.NET / IIS) Vous devrez (diviser / exploser) la chaîne en utilisant une virgule comme délimiteur pour créer un type de données de liste. ( [])

Vous pouvez maintenant tenter de récupérer le premier index de la liste si la case à cocher était avant l'élément caché et de récupérer le dernier index si la case à cocher était après l'élément caché.

Gestion des paramètres backend

source d'image

TarranJones
la source
6

J'utilise ce bloc de jQuery, qui ajoutera une entrée cachée au moment de la soumission à chaque case à cocher non cochée. Cela vous garantira que vous obtenez toujours une valeur soumise pour chaque case à cocher, à chaque fois, sans encombrer votre majoration et sans risquer d'oublier de le faire sur une case à cocher que vous ajouterez plus tard. Il est également indépendant de la pile backend (PHP, Ruby, etc.) que vous utilisez.

// Add an event listener on #form's submit action...
$("#form").submit(
    function() {

        // For each unchecked checkbox on the form...
        $(this).find($("input:checkbox:not(:checked)")).each(

            // Create a hidden field with the same name as the checkbox and a value of 0
            // You could just as easily use "off", "false", or whatever you want to get
            // when the checkbox is empty.
            function(index) {
                var input = $('<input />');
                input.attr('type', 'hidden');
                input.attr('name', $(this).attr("name")); // Same name as the checkbox
                input.attr('value', "0"); // or 'off', 'false', 'no', whatever

                // append it to the form the checkbox is in just as it's being submitted
                var form = $(this)[0].form;
                $(form).append(input);

            }   // end function inside each()
        );      // end each() argument list

        return true;    // Don't abort the form submit

    }   // end function inside submit()
);      // end submit() argument list
Matt Holden
la source
5

Vous pouvez également intercepter l'événement form.submit et inverser la vérification avant de soumettre

$('form').submit(function(event){
    $('input[type=checkbox]').prop('checked', function(index, value){
        return !value;
    });
});
Jimchao
la source
4

Je vois que cette question est ancienne et a tellement de réponses, mais je vais quand même donner mon sou. Mon vote est pour la solution javascript sur l'événement «soumettre» du formulaire, comme certains l'ont souligné. Pas de doublage des entrées (surtout si vous avez des noms longs et des attributs avec du code php mélangé avec du HTML), pas de soucis côté serveur (qui nécessiterait de connaître tous les noms de champs et de les vérifier un par un), il suffit de récupérer tous les éléments non cochés , attribuez-leur une valeur 0 (ou tout ce dont vous avez besoin pour indiquer un état «non vérifié»), puis changez leur attribut «vérifié» en vrai

    $('form').submit(function(e){
    var b = $("input:checkbox:not(:checked)");
    $(b).each(function () {
        $(this).val(0); //Set whatever value you need for 'not checked'
        $(this).attr("checked", true);
    });
    return true;
});

de cette façon, vous aurez un tableau $ _POST comme ceci:

Array
(
            [field1] => 1
            [field2] => 0
)
MarcoSpada
la source
Ne travaille pas à mes côtés. J'essaie de le faire mais je ne poste toujours pas toutes les cases à cocher. [code] $ ("# filter input"). change (function (e) {console.log ('sublmit'); var b = $ ("input: case à cocher: not (: vérifié)"); $ (b) .each (function () {$ (this) .val (2); $ (this) .attr ("checked", true);}); $ ("# filter"). submit ();}); [/ code]
lio
A fait l'affaire pour moi. Le seul inconvénient: soumettre chaque case à cocher est devenu coché. Cela peut être déroutant pour un utilisateur, mais comme la page se recharge après l'envoi du formulaire, je pense que c'est un problème mineur.
Oksana Romaniv
Comme l'a dit Oksana, il vérifie toutes les cases à cocher, y compris toutes les cases à cocher obligatoires que l'utilisateur n'a pas choisies lui-même, permettant au formulaire d'être soumis sans que l'utilisateur n'accepte certaines conditions.
bskool
4
$('form').submit(function () {
    $(this).find('input[type="checkbox"]').each( function () {
        var checkbox = $(this);
        if( checkbox.is(':checked')) {
            checkbox.attr('value','1');
        } else {
            checkbox.after().append(checkbox.clone().attr({type:'hidden', value:0}));
            checkbox.prop('disabled', true);
        }
    })
});
Sajjad Shirazy
la source
1
Cela a fonctionné pour moi. Au lieu d'utiliser .submit, vous utiliseriez .click. Supprimez ensuite le bit qui désactive les cases à cocher. Après cela, cela fonctionne parfaitement.
cgrouge
1
Meilleure réponse, pas besoin d'ajouter une autre entrée cachée pour chacun
Sky
3

Ce que j'ai fait était un peu différent. J'ai d'abord changé les valeurs de toutes les cases à cocher non cochées. À "0", puis tous sélectionnés, la valeur serait alors soumise.

function checkboxvalues(){
  $("#checkbox-container input:checkbox").each(function({ 
    if($(this).prop("checked")!=true){
      $(this).val("0");
      $(this).prop("checked", true);
    }
  });
}

Seborreia
la source
La réponse est bonne, mais je veux savoir si elle est différente de la réponse de @Rameez SOOMRO?
Imran Qamer
Résultat final similaire, mais de cette façon, vous ne modifiez pas la valeur des cases à cocher cochées.
Seborreia
2

Je préfère assembler le $ _POST

if (!$_POST['checkboxname']) !$_POST['checkboxname'] = 0;

cela ne dérange pas, si le POST n'a pas la valeur 'checkboxname', il a été décoché donc, attribuez une valeur.

vous pouvez créer un tableau de vos valeurs ckeckbox et créer une fonction qui vérifie si des valeurs existent, si ce n'est pas le cas, cela ne dérange pas et vous pouvez attribuer une valeur

Felipe Gonzalez
la source
1

Exemple sur les actions Ajax est (': vérifié') utilisé jQuery au lieu de .val ();

            var params = {
                books: $('input#users').is(':checked'),
                news : $('input#news').is(':checked'),
                magazine : $('input#magazine').is(':checked')
            };

params obtiendra la valeur TRUE OR FALSE.

Mehmet Ali Uysal
la source
1

Les cases à cocher représentent généralement les données binaires qui sont stockées dans la base de données sous forme de valeurs Oui / Non, O / N ou 1/0. Les cases à cocher HTML sont de mauvaise nature pour envoyer de la valeur au serveur uniquement si la case est cochée! Cela signifie que le script du serveur sur un autre site doit savoir à l'avance quelles sont toutes les cases à cocher possibles sur la page Web afin de pouvoir stocker des valeurs positives (cochées) ou négatives (non cochées). En fait, seules les valeurs négatives posent problème (lorsque l'utilisateur décoche la valeur précédemment (pré) vérifiée - comment le serveur peut-il le savoir lorsque rien n'est envoyé s'il ne sait pas à l'avance que ce nom doit être envoyé). Si vous avez un script côté serveur qui crée dynamiquement un script UPDATE, il y a un problème parce que vous ne savez pas ce que toutes les cases à cocher doivent être reçues afin de définir la valeur Y pour les cases cochées et N pour les cases non cochées (non reçues).

Étant donné que je stocke les valeurs «Y» et «N» dans ma base de données et les représente via des cases à cocher cochées et non cochées sur la page, j'ai ajouté un champ masqué pour chaque valeur (case à cocher) avec les valeurs «Y» et «N», puis j'utilise des cases à cocher uniquement à des fins visuelles. représentation, et utilisez la fonction JavaScript simple check () pour définir la valeur de if selon la sélection.

<input type="hidden" id="N1" name="N1" value="Y" />
<input type="checkbox"<?php if($N1==='Y') echo ' checked="checked"'; ?> onclick="check(this);" />
<label for="N1">Checkbox #1</label>

utiliser un écouteur JavaScript onclick et appeler la fonction check () pour chaque case à cocher sur ma page Web:

function check(me)
{
  if(me.checked)
  {
    me.previousSibling.previousSibling.value='Y';
  }
  else
  {
    me.previousSibling.previousSibling.value='N';
  }
}

De cette façon, les valeurs «Y» ou «N» sont toujours envoyées au script côté serveur, il sait quels sont les champs qui doivent être mis à jour et il n'est pas nécessaire de convertir la valeur checbox «on» en «Y» ou la case à cocher non reçue en «N '.

REMARQUE: un espace blanc ou une nouvelle ligne est également un frère donc ici j'ai besoin de .previousSibling.previousSibling.value. S'il n'y a pas d'espace entre alors seulement .previousSibling.value


Vous n'avez pas besoin d'ajouter explicitement l'écouteur onclick comme auparavant, vous pouvez utiliser la bibliothèque jQuery pour ajouter dynamiquement l'écouteur click avec fonction pour changer la valeur de toutes les cases à cocher de votre page:

$('input[type=checkbox]').click(function()
{
  if(this.checked)
  {
    $(this).prev().val('Y');
  }
  else
  {
    $(this).prev().val('N');
  }
});
sbrbot
la source
1

Toutes les réponses sont excellentes, mais si vous avez plusieurs cases à cocher dans un formulaire du même nom et que vous souhaitez publier le statut de chaque case à cocher. Ensuite, j'ai résolu ce problème en plaçant un champ caché avec la case à cocher (nom lié à ce que je veux).

<input type="hidden" class="checkbox_handler" name="is_admin[]" value="0" />
<input type="checkbox" name="is_admin_ck[]" value="1" />

puis contrôlez le changement d'état de la case à cocher en dessous du code jquery:

$(documen).on("change", "input[type='checkbox']", function() {
    var checkbox_val = ( this.checked ) ? 1 : 0;
    $(this).siblings('input.checkbox_handler').val(checkbox_val);
});

Désormais, en cas de modification d'une case à cocher, la valeur du champ masqué associé sera modifiée. Et sur le serveur, vous ne pouvez regarder que les champs cachés au lieu des cases à cocher.

J'espère que cela aidera quelqu'un à avoir ce type de problème. bravo :)

Imran Khan
la source
1

Le problème avec les cases à cocher est que si elles ne sont pas cochées, elles ne sont pas publiées avec votre formulaire. Si vous cochez une case et publiez un formulaire, vous obtiendrez la valeur de la case à cocher dans la variable $ _POST que vous pouvez utiliser pour traiter un formulaire, si elle n'est pas cochée, aucune valeur ne sera ajoutée à la variable $ _POST.

En PHP, vous contourneriez normalement ce problème en effectuant une vérification isset () sur votre élément de case à cocher. Si l'élément que vous attendez n'est pas défini dans la variable $ _POST, nous savons que la case n'est pas cochée et la valeur peut être fausse.

if(!isset($_POST['checkbox1']))
{
     $checkboxValue = false;
} else {
     $checkboxValue = $_POST['checkbox1'];
}

Mais si vous avez créé un formulaire dynamique, vous ne connaîtrez pas toujours l'attribut name de vos cases à cocher, si vous ne connaissez pas le nom de la case à cocher, vous ne pouvez pas utiliser la fonction isset pour vérifier si cela a été envoyé avec la variable $ _POST.

Daniel Galecki
la source
1
function SubmitCheckBox(obj) {
     obj.value   = obj.checked ? "on" : "off";
     obj.checked = true;
     return obj.form.submit();
}

<input type=checkbox name="foo" onChange="return SubmitCheckBox(this);">
ledav.net
la source
0

Il existe une meilleure solution de contournement. Tout d'abord, ne fournissez l'attribut de nom qu'aux cases à cocher qui sont cochées. Ensuite, en cliquant submit, à travers un JavaScript, functionvous cochez toutes les cases non cochées. Ainsi, lorsque vous submitseuls ceux-ci seront récupérés chez form collectionceux qui ont des namebiens.

  //removing name attribute from all checked checkboxes
                  var a = $('input:checkbox:checked');
                   $(a).each(function () {
                       $(this).removeAttr("name");        
                   });

   // checking all unchecked checkboxes
                   var b = $("input:checkbox:not(:checked)");
                   $(b).each(function () {
                       $(this).attr("checked", true);
                   });

Avantage: pas besoin de créer de boîtes cachées supplémentaires et de les manipuler.

Gyanesh Gouraw
la source
0

@cpburnz a bien fait mais avec beaucoup de code, voici la même idée en utilisant moins de code:

JS:

// jQuery OnLoad
$(function(){
    // Listen to input type checkbox on change event
    $("input[type=checkbox]").change(function(){
        $(this).parent().find('input[type=hidden]').val((this.checked)?1:0);
    });
});

HTML (notez le nom du champ en utilisant un nom de tableau):

<div>
    <input type="checkbox" checked="checked">
    <input type="hidden" name="field_name[34]" value="1"/>
</div>
<div>
    <input type="checkbox">
    <input type="hidden" name="field_name[35]" value="0"/>
</div>
<div>

Et pour PHP:

<div>
    <input type="checkbox"<?=($boolean)?' checked="checked"':''?>>
    <input type="hidden" name="field_name[<?=$item_id?>]" value="<?=($boolean)?1:0?>"/>
</div>
Polo Rodrigo
la source
0

Version jQuery de la réponse de @ vishnu.

if($('#testName').is(":checked")){
    $('#testNameHidden').prop('disabled', true);
}

Si vous utilisez jQuery 1.5 ou une version antérieure, veuillez utiliser la fonction .attr () au lieu de .prop ()

0x1ad2
la source
0

Cette solution est inspirée de celle de @ desw.

Si vos noms d'entrée sont en "style de formulaire", vous perdrez l'association d'index de tableau avec vos valeurs de chekbox dès qu'une chekbox est vérifiée, incrémentant cette "dissociation" d'une unité à chaque fois qu'une chekbox est vérifiée. Cela peut être le cas d'un formulaire pour insérer quelque chose comme des employés composé de certains champs, par exemple:

<input type="text" name="employee[]" />
<input type="hidden" name="isSingle[] value="no" />
<input type="checkbox" name="isSingle[] value="yes" />

Si vous insérez trois employés à la fois et que le premier et le second sont uniques, vous vous retrouverez avec un élément à 5 éléments isSingle tableau à , de sorte que vous ne pourrez pas parcourir à la fois les trois tableaux afin, par exemple, , insérez les employés dans une base de données.

Vous pouvez surmonter cela avec un post-traitement de tableau simple. J'utilise PHP côté serveur et je l'ai fait:

$j = 0;
$areSingles = $_POST['isSingle'];
foreach($areSingles as $isSingle){
  if($isSingle=='yes'){
    unset($areSingles[$j-1]);
  }
  $j++;
}
$areSingles = array_values($areSingles);
Pere
la source
0

Cette solution est donc exagérée pour cette question, mais elle m'a aidé lorsque j'ai eu la même case à cocher qui s'est produite plusieurs fois pour différentes lignes d'un tableau. Je devais connaître la ligne représentée par la case à cocher et connaître également l'état de la case à cocher (cochée / décochée).

Ce que j'ai fait était de retirer l'attribut name de mes entrées de case à cocher, de leur donner la même classe et de créer une entrée cachée qui contiendrait l'équivalent JSON des données.

HTML

 <table id="permissions-table">
    <tr>
	<td>
	    <input type="checkbox" class="has-permission-cb" value="Jim">
	    <input type="checkbox" class="has-permission-cb" value="Bob">
	    <input type="checkbox" class="has-permission-cb" value="Suzy">
	</td>
    </tr>
 </table>
 <input type="hidden" id="has-permissions-values" name="has-permissions-values" value="">

Javascript pour exécuter le formulaire soumettre

var perms = {};
$(".has-permission-checkbox").each(function(){
  var userName = this.value;
  var val = ($(this).prop("checked")) ? 1 : 0
  perms[userName] = {"hasPermission" : val};
});
$("#has-permissions-values").val(JSON.stringify(perms));

La chaîne json sera transmise avec le formulaire sous la forme $ _POST ["has-permissions-values"]. En PHP, décodez la chaîne en un tableau et vous aurez un tableau associatif qui a chaque ligne et la valeur vrai / faux pour chaque case à cocher correspondante. Il est alors très facile de parcourir et de comparer les valeurs actuelles de la base de données.

Tmac
la source