根据HTML规范,select
HTML中的标记没有readonly
属性,只有disabled
属性。因此,如果要阻止用户更改下拉菜单,则必须使用disabled
。
唯一的问题是禁用的HTML表单输入不会包含在POST / GET数据中。
模拟标签readonly
属性select
并仍然获取POST数据的最佳方法是什么?
根据HTML规范,select
HTML中的标记没有readonly
属性,只有disabled
属性。因此,如果要阻止用户更改下拉菜单,则必须使用disabled
。
唯一的问题是禁用的HTML表单输入不会包含在POST / GET数据中。
模拟标签readonly
属性select
并仍然获取POST数据的最佳方法是什么?
Answers:
您应该保留该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>
selected
值被回发而不是整个列表。因此,您hidden
坐在您的前面,select
并保持选定的值。如果选择被禁用为“只读”,则回发将仅包含隐藏输入的值。如果启用了选择,则可见的选定选项将“覆盖/替换”隐藏的值,该值将被回发。
我们也可以用这个
禁用除所选选项之外的所有选项:
<select>
<option disabled>1</option>
<option selected>2</option>
<option disabled>3</option>
</select>
这样,下拉列表仍然有效(并提交其值),但用户无法选择其他值。
$("#yourSelectId option:not(:selected)).attr("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);
});
... .on('mouseover', function(){ ... });
pointer-events: none
防止鼠标光标聚焦。为了防止键盘产生焦点,您可以通过在所有焦点事件上立即模糊来进行补充:$('select').css('pointer-events', 'none').on('focus', function () {$(this).blur();});
<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(适用于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
。
简单的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会逐渐增强效果。请记住,此解决方案(以及其他大多数解决方案)仅有助于用户代理提供最佳的用户体验-它实际上并没有执行任何操作(如果需要,必须在服务器端完成)。
简单的CSS解决方案:
select[readonly]{
background: #eee;
cursor:no-drop;
}
select[readonly] option{
display:none;
}
这会导致“选择”显示为灰色,
并在鼠标悬停时显示漂亮的“禁用”光标,并且在选择时,选项列表为“空”,因此您无法更改其值。
另一个更现代的选项(无双关)是禁用select元素(而不是所选元素)的所有选项。
但是请注意,这是HTML 4.0功能,即6,7,8 beta 1似乎不尊重这一点。
http://www.gtalbot.org/BrowserBugsSection/MSIE7Bugs/OptionDisabledSupport.html
我知道这为时已晚,但是可以使用简单的CSS来完成:
select[readonly] option, select[readonly] optgroup {
display: none;
}
当处于选中readonly
状态时,样式将隐藏所有选项和组,因此用户无法更改其选择。
无需JavaScript技巧。
更简单:将style属性添加到您的select标签中:
style="pointer-events: none;"
这是最简单,最好的解决方案。您将在选择的内容上设置一个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
除了禁用不应选择的选项外,我还想使它们从列表中消失,但是如果以后需要,仍能够启用它们:
$("select[readonly]").find("option:not(:selected)").hide().attr("disabled",true);
这将找到具有只读属性的所有选择元素,然后在那些未选择的选择内找到所有选项,然后将其隐藏并禁用它们。
出于性能原因,将jquery查询分成2个很重要,因为jquery从右到左读取它们,代码如下:
$("select[readonly] option:not(:selected)")
将首先在文档中找到所有未选择的选项,然后使用只读属性过滤select内的所有未选择选项。
.prop("disabled", true)
改为
如果您禁用表单字段,则在提交表单时将不会发送该字段。因此,如果您需要一个readonly
类似于disabled
但发送值的文件,请执行以下操作:
元素的只读属性发生任何更改后。
$('select.readonly option:not(:selected)').attr('disabled',true);
$('select:not([readonly]) option').removeAttr('disabled');
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();
});
遵循Grant Wagners的建议;这是一个使用处理程序函数(而不是直接的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,则可以执行以下操作,我使用了disable属性没有问题:
$(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>
这样,视觉效果不会改变,这将在内进行POST / GET <FORM>
。
除了当前选择的选项之外,您还可以禁用所有选项,而不是选择本身。这样会显示一个有效的下拉菜单,但是只有要传递的选项才是有效的选择。
html解决方案:
<select onfocus="this.blur();">
javascript:
selectElement.addEventListener("focus", selectElement.blur, true);
selectElement.attachEvent("focus", selectElement.blur); //thanks, IE
去除:
selectElement.removeEventListener("focus", selectElement.blur, true);
selectElement.detachEvent("focus", selectElement.blur); //thanks, IE
编辑:添加了删除方法
<select id="case_reason" name="case_reason" disabled="disabled">
disabled="disabled" ->
将从数据库中获取您的价值,并在表单中显示它。
readonly="readonly" ->
您可以在选择框中更改值,但是您的值无法保存在数据库中。
下面为我工作:
$('select[name=country]').attr("disabled", "disabled");
我通过隐藏选择框并span
在其位置仅显示参考值来管理它。在禁用.readonly
类的情况下,我们还需要删除.toVanish
元素并显示它们.toShow
。
$( '.readonly' ).live( 'focus', function(e) {
$( this ).attr( 'readonly', 'readonly' )
if( $( this ).get(0).tagName == 'SELECT' ) {
$( this ).before( '<span class="toVanish readonly" style="border:1px solid; padding:5px">'
+ $( this ).find( 'option:selected' ).html() + '</span>' )
$( this ).addClass( 'toShow' )
$( this ).hide()
}
});
这是尝试使用自定义jQuery函数来实现该功能(如此处所述):
$(function(){
$.prototype.toggleDisable = function(flag) {
// prepare some values
var selectId = $(this).attr('id');
var hiddenId = selectId + 'hidden';
if (flag) {
// disable the select - however this will not submit the value of the select
// a new hidden form element will be created below to compensate for the
// non-submitted select value
$(this).attr('disabled', true);
// gather attributes
var selectVal = $(this).val();
var selectName = $(this).attr('name');
// creates a hidden form element to submit the value of the disabled select
$(this).parents('form').append($('<input></input>').
attr('type', 'hidden').
attr('id', hiddenId).
attr('name', selectName).
val(selectVal) );
} else {
// remove the newly-created hidden form element
$(this).parents('form').remove(hiddenId);
// enable back the element
$(this).removeAttr('disabled');
}
}
// Usage
// $('#some_select_element').toggleDisable(true);
// $('#some_select_element').toggleDisable(false);
});