HTML-форма readonly SELECT тег/ввод

В соответствии с спецификациями HTML тег select в HTML не имеет атрибута readonly, а только атрибута disabled. Поэтому, если вы хотите, чтобы пользователь не менял раскрывающийся список, вам нужно использовать disabled.

Единственная проблема заключается в том, что отключенные входы HTML-формы не включаются в данные POST/GET.

Какой лучший способ эмулировать атрибут readonly для тега select и все еще получать данные POST?

Ответ 1

Вы должны сохранить элемент 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>

Ответ 2

Мы могли бы также использовать этот

Отключить все, кроме выбранной опции:

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

Таким образом, выпадающее меню все еще работает (и отправляет его значение), но пользователь не может выбрать другое значение.

Демо

Ответ 3

Вы можете снова включить объект select для отправки.

EDIT: т.е. обычно отключая тег select (с отключенным атрибутом), а затем повторно включающий его непосредственно перед отправкой формы:

Пример с jQuery:

  • Чтобы отключить его:

    $('#yourSelect').prop('disabled', true);
    
  • Чтобы снова включить его перед отправкой, чтобы включить данные GET/POST:

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

Кроме того, вы можете повторно включить каждый отключенный ввод или выбрать:

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

Ответ 4

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

Ответ 5

Простое решение jQuery

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

Ответ 6

другой способ использования атрибута readOnly для элемента select заключается в использовании css

вы можете сделать следующее:

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

DEMO

Ответ 7

Простое решение для CSS:

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

select[readonly] option{
    display:none;
}

В результате выберите "Выбрать", чтобы быть серым, с красивым курсором "отключить" при наведении курсора и при выборе списка опций "пусто", поэтому вы не можете изменить его значение.

Ответ 8

Еще один более современный вариант (без каламбура) - отключить все опции выбранного элемента, кроме выбранного.

Обратите внимание, что это функция HTML 4.0 и, следовательно, 6,7,8 бета 1, похоже, не уважают это.

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

Ответ 9

Это лучшее решение, которое я нашел:

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

Код выше отключает все остальные параметры, не выбранные при сохранении выбранного параметра. При этом выбранная опция превратит ее в данные после обратной связи.

Ответ 10

Установите для параметра "отключено", когда вы планируете его читать только для чтения, а затем удалите отключенный атрибут непосредственно перед отправкой формы.

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

Ответ 11

Это самое простое и лучшее решение. Вы установите readolny attr на свой выбор, или любой другой attr, как данные, и сделайте следующее

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

Ответ 12

В дополнение к отключению опций, которые не следует выбирать, я хотел, чтобы они фактически исчезли из списка, но все же сможете включить их, если мне нужно будет позже:

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

Это находит все элементы select с атрибутом readonly, затем находит все параметры внутри тех выбранных, которые не выбраны, затем скрывает их и отключает.

Важно отделить запрос jquery в 2 по соображениям производительности, поскольку jquery читает их справа налево, код:

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

сначала найдет все невыделенные параметры в документе, а затем отфильтрует те, которые находятся внутри selects, с атрибутом readonly.

Ответ 13

Если вы отключите поле формы, это не будет отправлено при отправке формы. Поэтому, если вам нужен readonly, который работает как disabled, но при отправке значений выполните следующее:

После любого изменения свойств readonly элемента.

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

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

Ответ 14

Один простой подход на стороне сервера - удалить все параметры, кроме тех, которые вы хотите выбрать. Таким образом, в 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);

Ответ 15

Легче: добавьте атрибут стиля в тэг select:

style="pointer-events: none;"

Ответ 16

Следуя предложению Гранта Вагнера; вот фрагмент 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);
        }
    });

};

Ответ 17

Я разрешил его с помощью jquery:

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

Ответ 18

Если вы используете проверку jquery, вы можете сделать следующее ниже, я использовал отключенный атрибут без проблем:

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

Ответ 19

Я знаю, что слишком поздно, но это можно сделать с помощью простого CSS:

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

Стиль скрывает все параметры и группы, когда выбор находится в состоянии readonly, поэтому пользователь не может изменить свой выбор.

Нет необходимости в JavaScript-хаках.

Ответ 20

Вместо самого выбора вы можете отключить все параметры, кроме выбранного в данный момент параметра. Это приводит к появлению рабочего раскрывающегося списка, но только вариант, который вы хотите передать, является допустимым выбором.

Ответ 21

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

edit: добавлены методы удаления

Ответ 22

Просто удалите атрибут disabled перед отправкой формы.

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

Ответ 23

То, что я нашел, отлично работает с простым javascript (т.е. не требуется библиотека JQuery), заключается в изменении тега innerHTML тега <select> на желаемое оставшееся значение.

До:

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

Ответ 24

Если раскрывающийся список select доступен только для чтения с момента рождения и вообще не нуждается в изменении, возможно, вы должны использовать другой элемент управления? Как простой <div> (плюс скрытое поле формы) или <input type="text">?

Добавлено: Если раскрывающийся список не доступен для чтения, все время и JavaScript используются для его включения/выключения, то это все еще решение - просто измените DOM на лету.

Ответ 25

Мне удалось заставить это работать, чтобы создать элемент управления выбора только для чтения с использованием JavaScript. Мне пришлось скрыть поле выбора и создать новое скрытое поле. Я разместил код на своем веб-сайте, чтобы использовать его в качестве ссылки. HTML Readonly Select: http://www.codepug.com/readonlySelect.html

Cheers, --ИКС .

Ответ 26

Ниже работал у меня:

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

Ответ 27

Мне это удалось, спрятав поле выбора и показывая 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

В IE я смог победить метод onfocus = > onblur, дважды щелкнув. Но запоминание значения, а затем восстановление его в событии onchange, похоже, справляется с этой проблемой.

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

Вы можете сделать подобное без свойств expando, используя переменную javascript.

Ответ 29

Здесь используется попытка использовать пользовательскую функцию 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);

});

Ответ 30

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