I faced with a strange behaviour of select element. So, I have a select element with several options. One of option is empty - it's required by plugin to output placeholder.
I needed functionality that would clear selected options and I wrote something like:
$(element).val('');
$(element).find("option:selected").removeAttr("selected");
The thing is that "selected" attribute is still here and it's on old option - you can see it in the code sample.
So, I have 2 questions:
1) Why .val() method of jQuery library do not update "selected" attribute in options list?
2) Why I can not update "selected" attribute in my case? If I switch these statements it's working:
$(element).find("option:selected").removeAttr("selected");
$(element).val('');
Code sample:
$(function(){
$("#unselect").click(function(){
$("#lang_type").val('');
$("#lang_type").find("option:selected").removeAttr("selected");
alert($("#lang_type").html());
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<select id="lang_type">
<option value=""></option>
<option value="01">01 - Language of text</option>
<option value="02">02 - Original language of a translated text</option>
<option selected="selected" value="03">03 - Language of abstracts</option>
<option value="04">04 - Rights language</option>
<option value="05">05 - Rights-excluded language</option>
<option value="06">06 - Original language in a multilingual edition</option>
<option value="07">07 - Translated language in a multilingual edition</option>
<option value="08">08 - Language of audio track</option>
<option value="09">09 - Language of subtitles</option>
</select>
<button id="unselect">Unselect</button>
EDIT:
You can use prop(false) property like this
$(function(){
$("#unselect").click(function(){
$("#lang_type").val('');
$("#lang_type").find("option:selected").prop('selected',false);
});
});
Like #yezzz said, read this :
Note: Do not use removeProp() method to remove native properties such as checked, disabled, or selected. This will remove the property completely and, once removed, cannot be added again to element. Use .prop() to set these properties to false instead.
If I'm not mistaken, a multi-select can be initially unselected, but once any option is selected, it can not be unselected any more. RFC 1866 states in section 8.1.3:
The initial state has the first option selected, unless a SELECTED attribute is present on any of the elements.
This lets me to believe that one option MUST always be selected. Obviously, different browsers interpret this differently...
But it does not seem to be a jQuery issue, rather a browser implementation issue.
The selected attribute reflects merely the initial state of the select input. You shouldn't really care about removing it, as it affects nothing once a different option is selected (either by the user or by a script on your page).
The current state of the input can be read or modified via the selectedIndex property, where a value of -1 means no option is selected (which never is the default, as there always is an option selected initially). However, you seem to want to select a particular "empty" option.
Setting the value on a select box results in the corresponding option being selected, which, in your case, is the very first one.
The code probably does exactly what you want. So don't mind checking the HTML, as the selected attribute - again - is unrelated to the current state of the input.
The :selected selector, however, matches the elements that are currently selected. Your first snippet selects an option, thus making it :selected, then attempts to remove a non-existent attribute from it. The second snippet of yours assumes that the selection remains on the option that was initially selected, and then removes the attribute from it. What follows is the "empty" option getting selected, and no more steps need to be taken, as that's all it takes to select an option.
To summarize: you can safely drop all the code that deals with the removal of the selected attribute, as it doesn't affect the current state of the element, the state being already tied to the correct option.
Related
I am implementing a dropdown using Ember, but I cannot set the selected property of an option element using a handlebars expression.
Here is an ember-twiddle example that shows the issue. Notice how in the DOM of the twiddle, the selected attribute does not appear for the top example.
<select
aria-disabled="{{disabled}}"
aria-multiselectable="{{multiselect}}"
disabled={{cannotOpen}}
onchange={{action 'itemClicked' value='target.value'}}
>
<option selected disabled value="">{{placeholder}}</option>
{{#each items as |item|}}
<option
value={{item.value}}
selected={{if (is-item-selected item.state) "selected"}}
disabled={{item.disabled}}
>
{{item.name}}
</option>
{{/each}}
</select>
"is-item-selected" is a custom helper that returns true if "item.state
=== 2", which is does when the item is selected in the dropdown.
No matter what I try in the handlebars, the selected attribute will not display (e.g. selected={{if true "selected"}} does not work either). However, changing selected to data-selected works exactly as intended.
Is anyone aware of this issue? Or am I misunderstanding how the selected attribute is supposed to work?
So this is actually a "feature" of the dom/html. Classes and data attributes are attributes, while the selected is a property.
There's a great write-up here (about this same issue!)
And if you want to go direct (I stole this from the other answer): .prop() vs .attr()
Given the following jQuery plugin: http://selectric.js.org/index.html which replaces the functionality of that of a regular select box by using custom UL LI lists,
Based on the plugins documentation, I know that you can programmatically select an option value if you already know the index to select by using the following code:
$('#idofselectbox').prop('selectedIndex', 3).selectric('refresh');
But they do not include a sample to be able to find and select an option value by a value.
For example,
Let's say i'd like to select the option value named 'apples' without actually knowing its index in the select box. Is this even remotely possible?
<select id="idofselectbox">
<option value="oranges">oranges</option>
<option value="pears">pears</option>
<option value="apples">apples</option>
<option value="strawberries">strawberries</option>
</select>
You can set the value as if it's a regular combo box, then call refresh on selectic to refresh the UI.
$('#idofselectbox').val('apples').selectric('refresh');
A <select> element looks like this:
<select id="ok">
<option value="one">First</option>
<option value="two" selected>Second</option>
</select>
Initially, the Second text value is shown, because the selected attribute is present.
If I manually change it (using mouse click), it shows the new chosen value in UI, but the <select> remains the same in HTML:
<select id="ok">
<option value="one">First</option>
<option value="two" selected>Second</option>
</select>
I can get the current select value:
document.getElementById('ok').value
or the current selected index:
document.getElementById('ok').selectedIndex
via JavaScript (or jQuery), but I don't know where these values come from.
Are they stored in DOM or somewhere else?
How does JavaScript know which is the current value in UI?
Is it stored in DOM?
Yes, it is stored in the DOM.
Whenever a change event is detected DOM is updated and the updated value is stored in the value object.
When you use document.getElementById("ok").value you are able to access the latest selection in JavaScript.
You can check this in:
Firefox Inspector view
Show DOM Properties
Filter by value:
Chrome DevTools
Select the element > Properties
Expand the select and use the vertical scroll to go to value:
Fisrt of all, the value of select is null(no option is selected) and there already exist some options. However, it changes to the value of first option after adding a new option into select through jquery and vue respectively, why? (we tested this case on chrome)
1.
<select>
<option val="a">a</option>
<option val="b">b</option>
<select>
at this time:
$("select").val() == null
add an option into select with jquery$("select").append("<option value='hi'>hi</option>")
at this time:
$("select").val() == "a"
By default, HTML prefers to have an option selected. It is likely that you manually set the selectedIndex to -1 for your select which is overridden after appending an element to the select. You have one of two options:
Detect your current selectedIndex and restore it after appending. Something along to lines of var originalSelectedIndex = $("select").prop("selectedIndex"); $("select").append("<option value='...'>...</option>"); $("select").prop("selectedIndex", originalSelectedIndex);.
Create an initial element with an empty label such as <option label=" "></option> which would in essence submit an empty value to your server upon submit.
I have a simple HTML select with options. What I do is - set an option of that control as selected just after the page is loaded. My question is - how can I do that so the users won't see the first option of the select and will see the select with the value from the DB set. Here's the example:
<select id="simpleSelect">
<option value = "1">One</option>
<option value = "2">Two</option>
<option value = "3">Three</option>
</select>
Setting the value as follows:
$("#simpleSElect").val(2);
Now the users will see the select with selected option "One" and it will flash changing the option to "Two" once the jQuery code is executed. This flashing does not look good and I'm curious if there's a way to prevent this flashing and show the users the select with directly "Two" selected.
Thanks.