如何将整个HTML表单设为“只读”?


155

我有两个带有HTML表单的页面。第一页有一个提交表单,第二页有一个确认表单。第一种形式提供了许多控件的选择,而第二页再次显示了提交表单中的数据并带有确认消息。在第二种形式上,所有字段都必须是静态的。

从我看到的内容来看,某些表单控件可以是,readonly而所有控件都可以disabled,区别在于您仍然可以跳至只读字段。

除了按字段进行此操作之外,没有其他方法可以将整个表单标记为只读/禁用/静态,从而使用户无法更改任何控件?

Answers:


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 2015年

1
很简单,这是迄今为止最好的客户端解决方案。
brunocoelho

注意:这具有“使表单控件成为[fieldset]后代的副作用,但其第一个可选<legend>元素的后代除外……[不]接收任何浏览事件,例如鼠标单击或与焦点相关的事件。 ”(developer.mozilla.org/zh-CN/docs/Web/HTML/Element/fieldset)。因此,您可能在后代上定义的所有js事件侦听器都可能无法运行。
Eric Freese

2
@EricFreese仅在禁用状态下,这是您在99%的情况下所需的状态。
Honza Kalfus '18年

11

并非所有表单元素都可以设置为readonly,例如:

  • 复选框
  • 收音机盒
  • 上传文件
  • ...更多..

然后,合理的解决方案是将所有表单元素的disabled属性都设置为true,因为OP没有声明应将特定的“锁定”表单发送到服务器(该disabled属性不允许)。

在下面的演示中介绍的另一种解决方案是在form元素的顶部放置一个层,该层将防止与元素内部的所有元素发生任何交互form,因为该层设置为更大的z-index值:

演示:

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


6

在确认页面上,不要将内容放在可编辑控件中,只需将其写入页面即可。


1
这确实是最明智的方法。不要向用户显示无法编辑的表格,否则您最终将成为“最低惊讶”问题中的一个条目。
kibibu

1
怎么样?如何显示复选框及其选中/未选中状态,或带有其选定项目的单选组等?
Mawg说恢复Monica 2010年

1
@Mawg也许是仅列出“选定”项目而没有复选框的选项。就像在披萨订单确认中一样:只列出您选择的所有食材。
marc82ch 2015年

在这种情况下,不是,但是要感谢您的多方面思考,这对其他人可能会有所帮助。
Mawg说恢复Monica

4

据我所知,没有内置的方法可以执行此操作,因此您将需要根据表单的复杂程度提出自定义解决方案。您应该阅读这篇文章:

将HTML表单转换为只读形式更新帖子断开链接,归档链接

编辑:根据您的更新,为什么您如此担心它是只读的?您可以通过客户端进行操作,但是如果没有,则必须将所需的标签添加到每个控件中,或者转换数据并将其显示为没有控件的原始文本。如果您试图将其设置为只读,以便下一个帖子不会被修改,那么您就会遇到问题,因为任何人都可以弄乱该帖子以产生他们想要的东西,因此当您实际上最终收到数据时,最好检查一下它再次确保它是有效的。


+1谢谢,但是我不能使用客户端解决方案,请参阅更新的问题(对不起,我的错)
Mawg说恢复Monica 2010年

“抱歉,基于您的更新,您为什么要担心它只能只读?您可以通过客户端进行操作”,对不起,但是1)我不能在客户端(不是我的选择)进行操作,以及2)给用户,就像他正在改变可能会使他困惑的事情一样。
Mawg说恢复Monica 2010年

@mawg很好,如果它仅用于视觉效果,那么我唯一推荐的就是用与其等价的文本替换所有内联控件,或者向控件添加readonly属性。没有灵丹妙药,我能感觉到您正在寻找什么。您可以发布允许修改的代码片段吗?只是为您使用的基础奠定了基础。
凯尔西(Kelsey)2010年

+1感谢您的建议。我以前从未真正注意到过,但是如果表格和我隐约记得它们的只读版本,而不仅仅是文本,那么我必须填写100或1,000。也许我应该再填写一些并观察:-)
Mawg说恢复Monica 2010年

3
惊奇... 6年后,该链接不再起作用。
mwallisch

3

没有完全兼容的官方HTML方法可以执行此操作,但是少量的javascript可以发挥很大的作用。您将遇到的另一个问题是,禁用字段不会显示在POST数据中


4
如果您已经验证了数据,则无论如何都需要将其保存在服务器端。来回发送给客户端是一个很大的安全漏洞。即使您使用css,js或html冻结字段,也可以使用Firebug编辑“ m”或手动更改下一个HTTP请求
Michael Clerx 2010年

+1谢谢,但是我不能使用客户端解决方案,请参阅更新的问题(对不起,我的错)
Mawg说恢复Monica 2010年

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

将所有表单ID编号并在JS中运行for循环。

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

+1谢谢,但是我不能使用客户端解决方案,请参阅更新的问题(对不起,我的错)
Mawg说恢复Monica 2010年

1

我宁愿使用jQuery:

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

与第一个嵌套子级的children()相比,到第n个嵌套子级为止,find()会更深入。


1
谢谢,由于您是新手,我会支持您的尝试。但是请注意,我明确要求提供仅服务器端的解决方案。那时我只编码PHP,还没有编码JS。一个友好的提示来阅读这个问题,因为有些人可能会为此而
深深地投票


1

您在表单上添加html不可见层。例如

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

和风格:

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

用户当然可以在Web浏览器中隐藏该层。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.