根据 HTML 规范,HTML 中的 select
标记没有 readonly
属性,只有 disabled
属性。因此,如果您想阻止用户更改下拉菜单,您必须使用 disabled
。
唯一的问题是禁用的 HTML 表单输入不会包含在 POST / GET 数据中。
模拟 select
标记的 readonly
属性并仍获取 POST 数据的最佳方法是什么?
您应该保留 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 { 填充:10px; }
我们还可以禁用除选定选项之外的所有选项。
这样下拉菜单仍然有效(并提交其值),但用户无法选择另一个值。
$("#yourSelectId option:not(:selected)).attr("disabled", "disabled")
您可以在提交时重新启用选择对象。
编辑:即,通常禁用选择标签(使用 disabled 属性),然后在提交表单之前自动重新启用它:
jQuery 示例:
要禁用它: $('#yourSelect').prop('disabled', true);
在提交之前重新启用它以便包含 GET / POST 数据: $('#yourForm').on('submit', function() { $('#yourSelect').prop('disabled', false) ; });
此外,您可以重新启用每个禁用的输入或选择:
$('#yourForm').on('submit', function() {
$('input, select').prop('disabled', false);
});
对 select
元素执行 readOnly
属性的另一种方法是使用 css
你可以这样做:
$('#selection').css('pointer-events','none');
... .on('mouseover', function(){ ... });
pointer-events: none
防止鼠标光标聚焦。为了防止键盘上的焦点,您可以通过在所有焦点事件上立即模糊来补充它:$('select').css('pointer-events', 'none').on('focus', function () {$(this).blur();});
-1
值的 tabIndex
属性/属性。
简单的 jQuery 解决方案
如果您的选择具有 readonly
类,请使用此选项
jQuery('select.readonly option:not(:selected)').attr('disabled',true);
或者,如果您的选择具有 readonly="readonly"
属性
$('select[readonly="readonly"] option:not(:selected)').attr('disabled',true);
$(document).ready(function(){$('select option:not(:selected)').attr('disabled',true);});
在单选时工作得很好。不需要“只读”类。多选是有问题的,因为如果已经选择了多个选项因此未被禁用并且用户选择了未禁用的选项之一,则其他先前选择的选项将变为未选中。
$select.find('option').not(':selected').attr('disabled', 'disabled');
select[readonly]
,以便您只需将 readonly 属性添加到元素 - 这样您就不必将选择与任何其他类型区别对待。然后javascript逐渐增强效果。请记住,此解决方案(以及大多数其他解决方案)仅帮助用户代理提供最佳用户体验 - 它实际上并不强制执行任何操作(如果需要,必须在服务器端完成)。
<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>
在 IE 6、7 和 8b2、Firefox 2 和 3、Opera 9.62、Safari 3.2.1 for Windows 和 Google Chrome 中测试和工作。
<select id="countries"> <option value="7" selected="selected">Country7</option> </select>
onchange = 'this.selectedIndex=this.defaultIndex; alert("You should not change this..");'
之类的操作,而不仅仅是静默更改所选索引。
not-allowed
,将背景颜色设置为 #CCC
。
我知道为时已晚,但可以使用简单的 CSS 来完成:
select[readonly] option, select[readonly] optgroup {
display: none;
}
The style hides all the options and the groups when the select is in readonly
state, so the user can not change his selection.
不需要 JavaScript hack。
简单的 CSS 解决方案:
select[readonly]{
background: #eee;
cursor:no-drop;
}
select[readonly] option{
display:none;
}
这导致选择为灰色,悬停时带有漂亮的“禁用”光标,选择选项列表为“空”,因此您无法更改其值。
另一个更现代的选项(不是双关语)是禁用选择元素的所有选项,而不是所选元素。
但是请注意,这是 HTML 4.0 功能,即 6、7、8 beta 1 似乎不尊重这一点。
http://www.gtalbot.org/BrowserBugsSection/MSIE7Bugs/OptionDisabledSupport.html
这是我找到的最佳解决方案:
$("#YourSELECTIdHere option:not(:selected)").prop("disabled", true);
上面的代码禁用所有其他未选中的选项,同时保持选中的选项处于启用状态。这样做,选定的选项将使其成为回发数据。
更简单:将样式属性添加到您的选择标签:
style="pointer-events: none;"
派对有点晚了。但这对我来说似乎完美无缺
select[readonly] {
pointer-events:none;
}
除了禁用不应该选择的选项之外,我还想让它们从列表中消失,但如果我以后需要,仍然可以启用它们:
$("select[readonly]").find("option:not(:selected)").hide().attr("disabled",true);
这会找到所有具有 readonly 属性的选择元素,然后在那些未选择的选择中找到所有选项,然后隐藏它们并禁用它们。
出于性能原因将jquery查询分开2很重要,因为jquery从右到左读取它们,代码:
$("select[readonly] option:not(:selected)")
将首先在文档中查找所有未选择的选项,然后使用 readonly 属性过滤选择中的选项。
.prop("disabled", true)
而不是
这是最简单和最好的解决方案。您将在您的选择上设置一个 readolny 属性,或任何其他属性,如 data-readonly,并执行以下操作
$("select[readonly]").live("focus mousedown mouseup click",function(e){
e.preventDefault();
e.stopPropagation();
});
当您计划将选择禁用时设置为只读,然后在提交表单之前删除禁用属性。
// 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
使用 tabindex 的解决方案。适用于选择但也适用于文本输入。
只需使用 .disabled 类。
CSS:
.disabled {
pointer-events:none; /* No cursor */
background-color: #eee; /* Gray background */
}
JS:
$(".disabled").attr("tabindex", "-1");
HTML:
<select class="disabled">
<option value="0">0</option>
</select>
<input type="text" class="disabled" />
编辑:使用 Internet Explorer,您还需要这个 JS:
$(document).on("mousedown", ".disabled", function (e) {
e.preventDefault();
});
如果您禁用表单字段,则在提交表单时不会发送该字段。因此,如果您需要一个与 disabled
类似但发送值的 readonly
,请执行以下操作:
在元素的只读属性发生任何更改之后。
$('select.readonly option:not(:selected)').attr('disabled',true);
$('select:not([readonly]) option').removeAttr('disabled');
一种简单的服务器端方法是删除除您要选择的选项之外的所有选项。因此,在 Zend Framework 1.12 中,如果 $element 是 Zend_Form_Element_Select:
$value = $element->getValue();
$options = $element->getAttrib('options');
$sole_option = array($value => $options[$value]);
$element->setAttrib('options', $sole_option);
[最简单的解决方案]
由于 OP 特别要求他不想禁用 select 元素,这就是我用来使 select readonly
在 html 中
<select class="form-control-sm" style="pointer-events: none;" onclick="return false;" onkeydown="return false;" ></select>
而已
或者如果你想通过 javascript
让 isReadOnly = true ; selectElement.onclick = function () { return !isReadOnly ; }; selectElement.onkeydown =function(){ return !isReadOnly ; } ; selectElement.style.pointerEvents = isReadOnly ? “无”:“全部”;
解释
将指针事件设置为无会禁用使用鼠标/光标事件编辑“选择元素”
将 onclick 和 onkeydown 函数设置为返回 false 禁用使用键盘编辑“选择元素”
这样您就不必创建任何额外的元素,或使用 javascript 禁用/重新启用该元素或弄乱表单提交逻辑,或使用任何第三方库。
另外,您可以轻松添加 css 样式,例如将背景颜色设置为灰色或将文本颜色设置为灰色,以暗示该元素是只读的。我没有将它添加到代码中,因为这非常特定于您的站点主题
遵循格兰特瓦格纳的建议;这是一个使用处理函数而不是直接 onXXX 属性的 jQuery 片段:
var readonlySelect = function(selector, makeReadonly) {
$(selector).filter("select").each(function(i){
var select = $(this);
//remove any existing readonly handler
if(this.readonlyFn) select.unbind("change", this.readonlyFn);
if(this.readonlyIndex) this.readonlyIndex = null;
if(makeReadonly) {
this.readonlyIndex = this.selectedIndex;
this.readonlyFn = function(){
this.selectedIndex = this.readonlyIndex;
};
select.bind("change", this.readonlyFn);
}
});
};
我用jquery解决了它:
$("select.myselect").bind("focus", function(){
if($(this).hasClass('readonly'))
{
$(this).blur();
return;
}
});
如果您使用的是 jquery validate,您可以执行以下操作,我使用 disabled 属性没有问题:
$(function(){
$('#myform').validate({
submitHandler:function(form){
$('select').removeAttr('disabled');
form.submit();
}
});
});
我发现使用纯 javascript(即:不需要 JQuery 库)效果很好,是将 <select>
标记的 innerHTML 更改为所需的单个剩余值。
前:
<select name='day' id='day'>
<option>SUN</option>
<option>MON</option>
<option>TUE</option>
<option>WED</option>
<option>THU</option>
<option>FRI</option>
<option>SAT</option>
</select>
示例 Javascript:
document.getElementById('day').innerHTML = '<option>FRI</option>';
后:
<select name='day' id='day'>
<option>FRI</option>
</select>
这样,视觉效果不会发生变化,这将在 <FORM>
内进行 POST/GET。
input
是您的 <select>
元素:
input.querySelectorAll(':not([selected])').forEach(option => {
option.disabled = true
})
这将保留数据中的选择(因为它没有被禁用),并且只有未选择的 option
被禁用,因此不可选择。结果是无法更改的可读选择(=> 只读)。
除了选择本身,您可以禁用除当前选择的选项之外的所有选项。这给出了一个工作下拉列表的外观,但只有您想要传入的选项才是有效的选择。
如果选择下拉菜单自出生以来就是只读的并且根本不需要更改,也许您应该使用另一个控件来代替?像一个简单的 <div>
(加上隐藏的表单域)还是一个 <input type="text">
?
补充:如果下拉菜单不是一直只读的并且使用 JavaScript 来启用/禁用它,那么这仍然是一个解决方案 - 只需即时修改 DOM。
html解决方案:
javascript的:
selectElement.addEventListener("焦点", selectElement.blur, true); selectElement.attachEvent("焦点", selectElement.blur); //谢谢,IE
去除:
selectElement.removeEventListener("焦点", selectElement.blur, true); selectElement.detachEvent("焦点", selectElement.blur); //谢谢,IE
编辑:添加删除方法
在 IE 中,我能够通过双击来击败 onfocus=>onblur 方法。但是记住这个值然后在 onchange 事件中恢复它似乎可以解决这个问题。
<select onfocus="this.oldvalue=this.value;this.blur();" onchange="this.value=this.oldvalue;">
....
</select>
您可以使用 javascript 变量在没有扩展属性的情况下执行类似操作。
简单地说,在提交表单之前删除 disabled 属性。
$('form').submit(function () {
$("#Id_Unidade").attr("disabled", false);
});
<select id="case_reason" name="case_reason" disabled="disabled">
disabled="disabled" ->
将从数据库中获取您的值并在表单中显示。 readonly="readonly" ->
您可以在选择框中更改您的值,但您的值无法保存在您的数据库中。
不定期副业成功案例分享
selected
值被回发,而不是整个列表。因此,您的hidden
位于您的select
之前并保存所选值。如果选择被禁用为“只读”,则回发将仅包含隐藏输入的值。如果启用了选择,则可见的选定选项将“覆盖/替换”隐藏的值,这就是将被回发的值。