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
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()
}
});
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);
}
});
};
<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.
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.
I resolved it with jquery:
$("select.myselect").bind("focus", function(){
if($(this).hasClass('readonly'))
{
$(this).blur();
return;
}
});
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.