Perché i pulsanti di opzione non possono essere "di sola lettura"?


214

Vorrei mostrare un pulsante di opzione, avere il suo valore inviato, ma a seconda delle circostanze, non può essere modificato. Disabilitato non funziona, perché non invia il valore (o lo fa?) E disattiva il pulsante di opzione. Sola lettura è davvero quello che sto cercando, ma per qualche misteriosa ragione non funziona.

C'è qualche strano trucco che devo tirare per ottenere la sola lettura per funzionare come previsto? Dovrei semplicemente farlo in JavaScript invece?

Per inciso, qualcuno sa perché la sola lettura non funziona nei pulsanti di opzione, mentre funziona in altri tag di input? Questa è una di quelle incomprensibili omissioni nelle specifiche HTML?


5
"Questa è una di quelle incomprensibili omissioni nelle specifiche HTML?" Pensalo dal punto di vista di un utente. Perché visualizzare un pulsante su cui non possono fare clic?
Paul D. Waite,

67
Perché visualizzare un pulsante su cui non possono fare clic? Perché voglio che sappiano che il pulsante è lì, ma non voglio che siano in grado di fare clic al momento. Ma forse dopo. È una forma dinamica, dopo tutto. Perché un pulsante di opzione sarebbe diverso da qualsiasi altro campo di input?
mcv,

7
Ecco le specifiche: w3.org/TR/html401/interact/forms.html#h-17.12.2 "I seguenti elementi supportano l'attributo readonly: INPUT e TEXTAREA." Il che è ovviamente sbagliato. Di seguito, però, vediamo un riepilogo più accurato: w3.org/TR/WD-forms-970402#readonly "READONLY si applica agli elementi INPUT di tipo TEXT o PASSWORD e all'elemento TEXTAREA." Sembra che questo sia scivolato tra le lacune di recs e specifiche.
graphicdivine,

Ancora più curioso. Secondo questo antico documento "Nelle caselle di controllo, ad esempio, è possibile selezionarle o disattivarle (impostando così lo stato VERIFICATO) ma non si modifica il valore del campo". ( htmlcodetutorial.com/forms/_INPUT_DISABLED.html ) È vero? L'impostazione READONLY su una casella / radio blocca il valore, anche se l'utente può apparentemente modificarlo?
graphicdivine,

controllare il mio post [qui] [1] dà una soluzione semplice pulito alla questione [1]: stackoverflow.com/a/15513256/1861389
driven4ward

Risposte:


149

Ho falsificato di sola lettura un pulsante di opzione disabilitando solo i pulsanti di opzione non selezionati. Impedisce all'utente di selezionare un valore diverso e il valore selezionato verrà sempre pubblicato al momento dell'invio.

Utilizzando jQuery per rendere di sola lettura:

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

Questo approccio ha funzionato anche per creare un elenco di selezione in sola lettura, tranne per il fatto che dovrai disabilitare ogni opzione non selezionata.


2
Grazie @Megan, questa è un'ottima soluzione
Michael La Voie,

9
Una variazione su questo per permetterti di usare la readonlyproprietà, poiché l'OP si aspettava che funzionasse:$(':radio[readonly]:not(:checked)').attr('disabled', true);
wodow,

1
Tra le soluzioni di seguito, questa soluzione fornisce il codice più pulito e funziona bene con il validatore Jquery poiché non ho bisogno di abilitare / disabilitare i campi, o gestire eventi di clic non vincolanti e ricollegarli quando invio il modulo.
Kristianne Nerona,

Funziona accuratamente. Grazie
Hassan Farooq,

Intelligente! Usando .not (..), nel caso in cui tu abbia già una serie di campi di input selezionati: var myRadios = $ ('# specific-radio'); myRadios.not ( ': checked') prop ( 'disabilitato', true);. api.jquery.com/not
JoePC

207

I pulsanti di opzione dovrebbero essere di sola lettura se ci sono altre opzioni. Se non hai altre opzioni, un pulsante di opzione selezionato non può essere deselezionato. Se hai altre opzioni, puoi impedire all'utente di modificare il valore semplicemente disabilitando le altre opzioni:

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

Fiddle: http://jsfiddle.net/qqVGu/


3
Il problema con la tua prima soluzione è che se voglio abilitare il pulsante di opzione tramite JavaScript, improvvisamente ho due campi con lo stesso nome, quindi devo ripulirne uno. Oppure usa quello nascosto per davvero e il pulsante di opzione imposta semplicemente il valore del campo nascosto. Modo eterico, è solo un po 'più ingombrante di quanto vorrei un pulsante radio. La tua seconda soluzione, anche se non dubito che funzioni, sembra davvero un brutto hack. Quindi immagino che la soluzione javascript sia l'unica che soddisfi i miei criteri. Vado con quello.
mcv,

7
Soluzione 1 per favore! È l'unico adeguatamente accessibile. E se è necessario copiarlo, è solo un'altra riga per impostare l'abilitazione del campo nascosto sull'opposto dell'abilitazione della radio.
Bobince,

5
Ho appena notato che le soluzioni 2 e 3 hanno cambiato posizione nella risposta di Jonathan, quindi ora i commenti non sembrano avere molto senso.
mcv,

1
Vuoi notare che la soluzione Javascript non funziona, deseleziona semplicemente il pulsante. Suppongo che debba essere onclick="return false"per impedire il cambiamento.
Dmitry

2
Quando imposto la radio "disabilitato" aggiungo "stile = cursore: impostazione predefinita" per rimuovere "cursore disabilitato".
Joao Paulo,

24

Questo è il trucco con cui puoi andare.

<input type="radio" name="name" onclick="this.checked = false;" />

4
Esattamente quello che stavo pensando, tuttavia sarebbe meglio se chiarissi che dovrebbe essere onClick="this.checked = <%=value%>"di una certa varietà :)
JustLoren,

è bello sapere. controllato può avere valori veri o falsi.
Sarfraz,

Solo un avvertimento che questo non funzionerà per quelli di noi che navigano con javascript non attivato per impostazione predefinita.
contattare il

3
Non è un problema per il mio caso. Usiamo già tonnellate di jQuery e Ajax.
mcv,

1
Vale la pena notare che puoi fare solo onclick="return false;"per mantenere lo stesso valore per il gruppo
Zach

12

Ho una forma lunga (oltre 250 campi) che pubblica su un db. Si tratta di una domanda di lavoro online. Quando un amministratore esamina un'applicazione che è stata archiviata, il modulo viene popolato con i dati dal database. I testi e le aree di testo di input vengono sostituiti con il testo inviato, ma le radio e le caselle di controllo sono utili da conservare come elementi del modulo. Disabilitarli li rende più difficili da leggere. L'impostazione della proprietà .checked su false onclick non funzionerà perché potrebbe essere stata verificata dall'utente compilando l'app. Comunque...

onclick="return false;"

funziona come un fascino per "disabilitare" le radio e le caselle di controllo ipso facto.


8

La soluzione migliore è impostare lo stato selezionato o deselezionato (dal client o dal server) e non consentire all'utente di modificarlo dopo i reparti (ovvero renderlo di sola lettura):

<input type="radio" name="name" onclick="javascript: return false;" />

no! in questo caso, l'utente può modificare HTML nel browser, contrassegnare l'opzione necessaria come selezionata e pubblicare il modulo.
errore 1009

2

Ho escogitato un modo pesantemente javascript per raggiungere uno stato di sola lettura per caselle di controllo e pulsanti di opzione. È testato con le versioni attuali di Firefox, Opera, Safari, Google Chrome, nonché con le versioni attuali e precedenti di IE (fino a IE7).

Perché non usare semplicemente la proprietà per disabili che chiedi? Quando si stampa la pagina, gli elementi di input disabilitati vengono visualizzati in grigio. Il cliente per il quale era stato implementato voleva che tutti gli elementi risultassero dello stesso colore.

Non sono sicuro di poter pubblicare qui il codice sorgente, poiché l'ho sviluppato mentre lavoravo per un'azienda, ma posso sicuramente condividere i concetti.

Con gli eventi onmousedown, è possibile leggere lo stato di selezione prima che l'azione del clic lo cambi. Quindi memorizzi queste informazioni e poi ripristini questi stati con un evento 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 parte javascript di questo funzionerebbe quindi in questo modo (di nuovo solo i concetti):

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;
}

Ora puoi abilitare / disabilitare i pulsanti di opzione / le caselle di controllo modificando le proprietà onclick e onmousedown degli elementi di input.


2

Per i pulsanti di opzione non selezionati, contrassegnarli come disabilitati. Ciò impedisce loro di rispondere all'input dell'utente e di cancellare il pulsante di opzione selezionato. Per esempio:

<input type="radio" name="var" checked="yes" value="Yes"></input>
<input type="radio" name="var" disabled="yes" value="No"></input>

4
checked="yes"? Che specifica è quella? Utilizzare checked="checked"o solo l'attributo checkedsenza un valore. Lo stesso per disabled.
Robin van Baalen,

2

Modo JavaScript - questo ha funzionato per me.

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

Motivo:

  1. $('#YourTableId').find('*') -> questo restituisce tutti i tag.

  2. $('#YourTableId').find('*').each(function () { $(this).attr("disabled", true); }); scorre su tutti gli oggetti catturati in questo e disabilita i tag di input.

Analisi (debug):

  1. form:radiobutton è considerato internamente come un tag "input".

  2. Come nella funzione sopra (), se si prova a stampare document.write(this.tagName);

  3. Ovunque, nei tag trova i pulsanti di opzione, restituisce un tag di input.

Quindi, sopra la riga di codice può essere più ottimizzata per i tag dei pulsanti di opzione, sostituendo * con input: $('#YourTableId').find('input').each(function () { $(this).attr("disabled", true); });


1

Un'opzione abbastanza semplice sarebbe quella di creare una funzione javascript chiamata sull'evento "onsubmit" del modulo per abilitare il pulsante di opzione in modo che il suo valore sia pubblicato con il resto del modulo.
Non sembra essere un'omissione sulle specifiche HTML, ma una scelta di progettazione (una logica, IMHO), un pulsante di opzione non può essere di sola lettura come un pulsante non può essere, se non si desidera utilizzarlo, quindi disabilitalo.


1

Ho scoperto che l'uso ha onclick='this.checked = false;'funzionato in una certa misura. Un pulsante di opzione su cui è stato fatto clic non sarebbe stato selezionato. Tuttavia, se fosse già stato selezionato un pulsante di opzione (ad esempio, un valore predefinito), quel pulsante di opzione verrebbe non selezionato.

<!-- 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>

Per questo scenario, lasciando da solo il valore predefinito e disabilitando gli altri pulsanti di opzione si conserva il pulsante di opzione già selezionato e si impedisce la deselezione.

<!-- 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>

Questa soluzione non è il modo più elegante per impedire la modifica del valore predefinito, ma funzionerà indipendentemente dal fatto che JavaScript sia abilitato o meno.


1

Prova l'attributo disabled, ma penso che non otterrai il valore dei pulsanti di opzione. O imposta le immagini invece come:

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

I migliori saluti.


1
oh, il mio codice html è stato rimosso: img src = "itIsChecked.gif" alt = "[x]" OptionChecked
Tim

0

Sto usando un plug-in JS che modella gli elementi di input radio / casella di controllo e ho usato il seguente jQuery per stabilire uno "stato di sola lettura" in cui il valore sottostante è ancora pubblicato ma l'elemento di input sembra inaccessibile all'utente, che credo ritenga il motivo previsto useremmo un attributo di input di sola lettura ...

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.