HTML表单只读SELECT标签/输入

Jrg*_*gns 547 html javascript

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

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

模拟标记readonly属性的最佳方法是什么select,仍然可以获取POST数据?

bez*_*max 439

您应该保留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;
});
Run Code Online (Sandbox Code Playgroud)
#formdata_container {
    padding: 10px;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

  • 虽然这是一个显而易见的解决方案,但它作为一种解决方案很糟糕,因为您必须添加另一个输入字段. (20认同)
  • 如果你重新启用选择,你必须然后禁用或删除隐藏的输入(当复制它的值时,如上所述).否则你将获得双倍提交的值 (5认同)
  • 如果我使用多项选择怎么办? (2认同)
  • 具有相同名称的两个元素将仅回发最后一个启用的输入/选择,而不是双重.此外,只有`selected`值被回发而不是整个列表.所以,你的`hidden`位于你的`select`之前,并保持所选的值.如果select为"readonly"禁用,则post back将仅包含隐藏输入的值.如果启用了选择,则可见选定选项将"覆盖/替换"隐藏值,这是将返回的值. (2认同)

vim*_*083 171

我们也可以用它

禁用除所选选项以外的所有选项

<select>
    <option disabled>1</option>
    <option selected>2</option>
    <option disabled>3</option>
</select>
Run Code Online (Sandbox Code Playgroud)

这样下拉列表仍然有效(并提交其值),但用户无法选择其他值.

演示

  • 适用于单值SELECT标签!但是不适用于<select multiple>,它仍然允许用户取消选择某些选定的选项,从而更改值. (8认同)
  • 动态选项的好选择 (5认同)
  • 这是一个很好的解决方案。我要补充一点,您可以使用jQuery这样轻松地实现它:`$(“#yourSelectId option:not(:selected))。attr(” disabled“,” disabled“)` (4认同)
  • [浏览器支持](https://www.w3schools.com/TagS/att_option_disabled.asp)`option`标签的`disabled`属性 (2认同)
  • $('#yourSelectId 选项:not(:selected)').attr('已禁用', '已禁用') (2认同)

kem*_*002 102

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

编辑:即,通常禁用select标签(使用disabled属性),然后在提交表单之前自动重新启用它:

jQuery示例:

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

$('#yourForm').on('submit', function() {
    $('input, select').prop('disabled', false);
});
Run Code Online (Sandbox Code Playgroud)

  • 使用.prop('disabled',true/false)来设置disabled属性.该属性不会更改实际状态. (4认同)
  • 这比接受的答案更清晰。如果您不想再禁用元素并且没有额外的输入标签,则更容易撤消逻辑。 (2认同)

Yaj*_*aje 47

另一种对元素执行readOnly属性的方法select是使用css

你可以这样做:

$('#selection').css('pointer-events','none');
Run Code Online (Sandbox Code Playgroud)

DEMO

  • 好的解决方案 但您仍然可以使用键盘更改值. (7认同)
  • `pointer-events: none` 阻止鼠标光标获得焦点。为了防止键盘获得焦点,您可以通过在所有焦点事件发生时立即模糊来补充它: `$('select').css('pointer-events', 'none').on('focus', function () {$(this).blur();});` (5认同)
  • 防止元素通过键盘导航获得焦点的方法是使用值为“-1”的“tabIndex”属性。 (4认同)
  • 是的,这真是太棒了。要使用键盘更改值,您必须按 TAB 键到元素,然后它就会被选中。如果您将背景颜色设置为灰色或禁用,您还会在视觉上通知用户这是“禁用”,而实际上并未禁用。没有人支持 IE 了,所以谁在乎。如果你想阻止,你也可以设置一个 keydown 阻止默认值。 (2认同)

Gra*_*ner 39

<select id="countries" onfocus="this.defaultIndex=this.selectedIndex;" onchange="this.selectedIndex=this.defaultIndex;">
<option value="1">Country1</option>
<option value="2">Country2</option>
<option value="3">Country3</option>
<option value="4">Country4</option>
<option value="5">Country5</option>
<option value="6">Country6</option>
<option value="7" selected="selected">Country7</option>
<option value="8">Country8</option>
<option value="9">Country9</option>
</select>
Run Code Online (Sandbox Code Playgroud)

在IE 6,7和8b2,Firefox 2和3,Opera 9.62,适用于Windows和Google Chrome的Safari 3.2.1中进行了测试和工作.

  • 这样做的问题是下拉列表就好像它不是只读的一样.用户会认为这个东西不起作用...... (15认同)
  • 我遇到了类似的问题并解决了它只显示所选的选项.不需要JS,减少对用户的混淆......`<select id ="countries"> <option value ="7"selected ="selected"> Country7 </ option> </ select>` (11认同)
  • 这对用户来说很困惑,因为他们仍然可以选择一个选项,但是当他们选择它时,列表会更改回先前选择的值.禁用列表以防止用户选择任何内容会更加直观. (8认同)

小智 36

简单的jQuery解决方案

如果你的选择有readonly类,请使用此选项

jQuery('select.readonly option:not(:selected)').attr('disabled',true);
Run Code Online (Sandbox Code Playgroud)

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

$('select[readonly="readonly"] option:not(:selected)').attr('disabled',true);
Run Code Online (Sandbox Code Playgroud)

  • 请稍微解释一下你的代码.我们是否必须在select元素中添加一个'readonly'类?我们何时必须调用此代码:仅在document.ready中或每次启用/禁用选择时?你的代码noscript安全吗? (7认同)
  • 我喜欢这个解决方案。我会将选择器更改为“select[readonly]”,以便您只需将 readonly 属性添加到元素中 - 这样您就不必以与任何其他类型不同的方式对待选择。然后 JavaScript 会逐渐增强效果。请记住,此解决方案(以及大多数其他解决方案)仅帮助用户代理提供最佳用户体验 - 它实际上并不强制执行任何操作(如果需要,必须在服务器端完成)。 (2认同)

d.r*_*aev 20

简单的CSS解决方案

select[readonly]{
    background: #eee;
    cursor:no-drop;
}

select[readonly] option{
    display:none;
}
Run Code Online (Sandbox Code Playgroud)

这导致选择为灰色,悬停
时选中漂亮的"禁用"光标,选择选项列表为"空",因此您无法更改其值.

  • 一个小改进:`select[readonly] option:not([selected]) {display:none;}` 这样它只会禁用未选中的选项,并且仍然在表单中提交选定的值。但这仍然是一个很棒的答案! (3认同)

Nic*_*her 17

[最简单的解决方案]

由于OP特别要求他不想禁用选择元素,因此我使用以下内容来使选择只读

在 HTML 中

<select style="pointer-events: none;" onclick="return false;" onkeydown="return false;" ></select>
Run Code Online (Sandbox Code Playgroud)

就是这样

解释

  • 将pointer-events设置为none会禁用使用鼠标/光标事件编辑“选择元素”
  • 将 onclick 和 onkeydown 函数设置为返回 false 会禁用使用键盘编辑“select-element”

这样您就不必创建任何额外的元素,或者使用 javascript 禁用/重新启用该元素,或者弄乱表单提交逻辑,或者使用任何第三方库。

另外,您可以轻松添加 css 样式,例如将背景颜色设置为灰色或将文本颜色设置为灰色以暗示该元素是只读的。我还没有将其添加到代码中,因为这非常特定于您的网站主题

或者如果你想通过 javascript 来完成

<select style="pointer-events: none;" onclick="return false;" onkeydown="return false;" ></select>
Run Code Online (Sandbox Code Playgroud)

  • 多谢!在所有有效的解决方案中,这是(对我来说)最简单的! (2认同)

epe*_*leg 12

另一个更现代的选项(没有双关语)是禁用所选元素以外的所有选项.

但请注意,这是一个HTML 4.0功能,即6,7,8 beta 1似乎不尊重这一点.

http://www.gtalbot.org/BrowserBugsSection/MSIE7Bugs/OptionDisabledSupport.html


Len*_*rri 11

这是我找到的最佳解决方案:

$("#YourSELECTIdHere option:not(:selected)").prop("disabled", true);
Run Code Online (Sandbox Code Playgroud)

上面的代码在启用所选选项的同时禁用未选中的所有其他选项.这样做所选的选项将使其成为回发后的数据.


小智 10

更简单:将style属性添加到select标签:

style="pointer-events: none;"
Run Code Online (Sandbox Code Playgroud)

  • 它不会工作.用户可以使用键盘更改输入. (2认同)

nro*_*fis 7

我知道它已经太晚了,但可以用简单的CSS完成:

select[readonly] option, select[readonly] optgroup {
    display: none;
}
Run Code Online (Sandbox Code Playgroud)

当选择处于readonly状态时,样式会隐藏所有选项和组,因此用户无法更改其选择.

不需要JavaScript hacks.

  • 2020 年,不可能向下拉列表添加只读属性...很好的解决方法! (2认同)

Joo*_*719 7

聚会有点晚了。但这对我来说似乎完美无缺

select[readonly] {
    pointer-events:none;
}
Run Code Online (Sandbox Code Playgroud)


Gui*_*ira 6

这是最简单,最好的解决方案.您将在select或任何其他attr上设置readolny attr,如数据只读,并执行以下操作

$("select[readonly]").live("focus mousedown mouseup click",function(e){
    e.preventDefault();
    e.stopPropagation();
});
Run Code Online (Sandbox Code Playgroud)


小智 5

当您计划将其设置为只读时设置禁用选项,然后在提交表单之前删除已禁用的属性.

// global variable to store original event/handler for save button
var form_save_button_func = null;

// function to get jQuery object for save button
function get_form_button_by_id(button_id) {
    return jQuery("input[type=button]#"+button_id);
}

// alter value of disabled element
function set_disabled_elem_value(elem_id, value)  {
    jQuery("#"+elem_id).removeAttr("disabled");
    jQuery("#"+elem_id).val(value);
    jQuery("#"+elem_id).attr('disabled','disabled');
}

function set_form_bottom_button_save_custom_code_generic(msg) {
    // save original event/handler that was either declared
    // through javascript or html onclick attribute
    // in a global variable
    form_save_button_func = get_form_button_by_id('BtnSave').prop('onclick'); // jQuery 1.6
    //form_save_button_func = get_form_button_by_id('BtnSave').prop('onclick'); // jQuery 1.7

    // unbind original event/handler (can use any of following statements below)
    get_form_button_by_value('BtnSave').unbind('click');
    get_form_button_by_value('BtnSave').removeAttr('onclick');

    // alternate save code which also calls original event/handler stored in global variable
    get_form_button_by_value('BtnSave').click(function(event){
        event.preventDefault();
        var confirm_result = confirm(msg);
        if (confirm_result) {
            if (jQuery("form.anyForm").find('input[type=text], textarea, select').filter(".disabled-form-elem").length > 0) {
                jQuery("form.anyForm").find('input[type=text], textarea, select').filter(".disabled-form-elem").removeAttr("disabled");
            }

            // disallow further editing of fields once save operation is underway
            // by making them readonly
            // you can also disallow form editing by showing a large transparent
            // div over form such as loading animation with "Saving" message text
            jQuery("form.anyForm").find('input[type=text], textarea, select').attr('ReadOnly','True');

            // now execute original event/handler
            form_save_button_func();
        }
    });
}

$(document).ready(function() {
    // if you want to define save button code in javascript then define it now

    // code below for record update
    set_form_bottom_button_save_custom_code_generic("Do you really want to update this record?");
    // code below for new record
    //set_form_bottom_button_save_custom_code_generic("Do you really want to create this new record?");

    // start disabling elements on form load by also adding a class to identify disabled elements
    jQuery("input[type=text]#phone").addClass('disabled-form-elem').attr('disabled','disabled');
    jQuery("input[type=text]#fax").addClass('disabled-form-elem').attr('disabled','disabled');
    jQuery("select#country").addClass('disabled-form-elem').attr('disabled','disabled');
    jQuery("textarea#address").addClass('disabled-form-elem').attr('disabled','disabled');

    set_disabled_elem_value('phone', '123121231');
    set_disabled_elem_value('fax', '123123123');
    set_disabled_elem_value('country', 'Pakistan');
    set_disabled_elem_value('address', 'address');

}); // end of $(document).ready function
Run Code Online (Sandbox Code Playgroud)


cer*_*nos 5

除了禁用不应该选择的选项之外,我想让它们从列表中消失,但是如果我需要以后仍然可以启用它们:

$("select[readonly]").find("option:not(:selected)").hide().attr("disabled",true);
Run Code Online (Sandbox Code Playgroud)

这将查找具有readonly属性的所有select元素,然后查找未选中的那些选择内的所有选项,然后隐藏它们并禁用它们.

出于性能原因,将jquery查询分成2是很重要的,因为jquery从右到左读取它们,代码如下:

$("select[readonly] option:not(:selected)")
Run Code Online (Sandbox Code Playgroud)

将首先在文档中找到所有未选中的选项,然后使用readonly属性过滤那些在选择内部的选项.


Joa*_*rez 5

如果禁用表单字段,则在提交表单时不会发送此字段。因此,如果您需要一个readonly类似disabled但发送值的方法,请执行以下操作:

在元素的只读属性发生任何更改之后。

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

$('select:not([readonly]) option').removeAttr('disabled');
Run Code Online (Sandbox Code Playgroud)


jBe*_*ger 5

使用 tabindex 的解决方案。适用于选择但也适用于文本输入。

只需使用 .disabled 类。

CSS:

.disabled {
    pointer-events:none; /* No cursor */
    background-color: #eee; /* Gray background */
}
Run Code Online (Sandbox Code Playgroud)

JS:

$(".disabled").attr("tabindex", "-1");
Run Code Online (Sandbox Code Playgroud)

HTML:

<select class="disabled">
    <option value="0">0</option>
</select>

<input type="text" class="disabled" />
Run Code Online (Sandbox Code Playgroud)

编辑:使用 Internet Explorer,您还需要这个 JS:

$(document).on("mousedown", ".disabled", function (e) {
    e.preventDefault();
});
Run Code Online (Sandbox Code Playgroud)