HTML仕様によると、HTMLのselect
タグにはreadonly
属性がなく、disabled
属性のみがあります。したがって、ユーザーがドロップダウンを変更できないようにするには、を使用する必要がありますdisabled
。
唯一の問題は、無効化されたHTMLフォーム入力がPOST / GETデータに含まれないことです。
タグのreadonly
属性をエミュレートし、select
それでもPOSTデータを取得する最良の方法は何ですか?
HTML仕様によると、HTMLのselect
タグにはreadonly
属性がなく、disabled
属性のみがあります。したがって、ユーザーがドロップダウンを変更できないようにするには、を使用する必要がありますdisabled
。
唯一の問題は、無効化されたHTMLフォーム入力がPOST / GETデータに含まれないことです。
タグのreadonly
属性をエミュレートし、select
それでもPOSTデータを取得する最良の方法は何ですか?
回答:
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")
送信時に選択オブジェクトを再度有効にすることができます。
編集:つまり、通常は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);
});
要素にreadOnly
属性を設定する別の方法select
は、css
あなたは次のようにすることができます:
$('#selection').css('pointer-events','none');
... .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>
WindowsおよびGoogle Chrome用のIE 6、7および8b2、Firefox 2および3、Opera 9.62、Safari 3.2.1でテストおよび動作。
<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);
または、selectにreadonly="readonly"
属性がある場合
$('select[readonly="readonly"] option:not(:selected)').attr('disabled',true);
$(document).ready(function(){$('select option:not(:selected)').attr('disabled',true);});
単一選択で問題なく動作します。「読み取り専用」クラスは必要ありません。複数選択は、すでに複数のオプションが選択されていて無効になっておらず、ユーザーが無効になっていないオプションの1つを選択すると、以前に選択されていた他のオプションが選択解除されるという問題があります。
$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;
}
これにより、選択が灰色になり、カーソルを合わせたときに「無効」カーソルが表示され
、選択時にオプションのリストが「空」になるため、値を変更できません。
さらにもう1つのより現代的なオプション(しゃれた意図はありません)は、選択されたもの以外の選択要素のすべてのオプションを無効にすることです。
ただし、これはHTML 4.0の機能であり、6、7、8ベータ1はこれを尊重しないようです。
http://www.gtalbot.org/BrowserBugsSection/MSIE7Bugs/OptionDisabledSupport.html
これは私が見つけた最良の解決策です:
$("#YourSELECTIdHere option:not(:selected)").prop("disabled", true);
上記のコードは、選択されたオプションを有効にしたまま、選択されていない他のすべてのオプションを無効にします。選択したオプションを選択すると、ポストバックデータになります。
さらに簡単:スタイル属性を選択タグに追加します。
style="pointer-events: none;"
これが最も簡単で最良のソリューションです。selectまたはread-nyのような他のattrにreadolny属性を設定し、次のようにします。
$("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はコードを右から左に読み取るため、パフォーマンス上の理由からjqueryクエリを2つに分離することが重要です。コード:
$("select[readonly] option:not(:selected)")
最初にドキュメント内の選択されていないすべてのオプションを検索し、select内にあるオプションを読み取り専用属性でフィルタリングします。
.prop("disabled", true)
代わりに
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();
});
グラントワグナーズの提案に続き、これは、直接の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;
}
});
私が見つけたのは、プレーンな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
編集:追加された削除メソッド
単純に、フォームを送信する前に、disabled属性を削除してください。
$('form').submit(function () {
$("#Id_Unidade").attr("disabled", false);
});
選択ドロップダウンが誕生以来読み取り専用であり、まったく変更する必要がない場合、おそらく代わりに別のコントロールを使用する必要がありますか?単純な<div>
(および非表示のフォームフィールド)または<input type="text">
?
追加:ドロップダウンが常に読み取り専用ではなく、JavaScriptを使用して有効化/無効化する場合でも、これは解決策です-DOMをその場で変更するだけです。
私は、選択ボックスを非表示に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);
});