Як я можу зробити всю форму HTML "лише для читання"?


155

У мене дві сторінки з формами HTML. Перша сторінка має форму подання, а друга - форма підтвердження. Перша форма пропонує вибір багатьох елементів керування, а на другій сторінці знову відображаються дані форми подання із повідомленням про підтвердження. У цій другій формі всі поля повинні бути статичними.

З того, що я бачу, деякі елементи форми можуть бути readonlyі всі можуть бути disabled, різниця полягає в тому, що ви все ще можете вкласти в поле для читання.

Замість того, щоб робити це поле за полем, чи є можливість позначити всю форму як лише для читання / відключення / статичної, щоб користувач не міг змінити жодне з елементів керування?

Відповіді:


309

Оберніть поля введення та інші речі в а <fieldset>та надайте йому disabled="disabled"атрибут.

Приклад ( 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
просте і найсмачне рішення для мене. Дякую
демонстрація

2
Найкраще рішення для клієнта :) +1
Sisir

1
Досить просто, це найкраще рішення на стороні клієнта поки що.
brunocoelho

Примітка. Це має побічний ефект - зробити "форми форми, які є [набором полів] нащадками, за винятком нащадків його першого необов'язкового елемента <legend> ... [не] отримувати будь-які події перегляду, наприклад, клацання миші або пов'язані з фокусом "( developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset ). Тож будь-які слухачі подій js, яких ви могли визначити нащадках, можуть не працювати.
Ерік Фрізе

2
@EricFreese Тільки у відключеному стані, що вам потрібно у 99% випадків.
Гонза Кальфус

11

Не всі елементи форми можна встановити readonly, наприклад:

  • прапорці
  • коробки радіо
  • завантаження файлу
  • ... докладніше ..

Тоді розумним рішенням буде встановити disabledатрибути всіх елементів форми true, оскільки ОП не заявляє, що конкретна "заблокована" форма повинна бути надіслана серверу (що disabledатрибут не дозволяє).

Інше рішення, представлене в демонстраційному описі нижче, полягає в тому, щоб розмістити шар поверх formелемента, який запобіжить будь-яку взаємодію з усіма елементами всередині formелемента, оскільки цей шар встановлений з більшим z-indexзначенням:

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
Зверніть увагу, що рішення CSS є неповним, оскільки це не заважає навігації по клавіатурі.
Tanriol

7

Ви можете використовувати цю функцію для відключення форми:

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

Дивіться робочу демонстрацію тут

Зауважте, що він використовує jQuery.


+1 Дякую, але я не можу використовувати рішення на стороні клієнта, дивіться оновлене запитання (вибачте, мій поганий)
Mawg каже, що відновіть Моніку

6

На сторінці підтвердження не ставте вміст у редаговані елементи керування, просто запишіть їх на сторінку.


1
Це дійсно найбезпечніший підхід. Не пред'являйте користувачеві непридатну форму, інакше ви станете запитанням у питанні "Найменшого здивування".
kibibu

1
як? Як я можу відобразити прапорець та його стан перевірки / неперевірену групу або радіогрупу із вибраним елементом тощо?
Мауг каже, що повернемо Моніку

1
@Mawg, можливо, це буде можливість просто перерахувати "вибрані" елементи, без прапорців. Як і у підтвердженні замовлення на піцу: просто перерахуйте всі вибрані вами інгредієнти.
marc82ch

У цьому випадку ні, але дякую за гарний куточок бокового мислення, який може допомогти іншим.
Мауг каже, що повернемо Моніку

4

Я не маю вбудованого способу, який я знаю для цього, тому вам потрібно буде придумати спеціальне рішення залежно від того, наскільки складна ваша форма. Ви повинні прочитати цю публікацію:

Перетворити HTML-форми в режим лише для читання ( оновлення : непрацююче посилання, заархівоване посилання )

EDIT: На основі оновлення, чому ви так переживаєте, щоб це було лише для читання? Ви можете це зробити за допомогою клієнта, але якщо ні, вам доведеться додати потрібний тег до кожного елемента управління або перетворити дані та відобразити їх у вигляді необробленого тексту без елементів керування. Якщо ви намагаєтеся зробити його лише для читання, щоб наступне повідомлення було немодифікованим, тоді у вас є проблема, тому що кожен може возитися з публікацією, щоб створити все, що хоче, тому коли ви насправді отримаєте дані, то краще перевірте їх ще раз, щоб переконатися, що він дійсний.


+1 Дякую, але я не можу використовувати рішення на стороні клієнта, дивіться оновлене запитання (вибачте, мій поганий)
Mawg каже, що відновити Моніку

"Виходячи з вашого оновлення, чому ви так переживаєте, щоб воно читало лише це? Ви можете це зробити за допомогою клієнта" Вибачте, але 1) Я не можу це зробити на стороні клієнта (не на мій вибір) та 2), якщо це виглядає для користувача, як він змінює речі, які можуть його заплутати.
Мауг каже, що повернемо Моніку

@mawg добре, якщо це виключно для візуальних зображень, то єдине, що я можу порекомендувати, - це замінити всі елементи управління в рядку їх текстовим еквівалентом або додати властивості readonly до елементів керування. Срібної кулі немає, і я розумію, що це те, що ти шукаєш. Чи можете ви опублікувати фрагмент коду, який ви можете змінити? Це допоможе просто отримати основу для того, з чим ви працюєте.
Келсі

+1 спасибі за пропозицію. Я ніколи не помічав цього раніше, але, мабуть, я заповнив 100 чи 1000 тисяч, якщо форми та невиразно запам’ятовували лише їхню версію, а не лише текст. Можливо, я повинен заповнити ще кілька і поспостерігати :-)
Мауг каже, що повернути Моніку

3
Сюрприз ... Через 6 років посилання більше не працює.
mwallisch

3

Існує не повністю сумісний офіційний HTML спосіб зробити це, але трохи JavaScript може пройти довгий шлях. Ще одна проблема, з якою ви зіткнетеся, полягає в тому, що відключені поля не відображаються в даних POST


4
Якщо ви вже перевірили дані, то все одно потрібно зберегти їх на стороні сервера. Відправлення клієнта туди-сюди - це велика дірка безпеки. Навіть якщо ви використовуєте css, js або html для заморожування полів, ви можете редагувати їх за допомогою firebug або вручну змінивши наступний запит HTTP
Michael Clerx

+1 Дякую, але я не можу використовувати рішення на стороні клієнта, дивіться оновлене запитання (вибачте, мій поганий)
Mawg каже, що відновити Моніку

3

Це ідеальне рішення для відключення всіх входів , текстових областей , вибору та кнопок у визначеному елементі.

Для jQuery 1.6 і вище :

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

Або

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

jQuery 1.5 і нижче :

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

І

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

2

Ще один простий спосіб, який підтримують усі браузери:

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

Але майте на увазі, що вкладка все ще працює при такому підході, і елементами з фокусом все ще може управляти користувач.


1

Пронумеруйте всі ідентифікатори форми та запустіть цикл for JS.

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

+1 Дякую, але я не можу використовувати рішення на стороні клієнта, дивіться оновлене запитання (вибачте, мій поганий)
Mawg каже, що відновити Моніку

1

Я вважаю за краще використовувати jQuery:

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

find () піде набагато глибше до nth вкладеної дитини, ніж діти (), яка шукає лише безпосередніх дітей.


1
Дякую, я підтримаю вас за спробу, оскільки ви новачок. Але зауважте, що я чітко попросив рішення лише для сервера. У той час я кодував лише PHP і ще не JS. Дружній натяк на прочитання питання, оскільки деякі можуть насправді порушити вас за це :-( Привітання на борт :-)
Мауг каже, що поверніть Моніку

1

Найпростіший спосіб

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

це правда, але це лише ось ось приклад, ви можете змінити свій другий селектор на будь-який інший, наприклад $ ('# yourform .yourclass_for_inputs'). prop ('readonly', true);
Самір Рахімі

1

Ви додаєте html-невидимий шар над формою. Наприклад

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

і стиль:

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

Користувач звичайно може заховати цей шар у веб-браузері.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.