Question

[Solved] HTML form readonly SELECT tag/input

According to HTML specs, the select tag in HTML doesn’t have a readonly attribute, only a disabled attribute. So if you want to keep the user from changing the dropdown, you have to use disabled.

The only problem is that disabled HTML form inputs don’t get included in the POST / GET data.

What’s the best way to emulate the readonly attribute for a select tag, and still get the POST data?

Enquirer: Jrgns

||

Solution #1:

You should keep the select element disabled but also add another hidden input with the same name and value.

If you reenable your SELECT, you should copy its value to the hidden input in an onchange event and disable (or remove) the hidden input.

Here is a demo:

$('#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>

Respondent: bezmax

Solution #2:

We could also use this

Disable all except the selected option:

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

This way the dropdown still works (and submits its value) but the user can not select another value.

Demo

Respondent: vimal1083

Solution #3:

You can re-enable the select object on submit.

EDIT: i.e., normally disabling the select tag (with the disabled attribute) and then re-enabling it automatically just before submiting the form:

Example with jQuery:

  • To disable it:

    $('#yourSelect').prop('disabled', true);
    
  • To re-enable it before submission so that GET / POST data is included:

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

In addition, you could re-enable every disabled input or select:

$('#yourForm').on('submit', function() {
    $('input, select').prop('disabled', false);
});
Respondent: kemiller2002

Solution #4:

another way of doing a readOnly attribute to a select element is by using css

you could do like :

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

DEMO

Respondent: Yaje

Solution #5:

<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>

Tested and working in IE 6, 7 & 8b2, Firefox 2 & 3, Opera 9.62, Safari 3.2.1 for Windows and Google Chrome.

Respondent: Grant Wagner

Solution #6:

Simple jQuery solution

Use this if your selects have the readonly class

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

Or this if your selects have the readonly="readonly" attribute

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

Solution #7:

I know that it is far too late, but it can be done with simple 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.

No JavaScript hacks are needed.

Respondent: nrofis

Solution #8:

Simple CSS solution:

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

select[readonly] option{
    display:none;
}

This results in Select to be gray with nice “disable” cursor on hover
and on select the list of options is “empty” so you can not change its value.

Respondent: d.raev

Solution #9:

Yet another more contemporary option (no pun intended) is to disable all the options of the select element other then the selected one.

note however that this is an HTML 4.0 feature
and ie 6,7,8 beta 1 seem to not respect this.

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

Respondent: epeleg

Solution #10:

This is the best solution I have found:

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

The code above disables all other options not selected while keeping the selected option enabled. Doing so the selected option will make it into the post-back data.

Respondent: Leniel Maccaferri

Solution #11:

Easier still:
add the style attribute to your select tag:

style="pointer-events: none;"

Solution #12:

This is the simplest and best solution.
You will set a readolny attr on your select, or anyother attr like data-readonly, and do the following

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

Solution #13:

Set the select disabled when you plan for it to be read-only and then remove the disabled attribute just before submitting the form.

// 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
Respondent: Craig Ambrose

Solution #14:

In addition to disabling the options that should not be selectable i wanted to actually make them dissapear from the list, but still be able to enable them should i need to later:

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

This finds all select elements with a readonly attribute, then finds all options inside those selects that are not selected, then it hides them and disables them.

It is important to separate the jquery query in 2 for performance reasons, because jquery reads them from right to left, the code:

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

will first find all unselected options in the document and then filter those that are inside selects with a readonly attribute.

Respondent: cernunnos

Solution #15:

Solution with tabindex. Works with select but also text inputs.

Simply use a .disabled class.

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" />

Edit: With Internet Explorer, you also need this JS:

$(document).on("mousedown", ".disabled", function (e) {
    e.preventDefault();
});
Respondent: jBelanger

Solution #16:

A bit late to the party. But this seems to work flawlessly for me

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

Solution #17:

If you disable a form field, this won’t be sent when form is submitted.
So if you need a readonly that works like disabled but sending values do this :

After any change in readonly properties of an element.

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

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

Solution #18:

One simple server-side approach is to remove all the options except the one that you want to be selected. Thus, in Zend Framework 1.12, if $element is a Zend_Form_Element_Select:

 $value =  $element->getValue();
 $options = $element->getAttrib('options');
 $sole_option = array($value => $options[$value]);
 $element->setAttrib('options', $sole_option);
Respondent: David

Solution #19:

Following on from Grant Wagners suggestion; here is a jQuery snippet that does it with handler functions instead of direct onXXX attributes:

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

};
Respondent: thetoolman

Solution #20:

I resolved it with jquery:

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

Solution #21:

If you are using jquery validate, you can do the following below, I used the disabled attribute without a problem:

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

Solution #22:

What I found works great, with plain javascript (ie: no JQuery library required), is to change the innerHTML of the <select> tag to the desired single remaining value.

Before:

<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>

Sample Javascript:

document.getElementById('day').innerHTML = '<option>FRI</option>';

After:

<select name='day' id='day'>
  <option>FRI</option>
</select>

This way, no visiual effect change, and this will POST/GET within the <FORM>.

Respondent: Syd

Solution #23:

input being your <select> element:

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

This will keep the select in the data (as it’s not disabled) and only the option that are not selected are disabled, therefore not selectable.
The result is a readable select that cannot be changed (=> read only).

Respondent: vinyll

Solution #24:

Rather than the select itself, you could disable all of the options except for the currently selected option. This gives the appearance of a working drop-down, but only the option you want passed in is a valid selection.

Respondent: Adam Bellaire

Solution #25:

html solution:

<select onfocus="this.blur();">

javascript ones:

selectElement.addEventListener("focus", selectElement.blur, true);
selectElement.attachEvent("focus", selectElement.blur); //thanks, IE

to remove:

selectElement.removeEventListener("focus", selectElement.blur, true);
selectElement.detachEvent("focus", selectElement.blur); //thanks, IE

edit: added remove methods

Respondent: Kadmillos

Solution #26:

Simply, remove the disabled attribute before submit the form.

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

Solution #27:

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

disabled="disabled" ->will get your value from database dan show it in the form.
readonly="readonly" ->you can change your value in selectbox, but your value couldn’t save in your database.

Respondent: Afwan Zikri

Solution #28:

If the select dropdown is read-only since birth and does not need to change at all, perhaps you should use another control instead? Like a simple <div> (plus hidden form field) or an <input type="text">?

Added: If the dropdown is not read-only all the time and JavaScript is used to enable/disable it, then this is still a solution – just modify the DOM on-the-fly.

Respondent: Vilx-

Solution #29:

Below worked for me :

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

Solution #30:

I managed it by hiding the select box and showing a span in its place with only informational value. On the event of disabling the .readonly class, we need also to remove the .toVanish elements and show the .toShow ones.

 $( '.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()
            }
    });
Respondent: fiatjaf

The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .

Most Popular

To Top
India and Pakistan’s steroid-soaked rhetoric over Kashmir will come back to haunt them both clenbuterol australia bossier man pleads guilty for leadership role in anabolic steriod distribution conspiracy