Pourquoi les boutons radio ne peuvent-ils pas être "en lecture seule"?

214

Je voudrais montrer un bouton radio, avoir sa valeur soumise, mais selon les circonstances, ne pas l'éditer. Désactivé ne fonctionne pas, car il ne soumet pas la valeur (ou le fait-il?), Et il grise le bouton radio. La lecture seule est vraiment ce que je recherche, mais pour une raison mystérieuse, cela ne fonctionne pas.

Y a-t-il une astuce étrange que je dois tirer pour que la lecture seule fonctionne comme prévu? Dois-je simplement le faire en JavaScript à la place?

Soit dit en passant, quelqu'un sait-il pourquoi la lecture seule ne fonctionne pas dans les boutons radio, alors qu'elle fonctionne dans d'autres balises d'entrée? Est-ce une de ces omissions incompréhensibles dans les spécifications HTML?

mcv
la source
5
"Est-ce une de ces omissions incompréhensibles dans les spécifications HTML?" Pensez-y du point de vue d'un utilisateur. Pourquoi afficher un bouton sur lequel ils ne peuvent pas cliquer?
Paul D. Waite
67
Pourquoi afficher un bouton sur lequel ils ne peuvent pas cliquer? Parce que je veux qu'ils sachent que le bouton est là, mais je ne veux pas qu'ils puissent cliquer dessus maintenant. Mais peut-être plus tard. C'est une forme dynamique, après tout. Pourquoi un bouton radio serait-il différent de tout autre champ de saisie?
mcv
7
Voici la spécification: w3.org/TR/html401/interact/forms.html#h-17.12.2 "Les éléments suivants prennent en charge l'attribut en lecture seule: INPUT et TEXTAREA." Ce qui est évidemment faux. Ici, cependant, nous voyons un résumé plus précis: w3.org/TR/WD-forms-970402#readonly "READONLY s'applique aux éléments INPUT de type TEXT ou PASSWORD et à l'élément TEXTAREA." On dirait que cela a glissé entre les lacunes des recommandations et des spécifications.
graphicdivine
Encore plus curieux. Selon cet ancien document "Dans les cases à cocher, par exemple, vous pouvez les activer ou les désactiver (définissant ainsi l'état VÉRIFIÉ) mais vous ne modifiez pas la valeur du champ." ( htmlcodetutorial.com/forms/_INPUT_DISABLED.html ) Est-ce vrai? Le réglage READONLY sur une case à cocher / radio verrouille-t-il la valeur, même si l'utilisateur peut apparemment la modifier?
graphicdivine
check my post [here] [1] donne une solution simple et propre au problème [1]: stackoverflow.com/a/15513256/1861389
driven4ward

Réponses:

149

J'ai simulé en lecture seule un bouton radio en désactivant uniquement les boutons radio non cochés. Cela empêche l'utilisateur de sélectionner une valeur différente, et la valeur vérifiée sera toujours publiée lors de la soumission.

Utiliser jQuery pour faire de la lecture seule:

$(':radio:not(:checked)').attr('disabled', true);

Cette approche a également fonctionné pour créer une liste de sélection en lecture seule, sauf que vous devrez désactiver chaque option non sélectionnée.

Megan
la source
2
Merci @Megan, c'est une excellente solution
Michael La Voie
9
Une variation à ce sujet pour vous permettre d'utiliser la readonlypropriété, comme l'OP s'attendait à ce qu'elle fonctionne:$(':radio[readonly]:not(:checked)').attr('disabled', true);
wodow
1
Parmi les solutions ci-dessous, cette solution fournit le code le plus propre et fonctionne bien avec le validateur Jquery car je n'ai pas besoin d'activer / désactiver les champs, ni de gérer les événements de clic non liés et de les relier lors de la soumission du formulaire.
Kristianne Nerona
Fonctionne avec précision. Merci
Hassan Farooq
Intelligent! En utilisant .not (..), dans le cas où vous avez déjà un ensemble de champs de saisie sélectionnés: var myRadios = $ ('# specific-radios'); myRadios.not (': vérifié'). prop ('désactivé', vrai); api.jquery.com/not
JoePC
207

Les boutons radio n'auraient besoin d'être en lecture seule que s'il existe d'autres options. Si vous n'avez aucune autre option, un bouton radio coché ne peut pas être décoché. Si vous avez d'autres options, vous pouvez empêcher l'utilisateur de modifier la valeur simplement en désactivant les autres options:

<input type="radio" name="foo" value="Y" checked>
<input type="radio" name="foo" value="N" disabled>

Violon: http://jsfiddle.net/qqVGu/

Sampson
la source
3
Le problème avec votre première solution est que si je veux activer le bouton radio via javascript, j'ai soudainement deux champs avec le même nom, donc je dois en nettoyer un. Ou utilisez celui caché pour de vrai et faites en sorte que le bouton radio définisse simplement la valeur du champ caché. Ether way, c'est juste un peu plus lourd que j'aimerais un radiobutton. Votre deuxième solution, même si je ne doute pas que cela fonctionne, ressemble à un hack vraiment moche. Je suppose donc que la solution javascript est la seule qui répond à mes critères. J'irai avec ça.
mcv
7
Solution 1 s'il vous plaît! C'est le seul bien accessible. Et si vous avez besoin de l'écrire, ce n'est qu'une ligne de plus pour définir l'activation du champ caché à l'opposé de l'activation de la radio.
bobince
5
Je viens de remarquer que les solutions 2 et 3 ont changé de place dans la réponse de Jonathan, alors maintenant les commentaires ne semblent pas avoir beaucoup de sens.
mcv
1
Vous voulez remarquer que la solution Javascript ne fonctionne pas, elle décoche simplement le bouton. Je suppose que cela doit être onclick="return false"pour empêcher le changement.
dmitry
2
Lorsque je mets la radio «désactivée», j'ajoute «style = curseur: par défaut» pour supprimer «curseur désactivé».
Joao Paulo
24

C'est l'astuce que vous pouvez suivre.

<input type="radio" name="name" onclick="this.checked = false;" />
Sarfraz
la source
4
Exactement ce que je pensais, mais il serait préférable que vous clarifiiez que cela devrait être onClick="this.checked = <%=value%>"d'une certaine variété :)
JustLoren
c'est bon à savoir. cochée peut avoir une valeur vraie ou fausse.
Sarfraz
Juste un avertissement que cela ne fonctionnera pas pour ceux d'entre nous qui naviguent avec javascript non activé par défaut.
tloach
3
Pas de problème pour mon cas. Nous utilisons déjà des tonnes de jQuery et Ajax.
mcv
1
Il convient de noter que vous pouvez simplement faire onclick="return false;"pour conserver la même valeur pour le groupe
Zach
12

J'ai un long formulaire (250+ champs) qui publie sur une base de données. Il s'agit d'une demande d'emploi en ligne. Lorsqu'un administrateur examine une demande déposée, le formulaire est rempli avec des données de la base de données. Les textes d'entrée et les zones de texte sont remplacés par le texte qu'ils ont soumis, mais les radios et les cases à cocher sont utiles à conserver comme éléments de formulaire. Les désactiver les rend plus difficiles à lire. La définition de la propriété .checked sur false onclick ne fonctionnera pas car ils peuvent avoir été vérifiés par l'utilisateur remplissant l'application. De toute façon...

onclick="return false;"

fonctionne comme un charme pour «désactiver» les radios et les cases à cocher ipso facto.

humbolight
la source
8

La meilleure solution consiste à définir l'état vérifié ou non vérifié (à partir du client ou du serveur) et à ne pas laisser l'utilisateur le modifier après la protection (c'est-à-dire le rendre en lecture seule), procédez comme suit:

<input type="radio" name="name" onclick="javascript: return false;" />
Vipresh
la source
non! dans ce cas, l'utilisateur peut modifier le html dans le navigateur, marquer l'option souhaitée comme sélectionnée et publier le formulaire.
error1009
2

J'ai trouvé un moyen lourd en javascript pour obtenir un état en lecture seule pour les cases à cocher et les boutons radio. Il est testé par rapport aux versions actuelles de Firefox, Opera, Safari, Google Chrome, ainsi que les versions actuelles et précédentes d'IE (jusqu'à IE7).

Pourquoi ne pas simplement utiliser la propriété pour handicapés que vous demandez? Lors de l'impression de la page, les éléments d'entrée désactivés apparaissent en gris. Le client pour lequel cela a été mis en œuvre voulait que tous les éléments soient de la même couleur.

Je ne sais pas si je suis autorisé à publier le code source ici, car j'ai développé cela en travaillant pour une entreprise, mais je peux sûrement partager les concepts.

Avec les événements onmousedown, vous pouvez lire l'état de sélection avant que l'action de clic ne le modifie. Vous stockez donc ces informations, puis restaurez ces états avec un événement onclick.

<input id="r1" type="radio" name="group1" value="r1" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);" checked="checked">Option 1</input>
<input id="r2" type="radio" name="group1" value="r2" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);">Option 2</input>
<input id="r3" type="radio" name="group1" value="r3" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);">Option 3</input>

<input id="c1" type="checkbox" name="group2" value="c1" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);" checked="checked">Option 1</input>
<input id="c2" type="checkbox" name="group2" value="c2" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);">Option 2</input>
<input id="c3" type="checkbox" name="group2" value="c3" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);" checked="checked">Option 3</input>

La partie javascript de cela fonctionnerait alors comme ceci (encore une fois seulement les concepts):

var selectionStore = new Object();  // keep the currently selected items' ids in a store

function storeSelectedRadiosForThisGroup(elementName) {
    // get all the elements for this group
    var radioOrSelectGroup = document.getElementsByName(elementName);

    // iterate over the group to find the selected values and store the selected ids in the selectionStore
    // ((radioOrSelectGroup[i].checked == true) tells you that)
    // remember checkbox groups can have multiple checked items, so you you might need an array for the ids
    ...
}

function setSelectedStateForEachElementOfThisGroup(elementName) {
    // iterate over the group and set the elements checked property to true/false, depending on whether their id is in the selectionStore
    ...

    // make sure you return false here
    return false;
}

Vous pouvez désormais activer / désactiver les cases d'option / cases à cocher en modifiant les propriétés onclick et onmousedown des éléments d'entrée.

À M
la source
2

Pour les boutons radio non sélectionnés, marquez-les comme désactivés. Cela les empêche de répondre aux entrées de l'utilisateur et d'effacer le bouton radio coché. Par exemple:

<input type="radio" name="var" checked="yes" value="Yes"></input>
<input type="radio" name="var" disabled="yes" value="No"></input>
dpolican
la source
4
checked="yes"? Quelle est cette spécification? Soit utiliser checked="checked"soit juste l'attribut checkedsans valeur. Pareil pour disabled.
Robin van Baalen
2

Manière JavaScript - cela a fonctionné pour moi.

<script>
$(document).ready(function() {
   $('#YourTableId').find('*').each(function () { $(this).attr("disabled", true); });
});
</script>

Raison:

  1. $('#YourTableId').find('*') -> cela renvoie toutes les balises.

  2. $('#YourTableId').find('*').each(function () { $(this).attr("disabled", true); }); itère tous les objets capturés dans ce champ et désactive les balises d'entrée.

Analyse (débogage):

  1. form:radiobutton est considéré en interne comme une balise "d'entrée".

  2. Comme dans la fonction ci-dessus (), si vous essayez d'imprimer document.write(this.tagName);

  3. Partout où, dans les balises, il trouve des boutons radio, il renvoie une balise d'entrée.

Ainsi, la ligne de code ci-dessus peut être plus optimisée pour les balises de bouton radio, en remplaçant * par une entrée: $('#YourTableId').find('input').each(function () { $(this).attr("disabled", true); });

user3702798
la source
1

Une option assez simple serait de créer une fonction javascript appelée sur l'événement "onsubmit" du formulaire pour réactiver le bouton radio afin que sa valeur soit publiée avec le reste du formulaire.
Cela ne semble pas être une omission sur les spécifications HTML, mais un choix de conception (logique, à mon humble avis), un bouton radio ne peut pas être lu uniquement comme un bouton ne peut pas l'être, si vous ne voulez pas l'utiliser, alors le désactiver.

hiver
la source
1

J'ai trouvé que l'utilisation onclick='this.checked = false;'fonctionnait dans une certaine mesure. Un bouton radio sur lequel vous avez cliqué ne sera pas sélectionné. Cependant, s'il y avait un bouton radio qui était déjà sélectionné (par exemple, une valeur par défaut), ce bouton radio deviendrait non sélectionné.

<!-- didn't completely work -->
<input type="radio" name="r1" id="r1" value="N" checked="checked" onclick='this.checked = false;'>N</input>
<input type="radio" name="r1" id="r1" value="Y" onclick='this.checked = false;'>Y</input>

Pour ce scénario, laisser la valeur par défaut et désactiver les autres boutons radio préserve le bouton radio déjà sélectionné et l'empêche d'être désélectionné.

<!-- preserves pre-selected value -->
<input type="radio" name="r1" id="r1" value="N" checked="checked">N</input>
<input type="radio" name="r1" id="r1" value="Y" disabled>Y</input>

Cette solution n'est pas le moyen le plus élégant d'empêcher la modification de la valeur par défaut, mais elle fonctionnera, que javascript soit activé ou non.

JW8
la source
1

Essayez l'attribut disabled, mais je pense que vous n'obtiendrez pas la valeur des boutons radio. Ou définissez des images à la place comme:

<img src="itischecked.gif" alt="[x]" />radio button option

Meilleures salutations.

Tim
la source
1
oh, mon code html a été supprimé: img src = "itIsChecked.gif" alt = "[x]" OptionChecked
Tim
0

J'utilise un plugin JS qui style les cases à cocher / éléments d'entrée radio et j'ai utilisé la requête jQuery suivante pour établir un `` état en lecture seule '' où la valeur sous-jacente est toujours publiée mais l'élément d'entrée semble inaccessible à l'utilisateur, ce qui est, je crois, la raison prévue nous utiliserions un attribut d'entrée en lecture seule ...

if ($(node).prop('readonly')) {
    $(node).parent('div').addClass('disabled'); // just styling, appears greyed out
    $(node).on('click', function (e) {
        e.preventDefault();
    });
}
chopstik
la source