Согласно спецификациям HTML, тег select в HTML не имеет атрибута readonly, только атрибут disabled. Поэтому, если вы хотите, чтобы пользователь не менял раскрывающийся список, вы должны использовать disabled.
Единственная проблема заключается в том, что отключенные входные данные HTML-формы не включаются в данные POST / GET.
Как лучше всего имитировать атрибут readonly для тега select и при этом получать данные POST?
Так много решений, что они отвечают на ваш вопрос, но ни одно из них не говорит, что вы можете сделать это с помощью простого исет в своем PHP-коде. Ваш код станет загроможденным, если вы воспользуетесь обходными путями.
Но это не вопрос, связанный с PHP.
@Jrgns Я вижу, вы провели свое исследование относительно ввода в HTML-формы только для чтения и отключенных, но вот полезный вопрос для тех, у кого нет stackoverflow.com/questions/7730695/…
Я бы посоветовал вообще не использовать элемент select в этом случае. Есть ли причина, по которой вы не можете просто отобразить значение как простой текст?
@ppumkin твой комментарий не имеет смысла. Я не говорю, что никогда не бывает хороших вариантов использования для выбранных или скрытых полей формы. У OP возникли проблемы с отображением некоторого текста на странице, и мне просто было интересно, какова цель использования элемента select в этом случае.
Я, должно быть, читаю не тот вопрос. Он говорит, что хочет отключить выбор, чтобы пользователь не менял его. Возможно, ему нужно отобразить страницу с помощью select и использовать jquery для предотвращения изменений. Но когда он отправляет его обратно, данных по нему нет. Я делал то же самое. Мне нужно отображать выборки, которые фильтруются другими выборками, а последнее раскрывающееся меню сохраняется в БД через ajax, поэтому все предыдущие должны быть заблокированы. Когда я повторно визуализирую страницу, да, хорошо - я мог отображать метки вместо выбора. Но проблема не в этом :)
@BrendanByrd В этом случае вы добавляете токен защиты от подделки в запрошенную форму, которую затем отправляете. На сервере токен оценивается.
Нет, не должно быть. Это дрянной А.Ф.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы можете повторно включить выбранный объект при отправке.
РЕДАКТИРОВАТЬ: то есть обычно отключение тега 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);
});
используйте .prop ('disabled', true / false), чтобы установить свойство disabled. Атрибут не изменит фактическое состояние.
Я думаю, что это решение умнее, чем решение @bezmax. Потому что, если мы добавляем скрытый ввод, мы должны были учитывать, что только один из каждого ввода (с тем же именем) был включен в любое время. В противном случае, если оба входа были включены, на стороне сервера программа примет массив входных данных, которые могут вызвать исключение (например, если мы не справились с этой ситуацией, и мы ожидаем одну строку и используем 'Request.Form [FieldName] 'команда)
@Kevin, работает> 90% случаев. Кроме того, у вас должен быть jquery на поясе ... Эх.
Это намного чище принятый ответ. Проще отменить логику, если вы больше не хотите, чтобы элемент отключался и не было дополнительных тегов ввода.
Ты спас мне день! Я искал решение, подобное этому. У меня всегда было NullPointerException в моем приложении Spring Boot. Большое спасибо! :)
это должен быть принятый ответ :)
Я думаю, что этот ответ - лучшее решение, а не добавление нового скрытого типа ввода.
Вы должны сохранить элемент selectdisabled, но также добавить еще один скрытый 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>Собственно, насколько мне известно, это стандартная практика.
Согласовано. Этот метод также небезопасен.
Если вы повторно активируете выбор, вы также должны затем отключить или удалить скрытый ввод (после копирования его значения, как описано), конечно. В противном случае вы получите двойное значение.
@ Адам Это еще один вариант, да. Я обычно использую способ, который я упомянул в своем ответе (без особой причины моего выбора): у тега select нет `` имени '', поэтому он никогда не отправляется, однако он имеет зарегистрированное событие onchange, поэтому, если он снова включен, его значения перенесен на скрытый ввод.
@max Ах !. Хорошо, это тоже работает. С тех пор как вы сказали, я предполагал, что скрытый ввод должен иметь «то же имя», что и выбранный элемент.
Что делать, если я использую множественный выбор?
@anyulled У каждого выбора должен быть отдельный скрытый элемент со значением.
@ Макс, ты можешь сделать это демо?
Да анюллед! У меня тоже были проблемы с выбором нескольких. Я опубликовал ниже то, чем я закончил.
Наличие двух элементов с одинаковыми именами приведет к отправке только последнего включенного / выбранного ввода, а не двойного. Кроме того, возвращается только значение selected, а не весь список. Итак, ваш hidden находится перед вашим select и содержит выбранное значение. Если выбор отключен для «только для чтения», ответная публикация будет содержать только значение скрытого ввода. Если выбор включен, видимая выбранная опция будет «перезаписывать / заменять» скрытое значение, и это значение будет отправлено обратно.
Если вы хотите сделать это правильно, то это правильно! Все остальное - работа вокруг'z - если вы чувствуете себя немного непослушным, но есть несколько хороших ...
Хотя это очевидное решение, оно отстой, поскольку вам нужно добавить еще одно поле ввода.
Итак, как исходный, так и скрытый раскрывающийся список имеют одно и то же имя. Но как мне скопировать значение в скрытое поле, если после повторного включения они имеют то же имя?
Поле @Yeen select не требует имени, его не следует отправлять. Если вам нужно включить его и отправить его значение - либо добавьте к нему событие onChange, чтобы скопировать значение в скрытое поле, либо переместите имя из скрытого поля в поле выбора.
Мне не нравится, как предполагается, что "jquery" используется повсюду. Это очень толстая библиотека, я никогда ее не использовал из-за ее огромного размера и производительности.
@John Вы правы, в настоящее время jQuery больше не является требованием, однако ответ был сделан в 2008 году, когда jQuery был в значительной степени стандартом. В любом случае, сообщение предназначено не для рекламы jQuery, а для демонстрации идеи создания скрытого ввода для обработки того, что было отправлено. Вы можете использовать ту же технику, используя любую другую библиотеку или даже чистый код JS. Просто с jQuery пример выглядит чистейшим ИМХО.
самое грязное решение когда-либо :)
Здесь есть лучший ответ stackoverflow.com/a/23428851/2557900
Вместо самого выбора вы можете отключить все параметры, кроме выбранного в данный момент. Это дает вид рабочего раскрывающегося списка, но допустимым выбором является только тот вариант, который вы хотите передать.
Теоретически отличная идея, но в IE до IE8 НЕТ поддержки отключенных опций. tinyurl.com/yle4bto
<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.
Проблема в том, что раскрывающийся список отображается так, как если бы он не был доступен только для чтения. Пользователь подумает, что это не работает ...
Решение Dojo: var connect = dojo.connect (dojo.byId ('my_select_id'), 'onfocus', function () {this.blur (); return;});
Это сбивает пользователя с толку, потому что он все еще может выбрать параметр, но при его выборе список возвращается к ранее выбранному значению. Гораздо более интуитивно понятно отключить список, чтобы пользователь вообще ничего не мог выбрать.
У меня была аналогичная проблема, и я решил ее, отображая только выбранный вариант. Не требуется JS, меньше путаницы для пользователя ... <select id = "countries"> <option value = "7" selected = "selected">Country7</option> </select>
Очень плохой пользовательский опыт. Люди скажут, что сайт не работает.
@ppumkin @dana @LukasEder Нет .. нет, если ты сможешь исправить этот UX. Например, вы могли бы сделать что-то вроде onchange = 'this.selectedIndex=this.defaultIndex; alert("You should not change this..");' вместо простого изменения выбранного индекса без уведомления.
Позвольте пользователю выбрать и вариант, а затем скажите им, что они не могут выбрать этот вариант. Блестяще. Я бы сразу закрыл этот сайт.
это позволяет мне изменить его один раз (на что-то не так), затем он заблокирован
@LukasEder Для тех, кто с подозрением относится к опыту респондентов, они могут добавить немного CSS, чтобы действительно подчеркнуть, что раскрывающийся список не должен изменяться. Установите курсор на not-allowed и цвет фона на #CCC.
это то, что я искал, а также комментарий @ Fr0zenFy
Если раскрывающийся список выбора доступен только для чтения с момента рождения и не требует никаких изменений, возможно, вам следует использовать другой элемент управления? Как простой <div> (плюс скрытое поле формы) или <input type = "text">?
Добавлен: Если раскрывающийся список не всегда доступен только для чтения и для его включения / отключения используется JavaScript, то это все же решение - просто измените DOM на лету.
Это не только для чтения с самого начала. Я использую JavaScript для изменения и обновления. Если в предыдущем раскрывающемся списке указано определенное значение, оно становится доступным только для чтения.
Тогда, возможно, вы можете заменить этот раскрывающийся список текстовым полем на лету?
Да, но всегда есть скрытый ввод, на мой взгляд, более элегантный
Следуя предложению Гранта Вагнерса; вот фрагмент 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);
}
});
};
Установите параметр select disabled, если вы планируете сделать его доступным только для чтения, а затем удалите атрибут disabled непосредственно перед отправкой формы.
// 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
Это похоже на состояние гонки, которое ждет своего часа.
Я решил это с помощью jquery:
$("select.myselect").bind("focus", function(){
if ($(this).hasClass('readonly'))
{
$(this).blur();
return;
}
});
Это сработало очень хорошо, хотя при анимации наведения мыши по-прежнему будет отображаться стрелка раскрывающегося списка, которая выглядит интерактивной.
У меня это не работает в Chrome 26: выбор по-прежнему полностью функционален.
Но он по-прежнему отображается в списке, когда вы дважды щелкаете по нему в IE. Как бы то ни было, чтобы предотвратить это?
Ниже сработало для меня:
$('select[name=country]').attr("disabled", "disabled");
К вашему сведению: отключенное поле формы не будет включено в отправку.
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: добавлены методы удаления
@ButtleButkus работают ли javascript? я предполагаю, что это может быть проблема, связанная с браузером. вы пытались добавить tabindex к элементу
Мне удалось это скрыть поле выбора и показать вместо него 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()
}
});
В IE мне удалось обойти подход onfocus => onblur двойным щелчком. Но запоминание значения и последующее его восстановление в событии onchange решает эту проблему.
<select onfocus = "this.oldvalue=this.value;this.blur();" onchange = "this.value=this.oldvalue;">
....
</select>
Вы можете сделать то же самое без свойств expando, используя переменную javascript.
Еще один более современный вариант (без каламбура) - отключить все параметры элемента select, кроме выбранного.
обратите внимание, однако, что это функция HTML 4.0 и то есть 6,7,8 бета 1, кажется, не уважает это.
http://www.gtalbot.org/BrowserBugsSection/MSIE7Bugs/OptionDisabledSupport.html
Простое решение jQuery
Используйте это, если ваш выбор имеет класс readonly
jQuery('select.readonly option:not(:selected)').attr('disabled',true);
Или это, если ваш выбор имеет атрибут readonly = "readonly"
$('select[readonly = "readonly"] option:not(:selected)').attr('disabled',true);
Пожалуйста, объясните немного свой код. Нужно ли добавлять к элементам select класс «только для чтения»? Когда мы должны вызывать этот код: только в document.ready или каждый раз при включении / отключении выбора? Безопасен ли ваш код без сценария?
$(document).ready(function(){$('select option:not(:selected)').attr('disabled',true);}); отлично работает с одиночным выбором. Класс "только для чтения" не требуется. Множественный выбор проблематичен в том смысле, что если уже выбрано несколько опций и поэтому они не отключены, и пользователь выбирает одну из не отключенных опций, другие ранее выбранные опции становятся невыбранными.
ничего из этого не понимаю.
Он отключает другие параметры, кроме выбранной, для полей выбора с классом «только для чтения». Если у вас есть элемент выбора, вы можете написать: $select.find('option').not(':selected').attr('disabled', 'disabled');
Black Brick Software - вам, сэр, нужен голос за, это быстрый / чистый способ подделать состояние только для чтения в списке выбора.
Мне нравится это решение. Я бы изменил селектор на select[readonly], чтобы вы просто добавляли атрибут readonly к элементу - таким образом вам не нужно обрабатывать выборки иначе, чем любой другой тип. Затем javascript постепенно усиливает эффект. Имейте в виду, что это решение (и большинство других) только помогает пользовательскому агенту обеспечить наилучшее взаимодействие с пользователем - на самом деле оно ничего не обеспечивает (при необходимости это должно выполняться на стороне сервера).
У меня это не работает. Элементы не изменены.
Это предотвращает отправку значения выбора, что не повторяет функциональность readonly.
Вот попытка использовать настраиваемую функцию 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);
});
Если вы используете проверку jquery, вы можете сделать следующее ниже, я без проблем использовал отключенный атрибут:
$(function(){
$('#myform').validate({
submitHandler:function(form){
$('select').removeAttr('disabled');
form.submit();
}
});
});
Один простой серверный подход - удалить все параметры, кроме той, которую вы хотите выбрать. Таким образом, в 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);
В опции вы можете использовать disabled = "disabled" вместо самого выбора
Почему это было отклонено? Это вполне разумный ответ. Если вы отключите все параметры поля выбора, поле выбора будет доступно только для чтения.
Сначала прочтите вопрос ... "Единственная проблема в том, что отключенные входные данные HTML-формы не включаются в данные POST / GET".
В предложенном здесь ответе option отключен, а не выбран; поэтому данные все еще отправляются, следовательно, они действительны ...
В дополнение к отключению параметров, которые не должны быть выбраны, я хотел, чтобы они действительно исчезли из списка, но все же иметь возможность включить их, если мне понадобится позже:
$("select[readonly]").find("option:not(:selected)").hide().attr("disabled",true);
Это находит все элементы select с атрибутом readonly, затем находит все параметры внутри тех выборок, которые не выбраны, затем скрывает их и отключает их.
Важно разделить запрос jquery на 2 по соображениям производительности, потому что jquery читает их справа налево, код:
$("select[readonly] option:not(:selected)")
сначала найдет все невыбранные параметры в документе, а затем отфильтрует те, которые находятся внутри select, с атрибутом readonly.
Может быть, вместо .prop("disabled", true)
Просто удалите атрибут disabled перед отправкой формы.
$('form').submit(function () {
$("#Id_Unidade").attr("disabled", false);
});
Была такая же проблема и обнаружила очень полезное свойство формы - submitdisabledcontrols.
Установите значение True, и отключенные входы теперь POST.
Это нестандартное свойство формы. Это только для ASP.NET.
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);
});
Если вы отключите поле формы, оно не будет отправлено при отправке формы.
Итак, если вам нужен readonly, который работает как disabled, но отправляет значения, сделайте следующее:
После любого изменения свойств элемента только для чтения.
$('select.readonly option:not(:selected)').attr('disabled',true);
$('select:not([readonly]) option').removeAttr('disabled');
Мы также могли бы использовать это
Отключить все, кроме выбранной опции:
<select>
<option disabled>1</option>
<option selected>2</option>
<option disabled>3</option>
</select>
Таким образом, раскрывающийся список по-прежнему работает (и отправляет свое значение), но пользователь не может выбрать другое значение.
Хороший для динамических опций
Идеально подходит для однозначного тега SELECT! Но не будет работать для <select multiple>, который по-прежнему позволит пользователям отменить выбор некоторых из выбранных параметров, тем самым изменив значение.
Это отличное решение. Я добавлю, что вы можете легко добиться этого с помощью jQuery, например: $("#yourSelectId option:not(:selected)).attr("disabled", "disabled")
$ ('# параметр yourSelectId: not (: selected)'). attr ('отключено', 'отключено')
Простое решение CSS:
select[readonly]{
background: #eee;
cursor:no-drop;
}
select[readonly] option{
display:none;
}
Это приводит к тому, что Select становится серым с красивым курсором "отключить" на hover
.
и при выборе список опций «пустой», поэтому вы не можете изменить его значение.
Если у вас есть проверка CSRF (как в symfony и многих других фреймворках), это не сработает.
другой способ сделать атрибут readOnly элементу select - использовать css
вы могли бы сделать подобное:
$('#selection').css('pointer-events','none');
Хорошее решение. Но вы все равно можете изменить значение с помощью клавиатуры.
Да, это довольно круто. Чтобы изменить значение с помощью клавиатуры, вам нужно будет нажать TAB на элемент, и тогда он станет выбранным. Если вы сделаете цвет фона серым или отключенным, вы также визуально информируете пользователя, что он «отключен», хотя на самом деле он не отключен. Никто больше не поддерживает IE, так что кого это волнует. Вы также можете поставить keydown для предотвращения по умолчанию, если хотите предотвратить.
Совершенно неортодоксальный !! Если необходимо заблокировать выделение для рендеринга страницы, ... .on('mouseover', function(){ ... });
pointer-events: none предотвращает фокусировку курсора мыши. Чтобы также предотвратить фокусировку с клавиатуры, вы можете дополнить его размытием сразу после всех событий фокусировки: $('select').css('pointer-events', 'none').on('focus', function () {$(this).blur();});Это лучшее решение, которое я нашел:
$("#YourSELECTIdHere option:not(:selected)").prop("disabled", true);
В коде выше отключает все остальные параметры не выбраны, при этом выбранный параметр остается включенным. При этом выбранный параметр будет включен в данные обратной передачи.
select multiple не так хорошо реагирует на приведенные выше предложения кода. С БОЛЬШОЙ кувалдой и клуджингом я получил вот что:
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);
});
});
Это самое простое и лучшее решение. Вы установите атрибут только для чтения на свой выбор или любой другой атрибут, например, только для чтения, и выполните следующие действия.
$("select[readonly]").live("focus mousedown mouseup click",function(e){
e.preventDefault();
e.stopPropagation();
});
вы должны добавить здесь keyup ad keydown, так как раскрывающийся список по-прежнему доступен с помощью табуляции и использования клавиш со стрелками для изменения значения.
очень просто. Сначала сохраните значение в переменной. Затем при изменении события установите значение в сохраненную переменную, которая содержит начальное значение
У меня есть имя - отображение. Тогда мой код будет следующим:
$("document").ready(function(){
var mapping=$("select[name=mapping]").val();
$("select[name=mapping]").change(function(){
$("select[name=mapping]").val(mapping);
});
});
<select id = "case_reason" name = "case_reason" disabled = "disabled">
disabled = "disabled" -> получит ваше значение из базы данных и покажет его в форме.
readonly = "readonly" ->: вы можете изменить свое значение в поле выбора, но ваше значение не удалось сохранить в базе данных.
неправильно, это спасено. Похоже, что свойство readonly обрабатывается не всеми браузерами и поэтому ненадежно.
Если у вас есть тег выбора, который должен быть доступен только для чтения, вы должны, по логике, преобразовать поле выбора в одно «текстовое» поле.
Я говорю логично, потому что это как: «Мне нужно показать значение пользователю»
Независимо от того, поступает ли значение из тега select, все равно одно значение и не может быть изменено (только для чтения).
Таким образом, логически вы используете тег select только тогда, когда впервые вставляете значение.
Затем, когда вам нужно отобразить это значение, вы должны поместить его в «текстовое поле только для чтения».
То же самое для множественного выбора, который становится списком значений (выбранное значение), если только чтение
Я использую «текст», потому что тегу только для чтения не нужен атрибут «тип». Ваше здоровье
Я знаю, что уже слишком поздно, но это можно сделать с помощью простого CSS:
select[readonly] option, select[readonly] optgroup {
display: none;
}
Стиль скрывает все параметры и группы, когда выбор находится в состоянии readonly, поэтому пользователь не может изменить свой выбор.
Никаких хаков JavaScript не требуется.
Красиво и просто. Мне это нравится.
Это очень хорошее решение проблемы. Спасибо!
2020, и нет возможности добавить атрибут только для чтения в раскрывающийся список ... отличное решение!
Это работает как шарм. Отлично и элегантно! Спасибо
То, что я обнаружил, отлично работает с простым 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>.
Еще проще: добавьте атрибут стиля в свой тег Выбрать:
style = "pointer-events: none;"
Это работает для меня, но события указателя сделают поддержку кросс-браузеров?
Это не сработает. Пользователь может изменить ввод с помощью клавиатуры.
Решение с 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();
});
Я знаю, что это не поможет всем (если вы только на стороне клиента), но поможет тем, у кого есть полный стек и который контролирует как бэкэнд, так и фронт.
Если у пользователя нет прав на редактирование поля, я возвращаю только текущий выбор для раскрывающегося списка.
Вот некоторые из моих внутренних контроллеров:
#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
What's the best way to emulate the readonly attribute for a select tag, and still get the POST data?
Просто сделайте его полем ввода / текста и добавьте к нему атрибут readonly. Если выбор фактически «отключен», то вы все равно не можете изменить значение, поэтому вам не нужен тег select, и вы можете просто отобразить значение «selected» как текстовый ввод только чтение. Я думаю, что для большинства задач пользовательского интерфейса этого должно быть достаточно.
Поэтому по какой-то причине все упомянутые здесь решения на основе 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; } }
Немного поздно на вечеринку. Но это, кажется, работает для меня безупречно.
select[readonly] {
pointer-events:none;
}
Мое решение - добавить стиль 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;
}
});
Это по-прежнему позволяет перемещаться по элементу с помощью табуляции.
input является вашим элементом <select>:
input.querySelectorAll(':not([selected])').forEach(option => {
option.disabled = true
})
Это сохранит выбор в данных (поскольку он не отключен), и только те option, которые не выбраны, будут отключены, поэтому их нельзя будет выбрать.
Результатом является читаемый выбор, который нельзя изменить (=> только для чтения).
Не полагайтесь на это на стороне сервера. Кто угодно может создать свою собственную HTML-страницу и сделать ее RW.