Reputation: 641
Using Jquery, I would like to be able to dynamically populate on focus a select field that may already have a value. After it's been populated, I would like to set the select tag's value to the prior value if it exists as an option in the new field. I can accomplish this in Chrome, but in Internet Explorer and Firefox I experience differing, unexpected behavior. A description of the problem, some sample code, and a link to a JSFiddle with the sample code follow.
In Firefox, if the user only tabs into the field, it works as intended. If the user clicks the field, the contents and the value update as intended, but if the field loses focus before the user clicks an item in the dropdown list (which the user is wont to do since the previous value could still be highlighted), the value will then update to the topmost option in the select tag.
In IE when the user clicks the field, the javascript fires and I believe updates the DOM, but the result of the change will not be displayed until the field loses focus. Thus the dropdown displayed to the user is of the now removed options, not the newly appended ones. If the select tag loses focus without the user selecting an option, it works as intended (but if the user clicks it again, the font in the dropdown mysteriously changes to serif. Bonus points if you can tell me why that happens).
I was wondering if there might be something wrong with my code or if my issues are caused by bugs (or features) in the browsers.
<p>
<select>
<option value='aaa'>aaa</option>
<option value='bbb' selected="selected">bbb</option>
</select>
</p>
<script>
$(document).ready(function() {
var newOpts = "<option value='ccc'>ccc</option><option value='ddd'>ddd</option><option value='bbb'>bbb</option>";
var $select = $("select");
var selectedOpt = $select.val();
$select.focus(function() {
$select
.empty()
.append(newOpts)
.val(selectedOpt);
});
});
</script>
I have the above in JSFiddle here.
A similar JSFiddle example exists here, explicitly displaying an appended option each time the select tag is clicked.
Any help would be greatly appreciated.
Upvotes: 1
Views: 1214
Reputation: 35670
Event handling for the select
element can vary greatly from browser to browser.
A somewhat hacky solution, which seems to work consistently cross-browser, is to simulate opening the select element on focus, then closing it on blur:
var newOpts = "<option value='ccc'>ccc</option><option value='ddd'>ddd</option><option value='bbb'>bbb</option>";
var $select = $("select");
var selectedOpt = $select.val();
$select.focus(function() {
if(!$(this)[0].size) {
$(this)
.empty()
.append(newOpts)
.val(selectedOpt)
$(this)[0].size= $(this)[0].options.length;
}
});
$select.on('change blur', function() {
$(this)[0].size= 0;
});
select {
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span style="position:relative;width:4em;float:left">
<select>
<option value='aaa'>aaa</option>
<option value='bbb' selected="selected">bbb</option>
</select>
</span>
<input>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Upvotes: 1
Reputation: 370
.val() doesn't work well with selects. Instead, get the text of the selected option like this:
var Selected = $("select option:selected").text();
Then, once you've replaced the select's options, do this:
$("select option").each(function() {
if ($(this).text() == Selected) {
$(this).attr("selected", "selected");
}
});
Upvotes: 0