HTML表单只读SELECT标签/输入

时间:2008-12-15 15:59:10

标签: javascript html

根据HTML规范,HTML中的select标记没有readonly属性,只有disabled属性。因此,如果您想让用户不要更改下拉菜单,则必须使用disabled

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

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

42 个答案:

答案 0 :(得分:415)

您应该保留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>

答案 1 :(得分:154)

我们也可以使用这个

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

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

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

Demo

答案 2 :(得分:101)

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

编辑:即,通常会禁用select标记(使用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);
});

答案 3 :(得分:47)

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

你可以这样做:

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

DEMO

答案 4 :(得分:38)

<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和&amp ;;中进行测试和工作8b2,Firefox 2&amp; 3,Opera 9.62,适用于Windows和Google Chrome的Safari 3.2.1。

答案 5 :(得分:31)

简单的jQuery解决方案

如果您的选择具有readonly

,请使用此选项
jQuery('select.readonly option:not(:selected)').attr('disabled',true);

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

,则为此
$('select[readonly="readonly"] option:not(:selected)').attr('disabled',true);

答案 6 :(得分:19)

简单的CSS解决方案:

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

select[readonly] option{
    display:none;
}

这会导致选择为灰色且很好&#34;禁用&#34;光标悬停在上面 并且选择选项列表是&#34;空&#34;所以你不能改变它的价值。

答案 7 :(得分:12)

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

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

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

答案 8 :(得分:10)

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

$("#YourSELECTIdHere option:not(:selected)").prop("disabled", true);

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

答案 9 :(得分:9)

更容易: 将style属性添加到 select 标记:

style="pointer-events: none;"

答案 10 :(得分:6)

我知道现在为时已晚,但可以通过简单的CSS完成:

select[readonly] option, select[readonly] optgroup {
    display: none;
}

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

不需要JavaScript hacks。

答案 11 :(得分: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

答案 12 :(得分:5)

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

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

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

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

$("select[readonly] option:not(:selected)")

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

答案 13 :(得分:5)

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

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

答案 14 :(得分:4)

如果您禁用表单字段,则在提交表单时不会发送此字段。 因此,如果您需要readonly,其工作方式与disabled类似,但发送值可执行以下操作:

元素的只读属性发生任何变化后。

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

$('select:not([readonly]) option').removeAttr('disabled');

答案 15 :(得分:4)

一种简单的服务器端方法是删除除了您要选择的选项之外的所有选项。因此,在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);

答案 16 :(得分:3)

使用tabindex的解决方案。适用于select和文本输入。

只需使用.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();
});

答案 17 :(得分:2)

我用jquery解决了它:

      $("select.myselect").bind("focus", function(){
        if($(this).hasClass('readonly'))
        {
          $(this).blur();   
          return;
        }
      });

答案 18 :(得分:2)

如果你正在使用jquery validate,你可以在下面执行以下操作,我使用了disabled属性而没有问题:

$(function(){
    $('#myform').validate({
        submitHandler:function(form){
            $('select').removeAttr('disabled');
            form.submit();
        }
    });
});

答案 19 :(得分:2)

继Grant Wagners的建议之后;这是一个jQuery代码片段,它使用处理函数而不是直接的onXXX属性来执行它:

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);
        }
    });

};

答案 20 :(得分:2)

我发现效果很好,使用普通的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。

答案 21 :(得分:1)

<select id="case_reason" name="case_reason" disabled="disabled">

disabled="disabled" ->将从数据库中获取您的值,并在表单中显示它。 readonly="readonly" ->您可以在selectbox中更改您的值,但您的值无法保存在数据库中。

答案 22 :(得分:1)

聚会晚了一点。但这似乎对我来说是完美的

select[readonly] {
    pointer-events:none;
}

答案 23 :(得分:1)

input是您的<select>元素:

input.querySelectorAll(':not([selected])').forEach(option => {
  option.disabled = true
})

这会将选择保留在数据中(因为未禁用),并且只有未选择的option被禁用,因此无法选择。 结果是无法更改的可读选择(=>只读)。

答案 24 :(得分:1)

除了选择本身,您可以禁用除当前所选选项之外的所有选项。这给出了工作下拉列表的外观,但只有您要传入的选项才是有效选择。

答案 25 :(得分:1)

只需在提交表单之前删除disabled属性。

    $('form').submit(function () {
        $("#Id_Unidade").attr("disabled", false);
    });

答案 26 :(得分:1)

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

编辑:添加删除方法

答案 27 :(得分:0)

我通过隐藏选择框并在其位置显示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()
            }
    });

答案 28 :(得分:0)

我的解决方案是按照此处建议的方式添加select[readonly] { pointer-events: none; }样式,然后添加此JS来处理键盘事件:

$(document).on('keydown', 'select[readonly]', function(e) {
    if (e.keyCode != 9) {
        if (e.preventDefault) {
            e.preventDefault();
        }

        e.returnValue = false;
        e.cancel = true;
    }
});

这仍然允许使用tab遍历元素。

答案 29 :(得分:0)

如果选择下拉列表从出生开始是只读的,根本不需要更改,也许您应该使用另一个控件?就像一个简单的<div>(加上隐藏的表单字段)或<input type="text">

已添加:如果下拉列表不是一直只读,并且JavaScript用于启用/禁用它,那么这仍然是一个解决方案 - 只需动态修改DOM即可。

答案 30 :(得分:0)

因此,无论出于何种原因,这里提到的所有基于jquery的解决方案都不适合我。因此,这是一个纯JavaScript解决方案,在执行POST时也应保留选定的值。

setDropdownReadOnly('yourIdGoesHere',true/false)
    function setDropdownReadOnly(controlName, state) {
        var ddl = document.getElementById(controlName);

        for (i = 0; i < ddl.length; i++) {
            if (i == ddl.selectedIndex)
                ddl[i].disabled = false;
            else
                ddl[i].disabled = state;
        }
    }

答案 31 :(得分:0)

  

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

只需将其设置为输入/文本字段,然后向其中添加“只读”属性即可。如果选择实际上已被“禁用”,则无论如何您都无法更改该值,因此您不需要选择标记,并且可以简单地将“已选择”值显示为只读文本输入。对于大多数UI目的,我认为这已经足够。

答案 32 :(得分:0)

我知道这并不能帮助所有人(如果您仅是客户端),但会帮助那些拥有完整堆栈并且可以控制后端和前端的人。

如果用户没有权限编辑字段,那么我只返回下拉菜单的当前选择。

这是我的一些后端控制器:

        #region Prepare Action Priviledges
        editAuditVM.ExtAuditEditRoleMatrixVM = new ExtAuditEditRoleMatrixVM
        {
            CanEditAcn = _extAuditEditRoleMatrixHelper.CanEditAcn(user, audit),
            CanEditSensitiveDesignation = _extAuditEditRoleMatrixHelper.CanEditSensitiveDesignation(user, audit),
            CanEditTitle = _extAuditEditRoleMatrixHelper.CanEditTitle(),
            CanEditAuditScope = _extAuditEditRoleMatrixHelper.CanEditAuditScope(user, audit)
        };
        #endregion


        #region Prepare SelectLists for Drop Downs
        #region AuditScope List
        IQueryable<SelectListItem> auditScopes = _auditTypesRepo.AuditTypes
            .Where(at => at.AuditTypeClassCode.ToLower() == "e")
            .Select(at => new SelectListItem
            { Text = at.AuditTypeText, Value = at.AuditTypeID.ToString() });
        // Cannot make a select readonly on client side.
        //  So only return currently selected option.
        if (!editAuditVM.ExtAuditEditRoleMatrixVM.CanEditAuditScope)
        {
            auditScopes = auditScopes
                .Where(ascopeId => ascopeId.Value == editAuditVM.ExternalAudit.AuditTypeID.ToString());
        }
        #endregion
        #endregion

答案 33 :(得分:0)

以下为我工作:

$('select[name=country]').attr("disabled", "disabled"); 

答案 34 :(得分:0)

    var selectedOpt;//initialize var
    var newIdForHidden;//initialize var
    $('.disabledOnEdit').focusin(function(){
        selectedOpt = $(this).find(":selected").val();
        newIdForHidden = $(this).attr('id')+'Hidden';
        //alert(selectedOpt+','+newIdForHidden);
        $(this).append('');
        $(this).find('input.hiddenSelectedOpt').attr('id',newIdForHidden).val(selectedOpt);
    });
    $('.disabledOnEdit').focusout(function(){
        var oldSelectedValue=$(this).find('input.hiddenSelectedOpt').val();
        $(this).val(oldSelectedValue);
    });

答案 35 :(得分:0)

在IE中,我能够通过双击击败onfocus =&gt; onblur方法。 但是记住该值然后在onchange事件中恢复它似乎可以解决这个问题。

<select onfocus="this.oldvalue=this.value;this.blur();" onchange="this.value=this.oldvalue;">
....
</select>

您可以使用javascript变量在没有expando属性的情况下执行类似操作。

答案 36 :(得分:0)

如果您的select标签应该是只读的,那么您必须在逻辑上将选择框转换为单个“文本”字段。

我在逻辑上说,因为它就像: “我必须向用户显示一个值”

无论该值是否来自select标记,仍然单个值且无法更改(只读)。

因此,从逻辑上讲,只有在第一次插入值时才使用select标记。

然后,当您需要显示此值时,您必须将其放在“text field-readonly”上。

如果是readonly

,则成为值列表(所选值)的多项选择相同

我使用“text”,因为readonly-tag不需要“type”属性。 干杯

答案 37 :(得分:0)

这是尝试使用自定义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);

});

答案 38 :(得分:0)

很简单。第一个存储值在变量中。然后将更改事件设置值更改为保存初始值

的存储变量

我的名字是映射。然后我的代码如下;

$("document").ready(function(){ 
    var mapping=$("select[name=mapping]").val();
    $("select[name=mapping]").change(function(){
        $("select[name=mapping]").val(mapping);
    });
});

答案 39 :(得分:0)

选择多个对上面的代码建议几乎没有响应。凭借大量的大锤和克服,我最终得到了这个:

var thisId="";
var thisVal="";
function selectAll(){
    $("#"+thisId+" option").each(function(){
        if(!$(this).prop("disabled"))$(this).prop("selected",true);
    });
    $("#"+thisId).prop("disabled",false);
}
$(document).ready(function(){
    $("select option:not(:selected)").attr('disabled',true);
    $("select[multiple]").focus(function(){
        thisId=$(this).prop("id");
        thisVal=$(this).val();
        $(this).prop("disabled",true).blur();
        setTimeout("selectAll();",200);
    });
});

答案 40 :(得分:-2)

在选项中,您可以使用disabled="disabled",而不是选择本身

答案 41 :(得分:-3)

有同样的问题,发现形式非常有用的属性 - submitdisabledcontrols

将其设置为True,禁用的输入现在为POST