Come posso rendere un intero modulo HTML "di sola lettura"?


155

Ho due pagine con moduli HTML. La prima pagina ha un modulo di invio e la seconda pagina ha un modulo di riconoscimento. Il primo modulo offre una scelta di numerosi controlli, mentre la seconda pagina visualizza nuovamente i dati dal modulo di invio con un messaggio di conferma. In questo secondo modulo tutti i campi devono essere statici.

Da quello che posso vedere, alcuni controlli del modulo possono essere readonlye tutti possono essere disabled, la differenza è che puoi ancora passare a un campo di sola lettura.

Invece di eseguire questo campo per campo, esiste un modo per contrassegnare l'intero modulo come di sola lettura / disabilitato / statico in modo tale che l'utente non possa modificare nessuno dei controlli?

Risposte:


310

Avvolgere i campi di input e altre cose in a <fieldset>e dargli l' disabled="disabled"attributo.

Esempio ( http://jsfiddle.net/7qGHN/ ):

<form>
    <fieldset disabled="disabled">
        <input type="text" name="something" placeholder="enter some text" />
        <select>
            <option value="0" disabled="disabled" selected="selected">select somethihng</option>
            <option value="1">woot</option>
            <option value="2">is</option>
            <option value="3">this</option>
        </select>
    </fieldset>
</form>


2
soluzione semplice e piacevole per me. Grazie
demo

2
Migliore soluzione per il lato client :) +1
Sisir

1
Abbastanza semplice, questa è la migliore soluzione lato client finora.
Brunocoelho,

Nota: questo ha l'effetto collaterale di rendere "i controlli del modulo che sono [i set di campi] discendenti, tranne i discendenti del suo primo elemento <legend> opzionale ... [non] ricevere eventi di navigazione, come clic del mouse o focus "( developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset ). Quindi tutti i listener di eventi js che potresti aver definito su discendenti potrebbero non funzionare.
Eric Freese,

2
@EricFreese Solo in stato disabilitato, che è quello che vuoi nel 99% dei casi.
Honza Kalfus,

11

Non tutti gli elementi del modulo possono essere impostati su readonly, ad esempio:

  • caselle di controllo
  • box radio
  • upload di file
  • ...Di Più..

Quindi la soluzione ragionevole sarebbe quella di impostare tutti gli disabledattributi degli elementi del modulo true, poiché l'OP non ha dichiarato che il modulo specifico "bloccato" dovrebbe essere inviato al server (cosa che l' disabledattributo non consente).

Un'altra soluzione, che viene presentata nella demo di seguito, è quella di posizionare un livello sopra l' formelemento che impedirà qualsiasi interazione con tutti gli elementi all'interno formdell'elemento, poiché quel livello è impostato con un z-indexvalore maggiore :

DEMO:

var form = document.forms[0], // form element to be "readonly"
    btn1 = document.querySelectorAll('button')[0],
    btn2 = document.querySelectorAll('button')[1]

btn1.addEventListener('click', lockForm)
btn2.addEventListener('click', lockFormByCSS)

function lockForm(){
  btn1.classList.toggle('on');
  [].slice.call( form.elements ).forEach(function(item){
      item.disabled = !item.disabled;
  });
}

function lockFormByCSS(){
  btn2.classList.toggle('on');
  form.classList.toggle('lock');
}
form{ position:relative; } 
form.lock::before{
  content:'';
  position:absolute;
  z-index:999;
  top:0;
  right:0;
  bottom:0;
  left:0;
}

button.on{ color:red; }
<button type='button'>Lock / Unlock Form</button>
<button type='button'>Lock / Unlock Form (with CSS)</button>
<br><br>
<form>
  <fieldset>
    <legend>Some Form</legend>
    <input placeholder='text input'>
    <br><br>
    <input type='file'>
    <br><br>
    <textarea placeholder='textarea'></textarea>
    <br><br>
    <label><input type='checkbox'>Checkbox</label>
    <br><br>
    <label><input type='radio' name='r'>option 1</label>
    <label><input type='radio' name='r' checked>option 2</label>
    <label><input type='radio' name='r'>option 3</label>
    <br><br>
    <select>
      <option>options 1</option>
      <option>options 2</option>
      <option selected>options 3</option>
    </select>
  </fieldset>
</form>


1
Si noti che la soluzione CSS è incompleta in quanto non impedisce la navigazione da tastiera.
Tanriol,

7

È possibile utilizzare questa funzione per disabilitare il modulo:

function disableForm(formID){
  $('#' + formID).children(':input').attr('disabled', 'disabled');
}

Guarda la demo di lavoro qui

Si noti che utilizza jQuery.


+1 Grazie, ma non riesco a utilizzare le soluzioni lato client, vedi la domanda aggiornata (scusate, mia cattiva)
Mawg dice di ripristinare Monica il

6

Nella pagina di conferma, non inserire il contenuto in controlli modificabili, basta scriverli nella pagina.


1
Questo è davvero l'approccio più sano. Non presentare un modulo non modificabile a un utente o finirai per essere una voce nella domanda "Minor stupore".
Kibibu,

1
Come? Come posso visualizzare una casella di controllo e la sua condizione di controllo / non selezionata o un gruppo radio con l'elemento selezionato, ecc.?
Mawg dice di ripristinare Monica il

1
@Mawg forse sarebbe un'opzione per elencare solo gli elementi 'selezionati', senza caselle di controllo. Come su una conferma d'ordine della pizza: basta elencare tutti gli ingredienti che hai selezionato.
marc82ch,

In questo caso no, ma grazie per un buon pezzo di pensiero laterale che potrebbe aiutare gli altri.
Mawg dice di ripristinare Monica il

4

Non esiste un modo integrato che conosco per fare questo, quindi dovrai trovare una soluzione personalizzata a seconda di quanto sia complicato il tuo modulo. Dovresti leggere questo post:

Converti i moduli HTML in sola lettura ( Aggiornamento : link post interrotto, link archiviato )

EDIT: in base al tuo aggiornamento, perché sei così preoccupato di averlo di sola lettura? Puoi farlo dal lato client, ma in caso contrario dovrai aggiungere il tag richiesto a ciascun controllo o convertire i dati e visualizzarlo come testo non elaborato senza controlli. Se stai provando a renderlo di sola lettura in modo che il prossimo post non sia modificato, allora hai un problema perché chiunque può pasticciare con il post per produrre quello che vuole, quindi quando effettivamente ricevi i dati, è meglio che tu lo stia controllando di nuovo per assicurarsi che sia valido.


+1 Grazie, ma non riesco a utilizzare le soluzioni lato client, vedi la domanda aggiornata (scusate, mia cattiva)
Mawg dice di ripristinare Monica il

"In base al tuo aggiornamento, perché sei così preoccupato di averlo letto solo? Puoi farlo dal lato client" Mi dispiace, ma 1) Non posso farlo dal lato client (non è una mia scelta) e 2) se sembra all'utente come se stesse cambiando cose che potrebbero confonderlo.
Mawg dice di ripristinare Monica il

@mawg bene se è puramente per gli oggetti visivi, l'unica cosa che posso raccomandare è sostituire tutti i controlli in linea con il loro equivalente di testo o aggiungere la proprietà readonly ai controlli. Non esiste un proiettile d'argento e ho la sensazione che sia quello che stai cercando. Puoi pubblicare uno snippet del codice che sei autorizzato a modificare? Aiuterebbe solo a ottenere una base per quello con cui stai lavorando.
Kelsey,

+1 grazie per il suggerimento. Non l'avevo mai notato prima, ma devo aver compilato 100 o 1.000 se i moduli e vagamente ricordano una loro versione di sola lettura, non solo un testo. Forse dovrei compilarne un altro po 'e osservare :-)
Mawg dice di ripristinare Monica il

3
Sorpresa ... 6 anni dopo il link non funziona più.
mwallisch,

3

Non esiste un modo HTML ufficiale pienamente conforme per farlo, ma un po 'di javascript può fare molto. Un altro problema che incontrerai è che i campi disabilitati non vengono visualizzati nei dati POST


4
Se hai già convalidato i dati, devi comunque salvarli sul lato server. Inviarlo avanti e indietro al cliente è un grosso buco di sicurezza. Anche se usi css, js o html per congelare i campi, puoi modificarli con firebug o modificando manualmente la successiva richiesta HTTP
Michael Clerx,

+1 Grazie, ma non riesco a utilizzare le soluzioni lato client, vedi la domanda aggiornata (scusate, mia cattiva)
Mawg dice di ripristinare Monica il

3

Questa è una soluzione ideale per disabilitare tutti gli input , le textareas , le selezioni e i pulsanti in un elemento specificato.

Per jQuery 1.6 e versioni successive :

// To fully disable elements
$('#myForm :input').prop('disabled', true); 

O

// To make elements readonly
$('#myForm :input').prop('readonly', true); 

jQuery 1.5 e precedenti :

$('#myForm :input').prop('disabled', 'disabled');

E

$('#myForm :input').prop('readonly', 'readonly');

2

Un altro modo semplice supportato da tutti i browser sarebbe:

HTML:

<form class="disabled">
  <input type="text" name="name" />
  <input type="radio" name="gender" value="male">
  <input type="radio" name="gender" value="female">
  <input type="checkbox" name="vegetarian">
</form>

CSS:

.disabled {
  pointer-events: none;
  opacity: .4;
}

Ma tieni presente che il tabbing funziona ancora con questo approccio e che gli elementi con focus possono essere comunque manipolati dall'utente.


1

Avere tutti gli ID del modulo numerati ed eseguire un ciclo for in JS.

 for(id = 0; id<NUM_ELEMENTS; id++)
   document.getElementById(id).disabled = false; 

+1 Grazie, ma non riesco a utilizzare le soluzioni lato client, vedi la domanda aggiornata (scusate, mia cattiva)
Mawg dice di ripristinare Monica il

1

Preferirei usare jQuery:

$('#'+formID).find(':input').attr('disabled', 'disabled');

find () andrebbe molto più in profondità fino all'ennesimo bambino nidificato rispetto ai bambini (), che cerca solo i bambini immediati.


1
Grazie, ti voterò per averci provato, dato che sei nuovo. MA, tieni presente che ho chiaramente chiesto una soluzione solo lato server. A quel tempo ho solo codificato PHP e non ancora JS. Un suggerimento amichevole per leggere la domanda in quanto alcuni potrebbero effettivamente sottovalutarti per questo :-( Benvenuto a bordo :-)
Mawg dice di ripristinare Monica il

1

Il modo più semplice

$('#yourform *').prop('readonly', true);

è vero, ma questo è solo un esempio di ax, puoi cambiare il tuo secondo selettore in qualsiasi altro, ad esempio $ ('# yourform .yourclass_for_inputs'). prop ('readonly', true);
Samir Rahimy,

1

Aggiungi un livello HTML invisibile al modulo. Per esempio

<div class="coverContainer">
<form></form>
</div>

e stile:

.coverContainer{
    width: 100%;
    height: 100%;
    z-index: 100;
    background: rgba(0,0,0,0);
    position: absolute;
}

L'utente Ofcourse può nascondere questo livello nel browser web.

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.