Jak mogę uczynić cały formularz HTML „tylko do odczytu”?


155

Mam dwie strony z formularzami HTML. Pierwsza strona zawiera formularz zgłoszeniowy, a druga strona zawiera formularz potwierdzenia. Pierwszy formularz oferuje wybór wielu kontrolek, podczas gdy druga strona ponownie wyświetla dane z formularza zgłoszeniowego z komunikatem potwierdzającym. W tym drugim formularzu wszystkie pola muszą być statyczne.

Z tego, co widzę, niektóre kontrolki formularza mogą być readonlyi wszystkie mogą być disabled, różnica polega na tym, że nadal możesz tabulować pole tylko do odczytu.

Zamiast robić to pole po polu, czy istnieje sposób, aby oznaczyć cały formularz jako tylko do odczytu / wyłączony / statyczny, tak aby użytkownik nie mógł zmienić żadnej z kontrolek?

Odpowiedzi:


309

Zawiń pola wejściowe i inne rzeczy w a <fieldset>i nadaj mu disabled="disabled"atrybut.

Przykład ( 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
proste i świetne rozwiązanie dla mnie. Dzięki
demo

2
Najlepsze rozwiązanie dla klienta :) +1
Sisir

1
Całkiem proste, jak dotąd jest to najlepsze rozwiązanie po stronie klienta.
brunocoelho

Uwaga: ma to efekt uboczny polegający na tym, że „kontrolki formularza, które są [zestawami pól] podrzędnymi, z wyjątkiem elementów podrzędnych pierwszego opcjonalnego elementu <legend>… [nie] otrzymują żadnych zdarzeń przeglądania, takich jak kliknięcia myszą lub związane z fokusem ”( developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset ). Zatem wszelkie detektory zdarzeń js, które zdefiniowałeś dla elementów podrzędnych, mogą nie działać.
Eric Freese

2
@EricFreese Tylko w stanie wyłączonym, czego chcesz w 99% przypadków.
Honza Kalfus

11

Nie wszystkie elementy formularza można ustawić na readonly, na przykład:

  • pola wyboru
  • skrzynki radiowe
  • Udostępnianie pliku
  • ...więcej..

Wtedy rozsądnym rozwiązaniem byłoby ustawienie disabledatrybutów wszystkich elementów formularza na true, ponieważ OP nie określał, że konkretny „zablokowany” formularz powinien zostać wysłany do serwera (na co ten disabledatrybut nie pozwala).

Innym rozwiązaniem, które zostało zaprezentowane na poniższym demo, jest umieszczenie warstwy na wierzchu formelementu, co uniemożliwi jakąkolwiek interakcję ze wszystkimi elementami wewnątrz formelementu, ponieważ ta warstwa ma ustawioną większą z-indexwartość:

PRÓBNY:

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
Należy pamiętać, że rozwiązanie CSS jest niekompletne, ponieważ nie uniemożliwia nawigacji za pomocą klawiatury.
Tanriol


6

Na stronie potwierdzenia nie umieszczaj zawartości w edytowalnych formantach, po prostu zapisz je na stronie.


1
To naprawdę najbardziej rozsądne podejście. Nie prezentuj użytkownikowi nieedytowalnego formularza, bo skończysz jako wpis w pytaniu „Najmniej zdziwienia”.
kibibu

1
w jaki sposób? Jak mogę wyświetlić pole wyboru i jego stan zaznaczenia / niezaznaczenia lub grupę radiową z wybraną pozycją itp.?
Mawg mówi, że przywróć Monikę

1
@Mawg może byłaby to opcja, aby po prostu wyświetlić listę „wybranych” elementów, bez pól wyboru. Jak na potwierdzeniu zamówienia pizzy: po prostu wymień wszystkie wybrane składniki.
marc82ch

W tym przypadku nie, ale dziękuję za dobry kawałek bocznego myślenia, który może pomóc innym.
Mawg mówi, że przywróć Monikę

4

Nie ma żadnego wbudowanego sposobu, aby to zrobić, więc będziesz musiał wymyślić niestandardowe rozwiązanie w zależności od tego, jak skomplikowany jest Twój formularz. Powinieneś przeczytać ten post:

Konwertuj formularze HTML na tylko do odczytu ( Aktualizacja : uszkodzony link do posta, zarchiwizowany link )

EDYCJA: Dlaczego w oparciu o aktualizację tak martwisz się, że jest ona tylko do odczytu? Możesz to zrobić po stronie klienta, ale jeśli nie, będziesz musiał dodać wymagany tag do każdej kontrolki lub przekonwertować dane i wyświetlić je jako surowy tekst bez kontrolek. Jeśli próbujesz uczynić go tylko do odczytu, aby następny post był niezmodyfikowany, masz problem, ponieważ każdy może zepsuć post, aby wyprodukować cokolwiek zechce, więc kiedy w końcu otrzymasz dane, lepiej to sprawdź ponownie, aby upewnić się, że jest ważny.


+1 Dzięki, ale nie mogę korzystać z rozwiązań po stronie klienta, zobacz zaktualizowane pytanie (przepraszam, moja wina)
Mawg mówi, że przywróć Monikę

„W oparciu o swoją aktualizację, dlaczego tak się martwisz, że to tylko do odczytu? Możesz to zrobić po stronie klienta” Przepraszam, ale 1) nie mogę tego zrobić po stronie klienta (nie mój wybór) i 2) jeśli wygląda dla użytkownika, jakby zmieniał rzeczy, które mogą go zmylić.
Mawg mówi, że przywróć Monikę

@mawg cóż, jeśli jest to wyłącznie dla wizualizacji, jedyne, co mogę polecić, to zastąpienie wszystkich kontrolek w tekście ich odpowiednikiem tekstowym lub dodanie właściwości readonly do kontrolek. Nie ma srebrnej kuli i mam wrażenie, że właśnie tego szukasz. Czy możesz opublikować fragment kodu, który możesz modyfikować? Pomogłoby to po prostu uzyskać podstawę do tego, nad czym pracujesz.
Kelsey

+1 dzięki za sugestię. Nigdy wcześniej tego nie zauważyłem, ale musiałem wypełnić 100 lub 1000, jeśli formularze i niejasno pamiętam ich wersję tylko do odczytu, a nie tylko tekst. Może powinienem wypełnić kilka więcej i obserwować :-)
Mawg mówi, że przywróć Monikę

3
Niespodzianka ... 6 lat później link już nie działa.
mwallisch,

3

Nie ma w pełni zgodnego, oficjalnego sposobu na HTML, ale trochę javascript może wiele zdziałać. Innym problemem, na który napotkasz, jest to, że wyłączone pola nie pojawiają się w danych POST


4
Jeśli już zweryfikowałeś dane, i tak musisz je zapisać po stronie serwera. Przesyłanie go do klienta w tę iz powrotem jest wielką luką w zabezpieczeniach. Nawet jeśli używasz css, js lub html do zamrożenia pól, możesz edytować je za pomocą firebuga lub ręcznie zmieniając następne żądanie HTTP
Michael Clerx

+1 Dzięki, ale nie mogę korzystać z rozwiązań po stronie klienta, zobacz zaktualizowane pytanie (przepraszam, moja wina)
Mawg mówi, że przywróć Monikę

3

Jest to idealne rozwiązanie do wyłączania wszystkich wejść , obszarów tekstowych , zaznaczeń i przycisków w określonym elemencie.

Dla jQuery 1.6 i nowszych :

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

Lub

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

jQuery 1.5 i starsze :

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

I

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

2

Innym prostym sposobem obsługiwanym przez wszystkie przeglądarki byłoby:

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

Należy jednak pamiętać, że tabulacja nadal działa z tym podejściem, a użytkownik może nadal manipulować elementami z fokusem.


1

Miej ponumerowane wszystkie identyfikatory formularzy i uruchom pętlę for w JS.

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

+1 Dzięki, ale nie mogę korzystać z rozwiązań po stronie klienta, zobacz zaktualizowane pytanie (przepraszam, moja wina)
Mawg mówi, że przywróć Monikę

1

Wolałbym raczej używać jQuery:

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

Funkcja find () sięgałaby znacznie głębiej do n-tego zagnieżdżonego dziecka niż children (), która szuka tylko najbliższych dzieci.


1
Dzięki, zagłosuję za próbą, ponieważ jesteś nowy. ALE proszę zauważyć, że wyraźnie poprosiłem o rozwiązanie tylko po stronie serwera. W tamtym czasie kodowałem tylko PHP, a nie JS. Przyjazna wskazówka, aby przeczytać pytanie, ponieważ niektórzy mogą cię za to zagłosować :-( Witamy na pokładzie :-)
Mawg mówi, że przywróć Monikę

1

Najprostszy sposób

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

to prawda, ale to tylko przykład ax, możesz zmienić swój drugi selektor na dowolny inny, na przykład $ ('# yourform .yourclass_for_inputs'). prop ('readonly', true);
Samir Rahimy

1

Nad formularzem dodajesz niewidoczną warstwę html. Na przykład

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

i styl:

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

Oczywiście użytkownik może ukryć tę warstwę w przeglądarce internetowej.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.