Bagaimana saya bisa membuat seluruh formulir HTML "hanya baca"?

155

Saya punya dua halaman dengan formulir HTML. Halaman pertama memiliki formulir pengiriman, dan halaman kedua memiliki formulir penerimaan. Formulir pertama menawarkan pilihan banyak kontrol, sementara halaman kedua menampilkan data dari formulir pengiriman lagi dengan pesan konfirmasi. Pada formulir kedua ini semua bidang harus statis.

Dari apa yang saya lihat, beberapa kontrol formulir bisa readonlydan semua bisa disabled, bedanya adalah Anda masih bisa tab ke bidang hanya baca.

Daripada melakukan bidang ini demi bidang, adakah cara untuk menandai seluruh formulir sebagai hanya-baca / dinonaktifkan / statis sehingga pengguna tidak dapat mengubah kontrol apa pun?

Mawg berkata mengembalikan Monica
sumber

Jawaban:

310

Bungkus bidang input dan hal-hal lain ke dalam <fieldset>dan berikan disabled="disabled"atribut.

Contoh ( 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>

Klemen Tušar
sumber
2
solusi sederhana dan serakah bagi saya. Terima kasih
demo
2
Solusi terbaik untuk sisi klien :) +1
Sisir
1
Cukup sederhana, ini adalah solusi sisi klien terbaik sejauh ini.
brunocoelho
Catatan: Ini memiliki efek samping dari membuat "kontrol formulir yang merupakan turunan [fieldset], kecuali turunan dari elemen <legend> opsional pertama ... [tidak] menerima acara penelusuran apa pun, seperti klik mouse atau yang terkait dengan fokus "( developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset ). Jadi, setiap pendengar acara yang mungkin Anda tetapkan untuk keturunan mungkin tidak berfungsi.
Eric Freese
2
@EricFreese Hanya dalam keadaan dinonaktifkan, itulah yang Anda inginkan dalam 99% kasus.
Honza Kalfus
11

Tidak semua elemen formulir dapat disetel ke readonly, misalnya:

  • kotak centang
  • kotak radio
  • unggah file
  • ...lebih..

Maka solusi yang masuk akal adalah mengatur disabledatribut semua elemen form true, karena OP tidak menyatakan bahwa form "terkunci" spesifik harus dikirim ke server (yang disabledtidak diizinkan oleh atribut).

Solusi lain, yang disajikan dalam demo di bawah ini, adalah menempatkan lapisan di atas formelemen yang akan mencegah interaksi dengan semua elemen di dalam formelemen, karena lapisan itu diatur dengan z-indexnilai yang lebih besar:

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>

vsync
sumber
1
Harap dicatat bahwa solusi CSS tidak lengkap karena tidak mencegah navigasi keyboard.
Tanriol
7

Anda dapat menggunakan fungsi ini untuk menonaktifkan formulir:

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

Lihat demo yang berfungsi di sini

Perhatikan bahwa ia menggunakan jQuery.

Sarfraz
sumber
+1 Terima kasih, tapi saya tidak bisa menggunakan solusi sisi klien, lihat pertanyaan terbaru (maaf, salah saya)
Mawg mengatakan mengembalikan Monica
6

Di halaman konfirmasi, jangan meletakkan konten di kontrol yang dapat diedit, cukup tuliskan ke halaman.

Doobi
sumber
1
Ini benar-benar pendekatan yang paling sehat. Jangan menyajikan formulir yang tidak dapat diedit kepada pengguna, atau Anda akan berakhir dengan entri dalam pertanyaan "Terkejut".
kibibu
1
bagaimana? Bagaimana saya bisa menampilkan kotak centang dan kondisinya cek / tidak dicentang, atau grup radio dengan item yang dipilih, dll?
Mawg mengatakan mengembalikan Monica
1
@ Mawg mungkin itu akan menjadi opsi untuk hanya daftar item yang 'dipilih', tanpa kotak centang. Seperti pada konfirmasi pesanan pizza: cukup daftarkan semua bahan yang Anda pilih.
marc82ch
Dalam hal ini tidak, tapi terima kasih atas pemikiran lateral yang bagus yang mungkin bisa membantu orang lain.
Mawg mengatakan mengembalikan Monica
4

Tidak ada cara bawaan yang saya tahu untuk melakukan ini sehingga Anda perlu membuat solusi khusus tergantung pada seberapa rumit formulir Anda. Anda harus membaca posting ini:

Konversikan formulir HTML menjadi hanya-baca ( Perbarui : tautan kiriman rusak, tautan arsip )

EDIT: Berdasarkan pada pembaruan Anda, mengapa Anda begitu khawatir karena hanya dapat dibaca? Anda dapat melakukannya melalui sisi klien tetapi jika tidak, Anda harus menambahkan tag yang diperlukan untuk setiap kontrol atau mengonversi data dan menampilkannya sebagai teks mentah tanpa kontrol. Jika Anda mencoba membuatnya hanya-baca sehingga posting berikutnya tidak akan dimodifikasi maka Anda memiliki masalah karena siapa pun dapat mengacaukan posting tersebut untuk menghasilkan apa pun yang mereka inginkan sehingga ketika Anda melakukannya pada akhirnya menerima data yang lebih baik Anda memeriksanya. lagi untuk memastikan itu valid.

Kelsey
sumber
+1 Terima kasih, tapi saya tidak bisa menggunakan solusi sisi klien, lihat pertanyaan terbaru (maaf, salah saya)
Mawg mengatakan mengembalikan Monica
"Berdasarkan pembaruan Anda, mengapa Anda begitu khawatir jika hanya membaca saja? Anda dapat melakukannya melalui sisi klien" Maaf, tetapi 1) Saya tidak dapat melakukannya dari sisi klien (bukan pilihan saya) dan 2) jika terlihat kepada pengguna seperti dia mengubah hal-hal yang mungkin membingungkannya.
Mawg mengatakan mengembalikan Monica
@mawg baik jika itu murni untuk visual, satu-satunya hal yang saya dapat merekomendasikan adalah mengganti semua kontrol sejalan dengan teks yang setara atau menambahkan properti readonly ke kontrol. Tidak ada peluru perak dan saya merasa itulah yang Anda cari. Bisakah Anda memposting potongan kode yang Anda boleh modifikasi? Akan membantu jika hanya mendapatkan dasar untuk apa yang sedang Anda kerjakan.
Kelsey
+1 terima kasih atas sarannya. Saya tidak pernah benar-benar memperhatikan sebelumnya, tetapi saya harus mengisi 100 atau 1.000 jika bentuk & samar-samar ingat versi hanya baca dari mereka, bukan hanya teks. Mungkin saya harus mengisi beberapa lagi & amati :-)
Mawg mengatakan mengembalikan Monica
3
Kejutan ... 6 tahun kemudian tautannya tidak berfungsi lagi.
mwallisch
3

Tidak ada cara HTML resmi yang sepenuhnya patuh untuk melakukannya, tetapi sedikit javascript bisa bermanfaat. Masalah lain yang akan Anda hadapi adalah bahwa bidang yang dinonaktifkan tidak muncul di data POST

Michael Clerx
sumber
4
Jika Anda sudah memvalidasi data, Anda harus menyimpannya di sisi server. Mengirimnya bolak-balik ke klien adalah lubang keamanan yang besar. Bahkan jika Anda menggunakan css, js, atau html untuk membekukan bidang, Anda dapat mengeditnya dengan firebug atau dengan secara manual mengubah permintaan HTTP berikutnya
Michael Clerx
+1 Terima kasih, tapi saya tidak bisa menggunakan solusi sisi klien, lihat pertanyaan terbaru (maaf, salah saya)
Mawg mengatakan mengembalikan Monica
3

Ini adalah solusi ideal untuk menonaktifkan semua input , textareas , select dan tombol dalam elemen tertentu.

Untuk jQuery 1.6 ke atas :

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

Atau

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

jQuery 1.5 dan di bawah :

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

Dan

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

Cara sederhana lain yang didukung oleh semua browser adalah:

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

Namun perlu diperhatikan, bahwa tabbing masih bekerja dengan pendekatan ini dan elemen-elemen dengan fokus masih dapat dimanipulasi oleh pengguna.

M. Neuweiler
sumber
1

Buat semua id formulir diberi nomor dan jalankan perulangan for di JS.

 for(id = 0; id<NUM_ELEMENTS; id++)
   document.getElementById(id).disabled = false; 
TTT
sumber
+1 Terima kasih, tapi saya tidak bisa menggunakan solusi sisi klien, lihat pertanyaan terbaru (maaf, salah saya)
Mawg mengatakan mengembalikan Monica
1

Saya lebih suka menggunakan jQuery:

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

find () akan lebih dalam hingga anak yang bersarang daripada anak-anak (), yang mencari anak langsung saja.

pengguna163861
sumber
1
Terima kasih, saya akan mendukung Anda untuk mencoba, karena Anda baru. TAPI, harap dicatat bahwa saya jelas meminta solusi sisi server saja. Saat itu saya hanya kode PHP dan belum JS. Sebuah petunjuk ramah untuk membaca pertanyaan karena beberapa mungkin benar-benar menurunkan Anda untuk ini :-( Selamat datang :-)
Mawg mengatakan mengembalikan Monica
1

Cara termudah

$('#yourform *').prop('readonly', true);
Samir Rahimy
sumber
itu benar, tetapi ini hanya contoh kapak Anda dapat mengubah pemilih kedua Anda ke yang lain misalnya $ ('# formulir Anda .class_for_inputs'). prop ('readonly', true);
Samir Rahimy
1

Anda menambahkan html lapisan tak terlihat di atas formulir. Misalnya

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

dan gaya:

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

Pengguna Ofcourse dapat menyembunyikan lapisan ini di browser web.

Marcin Żurek
sumber