HTML 表单只读 SELECT 标签/输入

IT技术 javascript html
2021-01-26 03:13:40

根据 HTML 规范,selectHTML 中标签没有readonly属性,只有disabled属性。因此,如果您想阻止用户更改下拉列表,则必须使用disabled.

唯一的问题是禁用的 HTML 表单输入不会包含在 POST / GET 数据中。

模拟标签readonly属性select并仍然获取 POST 数据的最佳方法是什么

6个回答

您应该保留该select元素,disabled但还要添加另一个input具有相同名称和值的隐藏元素

如果您重新启用 SELECT,您应该将其值复制到 onchange 事件中的隐藏输入并禁用(或删除)隐藏输入。

这是一个演示:

$('#mainform').submit(function() {
    $('#formdata_container').show();
    $('#formdata').html($(this).serialize());
    return false;
});

$('#enableselect').click(function() {
    $('#mainform input[name=animal]')
        .attr("disabled", true);
    
    $('#animal-select')
        .attr('disabled', false)
    	.attr('name', 'animal');
    
    $('#enableselect').hide();
    return false;
});
#formdata_container {
    padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
    <form id="mainform">
        <select id="animal-select" disabled="true">
            <option value="cat" selected>Cat</option>
            <option value="dog">Dog</option>
            <option value="hamster">Hamster</option>
        </select>
        <input type="hidden" name="animal" value="cat"/>
        <button id="enableselect">Enable</button>
        
        <select name="color">
            <option value="blue" selected>Blue</option>
            <option value="green">Green</option>
            <option value="red">Red</option>
        </select>

        <input type="submit"/>
    </form>
</div>

<div id="formdata_container" style="display:none">
    <div>Submitted data:</div>
    <div id="formdata">
    </div>
</div>

虽然这是显而易见的解决方案,但它作为一个解决方案很糟糕,因为您必须添加另一个输入字段。
2021-03-15 03:13:40
@max 啊!。好的,这也有效。自从你说隐藏输入应该与选择具有名称的“相同名称”以来,我一直假设。
2021-03-17 03:13:40
如果我使用多选怎么办?
2021-03-18 03:13:40
如果您重新启用选择,您当然还必须禁用或删除隐藏的输入(在按照描述复制其值之后)。否则你会得到双倍提交的值
2021-04-01 03:13:40
具有相同名称的两个元素只会回发最后启用的输入/选择,而不是双重。此外,只有selected值被回发,而不是整个列表。因此,您的位置hidden在您之前select并持有选定的值。如果选择被禁用为“只读”,则回发将仅包含隐藏输入的值。如果启用了选择,可见的选定选项将“覆盖/替换”隐藏值,这就是将被回发的值。
2021-04-04 03:13:40

我们还可以禁用除选定选项之外的所有选项。

这样下拉菜单仍然有效(并提交其值),但用户无法选择另一个值。

演示

<select>
    <option disabled>1</option>
    <option selected>2</option>
    <option disabled>3</option>
</select>

动态选项的好选择
2021-03-16 03:13:40
这是一个很好的解决方案。我要补充的是,您可以像这样使用 jQuery 轻松实现它: $("#yourSelectId option:not(:selected)).attr("disabled", "disabled")
2021-03-19 03:13:40
浏览器支持option标签的disabled属性
2021-03-31 03:13:40
$('#yourSelectId option:not(:selected)').attr('disabled', 'disabled')
2021-04-01 03:13:40
非常适合单值 SELECT 标签!但不适用于 <select multiple>,它仍然允许用户取消选择某些选定的选项,从而更改值。
2021-04-09 03:13:40

您可以在提交时重新启用选择对象。

编辑:即,通常禁用选择标记(具有禁用属性),然后在提交表单之前自动重新启用它:

jQuery 示例:

  • 要禁用它:

    $('#yourSelect').prop('disabled', true);
    
  • 在提交之前重新启用它以便包含 GET / POST 数据:

    $('#yourForm').on('submit', function() {
        $('#yourSelect').prop('disabled', false);
    });
    

此外,您可以重新启用每个禁用的输入或选择:

$('#yourForm').on('submit', function() {
    $('input, select').prop('disabled', false);
});
使用 .prop('disabled',true/false) 设置禁用属性。该属性不会改变实际状态。
2021-03-16 03:13:40
我认为这个解决方案比@bezmax解决方案更聪明因为如果我们添加隐藏输入,我们必须考虑在任何时候每个输入(同名)中只有一个是启用的。否则,如果两个输入都被启用,在服务器端,程序将采用可能导致异常的输入数组(例如,如果我们没有处理这种情况,我们期望一个字符串并使用 'Request.Form[FieldName] ' 命令)
2021-03-16 03:13:40
这比接受的答案更清晰。如果您不想再禁用元素并且没有额外的输入标签,则更容易撤消逻辑。
2021-03-21 03:13:40
@Kevin,工作> 90% 的情况。另外,你必须有jquery在你的腰带......呃。
2021-03-27 03:13:40
你救了我的一天!我正在寻找与此类似的解决方案。我的 Spring Boot 应用程序中总是出现 NullPointerException。非常感谢你!:)
2021-03-27 03:13:40

readOnlyselect元素添加属性的另一种方法是使用css

你可以这样做:

$('#selection').css('pointer-events','none');

演示

是的,这真是太棒了。要使用键盘更改值,您必须按 TAB 键到元素,然后它就会被选中。如果您将背景颜色设置为灰色或禁用,您还会在视觉上通知用户这是“禁用”,而实际上并未禁用。没有人支持 IE 了,所以谁在乎。如果你想阻止,你也可以设置一个 keydown 阻止默认值。
2021-03-17 03:13:40
pointer-events: none防止焦点从鼠标光标。为了防止键盘获得焦点,您可以通过在所有焦点事件上立即模糊来补充它:$('select').css('pointer-events', 'none').on('focus', function () {$(this).blur();});
2021-03-30 03:13:40
很不正统!!如果选择需要阻止页面渲染,... .on('mouseover', function(){ ... });
2021-04-01 03:13:40
不错的解决方案。但是您仍然可以使用键盘更改该值。
2021-04-02 03:13:40

简单的jQuery解决方案

如果您的选择有readonly课程,请使用它

jQuery('select.readonly option:not(:selected)').attr('disabled',true);

或者如果您的选择具有readonly="readonly"属性

$('select[readonly="readonly"] option:not(:selected)').attr('disabled',true);
我喜欢这个解决方案。我会将选择器更改为 ,select[readonly]以便您只需将 readonly 属性添加到元素 - 这样您就不必以不同于任何其他类型的方式对待选择。然后 javascript 会逐步增强效果。请记住,此解决方案(以及大多数其他解决方案)仅帮助用户代理提供最佳用户体验 - 它实际上并未强制执行任何操作(如果需要,必须在服务器端完成)。
2021-03-13 03:13:40
它禁用“只读”类的选择框以外的选项。如果您手头有 select 元素,您可以编写:$select.find('option').not(':selected').attr('disabled', 'disabled');
2021-03-14 03:13:40
请稍微解释一下您的代码。我们是否必须向 select 元素添加“只读”类?我们什么时候必须调用此代码:仅在 document.ready 中或每次启用/禁用选择时?你的代码 noscript 安全吗?
2021-03-27 03:13:40
不明白这些。
2021-03-30 03:13:40
$(document).ready(function(){$('select option:not(:selected)').attr('disabled',true);});在单选上工作得很好。不需要“只读”类。多选的问题在于,如果已经选择了多个选项并因此未禁用,并且用户选择了未禁用的选项之一,则其他先前选择的选项将变为未选择状态。
2021-04-10 03:13:40