Как я могу сделать всю форму HTML «только для чтения»?


155

У меня есть две страницы с формами HTML. Первая страница имеет форму отправки, а вторая страница имеет форму подтверждения. Первая форма предлагает выбор из множества элементов управления, а на второй странице снова отображаются данные из формы отправки с подтверждением. На этой второй форме все поля должны быть статическими.

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

Вместо того, чтобы делать это поле за полем, есть ли способ пометить всю форму как readonly / disabled / static так, чтобы пользователь не мог изменить ни один из элементов управления?

Ответы:


310

Оберните поля ввода и другие данные в a <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

Примечание: у этого есть побочный эффект создания "элементов управления формы, которые являются потомками [fieldsets], кроме потомков его первого необязательного элемента <legend> ... [not], получают любые события просмотра, такие как щелчки мыши или связанные с фокусом "( developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset ). Поэтому любые прослушиватели событий js, которые вы, возможно, определили для потомков, могут не работать.
Эрик Фриз

2
@EricFreese Только в отключенном состоянии, что вам нужно в 99% случаев.
Хонза Кальфус

11

Не все элементы формы могут быть установлены readonly, например:

  • флажки
  • радио коробки
  • файл загружен
  • ...Больше..

Тогда разумным решением было бы установить disabledатрибуты всех элементов формы true, поскольку OP не указывал, что конкретная «заблокированная» форма должна быть отправлена ​​на сервер (что 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 неполное, так как оно не мешает навигации с помощью клавиатуры.
Танриоль

7

Вы можете использовать эту функцию для отключения формы:

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

Смотрите рабочую демо здесь

Обратите внимание, что он использует jQuery.


+1 Спасибо, но я не могу использовать решения на стороне клиента, см. Обновленный вопрос (извините, мой плохой)
Моуг говорит восстановить Monica

6

На странице подтверждения не помещайте содержимое в редактируемые элементы управления, просто напишите их на странице.


1
Это действительно самый разумный подход. Не показывайте пользователю не редактируемую форму, иначе вы окажетесь в вопросе «Наименьшее изумление».
kibibu

1
как? Как я могу отобразить флажок и его состояние «проверено / не отмечено», или группу радиосвязи с выбранным элементом и т. Д.?
Mawg говорит восстановить Monica

1
@Mawg, возможно, можно было бы просто перечислить «выбранные» элементы без флажков. Как и в подтверждении заказа пиццы: просто перечислите все ингредиенты, которые вы выбрали.
марта

В этом случае нет, но спасибо за хороший пример бокового мышления, который может помочь другим.
Mawg говорит восстановить Монику

4

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

Конвертировать HTML-формы только для чтения ( Обновление : неработающая ссылка, заархивированная ссылка )

РЕДАКТИРОВАТЬ: Основываясь на вашем обновлении, почему вы так беспокоитесь о том, что он только для чтения? Вы можете сделать это через клиентскую часть, но если это не так, вам придется добавить требуемый тег в каждый элемент управления или преобразовать данные и отобразить их в виде необработанного текста без элементов управления. Если вы пытаетесь сделать его доступным только для чтения, чтобы следующий пост не был изменен, то у вас есть проблема, потому что любой может связываться с постом, чтобы произвести то, что он хочет, поэтому, когда вы на самом деле наконец-то получите данные, вам лучше их проверить. еще раз, чтобы убедиться, что это действительно.


+1 Спасибо, но я не могу использовать решения на стороне клиента, см. Обновленный вопрос (извините, мой плохой)
Моуг говорит восстановить Monica

«Исходя из вашего обновления, почему вы так беспокоитесь о том, что он доступен только для чтения? Вы можете сделать это через клиентскую часть» Извините, но 1) я не могу сделать это на стороне клиента (не мой выбор) и 2) если он выглядит пользователю, как будто он меняет вещи, которые могут его запутать.
Mawg говорит восстановить Monica

@mawg хорошо, если это только для визуалов, единственное, что я могу порекомендовать, это заменить все встроенные элементы управления на их текстовый эквивалент или добавить свойство readonly к элементам управления. Там нет серебряной пули, и я чувствую, что это то, что вы ищете. Можете ли вы опубликовать фрагмент кода, который вам разрешено изменять? Это помогло бы просто получить основу для того, с чем вы работаете.
Келси

+1 спасибо за предложение. Я никогда не замечал раньше, но я должен был заполнить 100 или 1000, если формы и смутно помнить их только для чтения, а не просто текст. Возможно я должен заполнить еще несколько и наблюдать :-)
Mawg говорит восстановить Monica

3
Сюрприз ... Через 6 лет ссылка больше не работает.
mwallisch

3

Не существует полностью совместимого официального HTML-способа сделать это, но небольшой JavaScript может иметь большое значение. Другая проблема, с которой вы столкнетесь, заключается в том, что отключенные поля не отображаются в данных POST.


4
Если вы уже проверили данные, вам все равно нужно сохранить их на стороне сервера. Отправлять его туда и обратно клиенту - большая дыра в безопасности. Даже если вы используете css, js или html, чтобы заморозить поля, вы можете отредактировать их с помощью firebug или вручную изменив следующий HTTP-запрос
Michael Clerx

+1 Спасибо, но я не могу использовать решения на стороне клиента, см. Обновленный вопрос (извините, мой плохой)
Моуг говорит восстановить Monica

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 Спасибо, но я не могу использовать решения на стороне клиента, см. Обновленный вопрос (извините, мой плохой)
Моуг говорит восстановить Monica

1

Я бы лучше использовал jQuery:

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

find () будет намного глубже до n-го вложенного потомка, чем children (), который ищет только непосредственных потомков.


1
Спасибо, я буду признателен вам за попытку, так как вы новичок. НО, пожалуйста, обратите внимание, что я четко попросил решение только на стороне сервера. В то время я только кодировал PHP, а не JS. Дружеский намек на чтение вопроса, так как некоторые могут на самом деле понизить вас за это :-( Добро пожаловать на борт :-)
Mawg говорит восстановить Монику

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.