onClick event that checks if an array includes the element - javascript

I have an array of state which is controlled through a dropdown.
This is state held like:
const [finalselected, setfinalSelected] = useState([]);
When a submit button is clicked, I would like to confirm that an element does not already exist in the array, for example an individual cannot input "experience": "A similar role" 10 times into the array.
My current function does not stop additional elements coming if it is a duplicate:
const onSubmitFinalSelection = (val) => {
if (!finalselected.includes(selectedExperience)) {
//if finalselected does NOT include the element, then add in a new element
// setfinalSelected((prev) => [...prev, selectedExperience, inputfield]);
setfinalSelected((prevFinalSelection) => [
...prevFinalSelection,
{
//this is the dropdown
experience: selectedExperience,
//this is an input
inputfield,
},
]);
}
console.log(finalselected)
};
How would you re-write this?

Something like this? I don't think the includes function works with the selectedExperience as single parameter since the array contains objects.
const onSubmitFinalSelection = (val) => {
// If found, return
if (finalselected.some(x => x.experience === selectedExperience))
return;
setfinalSelected([...finalSelected, {
//this is the dropdown
experience: selectedExperience,
//this is an input
inputfield,
}])
console.log(finalsSlected)
};

Alerting if the element is already inside my array if not doing normal push.
let selectedValues = document.querySelector(".selectedValues");
let array = [];
function myFunction(option) {
option = option.value;
if (array.includes(option)) {
alert(option + " "+ "is already selected")
} else {
array.push(option);
}
selectedValues.textContent = array;
}
<textarea class="selectedValues" type="text"></textarea>
<select onchange="myFunction(this)" id="cars">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>

Related

How to add multiple values to a key in local storage

Im trying to allow a user to select multiple select options that can be stored in local storage.
Trying to allow users to choose multiple select options that get saved and are displayed on screen.
html
<body>
<div class="custom_tunings">
<h1>Custom Tunings</h1>
<br>
<fieldset>
<legend>Add New Tunings</legend>
<div class="formBox">
<label for="">Tuning Name</label>
<input type="text" id="inpkey" placeholder="Insert Name"> <br>
</div>
<form class="" action="index.html" method="post">
<div class="formBox">
<select class="mynoteslist" id="inpvalue">
<option value="A1">A1</option>
<option value="B1">B1</option>
<option value="C1">C1</option>
<option value="D1">D1</option>
<option value="E1">E1</option>
<option value="F1">F1</option>
<option value="G1">G1</option>
</select>
</div>
<div class="formBox">
<select class="mynoteslist" id="inpvalue2">
<option value="A1">A1</option>
<option value="B1">B1</option>
<option value="C1">C1</option>
<option value="D1">D1</option>
<option value="E1">E1</option>
<option value="F1">F1</option>
<option value="G1">G1</option>
</select>
</div>
</form>
<button type="button" id="btninsert">Save Tuning </button>
<br>
</fieldset>
<fieldset>
<legend>My Tunings</legend>
<div id="isoutput"> </div>
</fieldset>
</div>
Im trying add multiple inpvalues to a key.
I cant seem to add another inpvalue as it seems to only accept the first value.
Im wondering if theres a simple way around this?
javascript
let inpkey = document.getElementById("inpkey");
let inpvalue=document.getElementById("inpvalue");
//let inpvalue2=document.getElementById("inpvalue2");
let btninsert = document.getElementById("btninsert");
let isoutput = document.getElementById("isoutput");
btninsert.onclick = function(){
let key = inpkey.value;
let value = inpvalue.value;
//let value2 = inpvalue.value;
console.log(key);
console.log(value);
//console.log(value2);
if(key && value) {
localStorage.setItem(key,value);
location.reload();
}
};
for(let i=0; i<localStorage.length; i++){
let key=localStorage.key(i);
let value=localStorage.getItem(key);
isoutput.innerHTML += `${key}: ${value} <br>` ;
}
the desired output would be something like this
Howver if i try to select different options it only takes the first value and applies them to all.
You need to check for the existence of a key and if found, append the new value to the existing value before saving.
if(key && value) {
// if the key exists
if(localStorage.getItem(key)){
// split the existing values into an array
let vals = localStorage.getItem(key).split(',');
// if the value has not already been added
if(! vals.includes(value)){
// add the value to the array
vals.push(value);
// sort the array
vals.sort();
// join the values into a delimeted string and store it
localStorage.setItem(key, vals.join(','));
}
}else{
// the key doesn't exist yet, add it and the new value
localStorage.setItem(key,value);
}
location.reload();
}
I made a working example of the above code here: https://jsfiddle.net/01rjn3cf/2/
EDIT: Based on your comments and added example of desired output, I see that you don't want a distinct list of values and that any value can be added to the list of previously selected values. In this case the solution is even easier..
if(key && value) {
// if the key exists
if(localStorage.getItem(key)){
// add this value onto the end of the existing string
localStorage.setItem(key, localStorage.getItem(key) + ', ' + value);
}else{
// the key doesn't exist yet, add it and the new value
localStorage.setItem(key,value);
}
location.reload();
}
EDIT:
I modified it as so to work as desired.
if(key && value) {
var content = value + ', ' + value2 + value3;
// if the key exists
if(localStorage.getItem(key)){
// add this value onto the end of the existing string
localStorage.setItem(key, content);
}else{
// the key doesn't exist yet, add it and the new value
localStorage.setItem(key, content);
}
location.reload();
}
};
for(var i=0; i<localStorage.length; i++){
var key=localStorage.key(i);
var value=localStorage.getItem(key);
isoutput.innerHTML += `${key}: ${value} <br>` ;
}
Once you have implemented #Drew's fix to store a list of items, you will need to supply all of the values of the selects.
Rather than
btninsert.onclick = function(){
let key = inpkey.value;
let value = inpvalue.value;
//let value2 = inpvalue.value;
...
You'll need all of the selects, and then pass each one into the localStorage part. Here I find all the select elements with class "mynoteslist", get their values, then filter out the empty ones
btninsert.onclick = function(){
let key = inpkey.value;
const inpValues = [...document.querySelectorAll("select.mynoteslist")]
.map({value} => value)
.filter(value => value);
if (inpValues.length) {
inpValues.forEach(v => storeLocally(key, v));
location.reload();
}
//...
Then #Drew's part wrapped in a function
function storeLocally(key, value) {
if(key && value) {
// if the key exists
if(localStorage.getItem(key)){
// split the existing values into an array
let vals = localStorage.getItem(key).split(',');
// if the value has not already been added
if(! vals.includes(value)){
// add the value to the array
vals.push(value);
// sort the array
vals.sort();
// join the values into a delimeted string and store it
localStorage.setItem(key, vals.join(','));
}
}else{
// the key doesn't exist yet, add it and the new value
localStorage.setItem(key,value);
}
}
}

get multi selection value from lookup field using java script

I nee d get mutiple value from a lookup field and i need to validate it,if i get more than one value i need to give a message and if get one value i need to give another message.i have try something but it not work.
function getbankdetails()
{
debugger;
var arr = $('#R3413775').val();
if(arr[0]!="" && arr[1] !="")
{
alert("first"+arr[0]+" "+arr[1]);
}
else
{
alert("sasa");
}
}
This may work (Javascript)
function getbankdetails()
{
debugger;
var arr = Array.from(document.getElementById("R3413775").selectedOptions).map((ele) => ele.value)
if(arr[0] && arr[1] && arr.length == 2)
{
alert("first"+arr[0]+" "+arr[1]);
}
else
{
alert("sasa");
}
}
You can simply get the elements as the array and either console log the "sasa" string or the list of selected items as a string (by concatenating the array with commas.
$('#R3413775').change(function(){
getbankdetails();
})
function getbankdetails() {
var arr = $('#R3413775').val();
arr.length == 1
? console.log("sasa")
: console.log(arr.join(', '))
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="R3413775" multiple>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel" >Opel</option>
<option value="audi">Audi</option>
</select>

How to get all selected values from <select multiple=multiple>? [duplicate]

I have a <select> element with the multiple attribute. How can I get this element's selected values using JavaScript?
Here's what I'm trying:
function loopSelected() {
var txtSelectedValuesObj = document.getElementById('txtSelectedValues');
var selectedArray = new Array();
var selObj = document.getElementById('slct');
var i;
var count = 0;
for (i=0; i<selObj.options.length; i++) {
if (selObj.options[i].selected) {
selectedArray[count] = selObj.options[i].value;
count++;
}
}
txtSelectedValuesObj.value = selectedArray;
}
No jQuery:
// Return an array of the selected opion values
// select is an HTML select element
function getSelectValues(select) {
var result = [];
var options = select && select.options;
var opt;
for (var i=0, iLen=options.length; i<iLen; i++) {
opt = options[i];
if (opt.selected) {
result.push(opt.value || opt.text);
}
}
return result;
}
Quick example:
<select multiple>
<option>opt 1 text
<option value="opt 2 value">opt 2 text
</select>
<button onclick="
var el = document.getElementsByTagName('select')[0];
alert(getSelectValues(el));
">Show selected values</button>
With jQuery, the usual way:
var values = $('#select-meal-type').val();
From the docs:
In the case of <select multiple="multiple"> elements, the .val() method returns an array containing each selected option;
Actually, I found the best, most-succinct, fastest, and most-compatible way using pure JavaScript (assuming you don't need to fully support IE lte 8) is the following:
var values = Array.prototype.slice.call(document.querySelectorAll('#select-meal-type option:checked'),0).map(function(v,i,a) {
return v.value;
});
UPDATE (2017-02-14):
An even more succinct way using ES6/ES2015 (for the browsers that support it):
const selected = document.querySelectorAll('#select-meal-type option:checked');
const values = Array.from(selected).map(el => el.value);
You can use selectedOptions property
var options = document.getElementById('select-meal-type').selectedOptions;
var values = Array.from(options).map(({ value }) => value);
console.log(values);
<select id="select-meal-type" multiple="multiple">
<option value="1">Breakfast</option>
<option value="2" selected>Lunch</option>
<option value="3">Dinner</option>
<option value="4" selected>Snacks</option>
<option value="5">Dessert</option>
</select>
ES6
[...select.options].filter(option => option.selected).map(option => option.value)
Where select is a reference to the <select> element.
To break it down:
[...select.options] takes the Array-like list of options and destructures it so that we can use Array.prototype methods on it (Edit: also consider using Array.from())
filter(...) reduces the options to only the ones that are selected
map(...) converts the raw <option> elements into their respective values
If you wanna go the modern way, you can do this:
const selectedOpts = [...field.options].filter(x => x.selected);
The ... operator maps iterable (HTMLOptionsCollection) to the array.
If you're just interested in the values, you can add a map() call:
const selectedValues = [...field.options]
.filter(x => x.selected)
.map(x => x.value);
Check-it Out:
HTML:
<a id="aSelect" href="#">Select</a>
<br />
<asp:ListBox ID="lstSelect" runat="server" SelectionMode="Multiple" Width="100px">
<asp:ListItem Text="Raj" Value="1"></asp:ListItem>
<asp:ListItem Text="Karan" Value="2"></asp:ListItem>
<asp:ListItem Text="Riya" Value="3"></asp:ListItem>
<asp:ListItem Text="Aman" Value="4"></asp:ListItem>
<asp:ListItem Text="Tom" Value="5"></asp:ListItem>
</asp:ListBox>
JQUERY:
$("#aSelect").click(function(){
var selectedValues = [];
$("#lstSelect :selected").each(function(){
selectedValues.push($(this).val());
});
alert(selectedValues);
return false;
});
CLICK HERE TO SEE THE DEMO
First, use Array.from to convert the HTMLCollection object to an array.
let selectElement = document.getElementById('categorySelect')
let selectedValues = Array.from(selectElement.selectedOptions)
.map(option => option.value) // make sure you know what '.map' does
// you could also do: selectElement.options
suppose the multiSelect is the Multiple-Select-Element, just use its selectedOptions Property:
//show all selected options in the console:
for ( var i = 0; i < multiSelect.selectedOptions.length; i++) {
console.log( multiSelect.selectedOptions[i].value);
}
$('#select-meal-type :selected') will contain an array of all of the selected items.
$('#select-meal-type option:selected').each(function() {
alert($(this).val());
});
​
Pretty much the same as already suggested but a bit different. About as much code as jQuery in Vanilla JS:
selected = Array.prototype.filter.apply(
select.options, [
function(o) {
return o.selected;
}
]
);
It seems to be faster than a loop in IE, FF and Safari. I find it interesting that it's slower in Chrome and Opera.
Another approach would be using selectors:
selected = Array.prototype.map.apply(
select.querySelectorAll('option[selected="selected"]'),
[function (o) { return o.value; }]
);
Update October 2019
The following should work "stand-alone" on all modern browsers without any dependencies or transpilation.
<!-- display a pop-up with the selected values from the <select> element -->
<script>
const showSelectedOptions = options => alert(
[...options].filter(o => o.selected).map(o => o.value)
)
</script>
<select multiple onchange="showSelectedOptions(this.options)">
<option value='1'>one</option>
<option value='2'>two</option>
<option value='3'>three</option>
<option value='4'>four</option>
</select>
If you need to respond to changes, you can try this:
document.getElementById('select-meal-type').addEventListener('change', function(e) {
let values = [].slice.call(e.target.selectedOptions).map(a => a.value));
})
The [].slice.call(e.target.selectedOptions) is needed because e.target.selectedOptions returns a HTMLCollection, not an Array. That call converts it to Array so that we can then apply the map function, which extract the values.
Check this:
HTML:
<select id="test" multiple>
<option value="red" selected>Red</option>
<option value="rock" selected>Rock</option>
<option value="sun">Sun</option>
</select>
Javascript one line code
Array.from(document.getElementById("test").options).filter(option => option.selected).map(option => option.value);
if you want as you expressed with breaks after each value;
$('#select-meal-type').change(function(){
var meals = $(this).val();
var selectedmeals = meals.join(", "); // there is a break after comma
alert (selectedmeals); // just for testing what will be printed
})
Try this:
$('#select-meal-type').change(function(){
var arr = $(this).val()
});
Demo
$('#select-meal-type').change(function(){
var arr = $(this).val();
console.log(arr)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="select-meal-type" multiple="multiple">
<option value="1">Breakfast</option>
<option value="2">Lunch</option>
<option value="3">Dinner</option>
<option value="4">Snacks</option>
<option value="5">Dessert</option>
</select>
fiddle
Here is an ES6 implementation:
value = Array(...el.options).reduce((acc, option) => {
if (option.selected === true) {
acc.push(option.value);
}
return acc;
}, []);
Building on Rick Viscomi's answer, try using the HTML Select Element's selectedOptions property:
let txtSelectedValuesObj = document.getElementById('txtSelectedValues');
[...txtSelectedValuesObj.selectedOptions].map(option => option.value);
In detail,
selectedOptions returns a list of selected items.
Specifically, it returns a read-only HTMLCollection containing HTMLOptionElements.
... is spread syntax. It expands the HTMLCollection's elements.
[...] creates a mutable Array object from these elements, giving you an array of HTMLOptionElements.
map() replaces each HTMLObjectElement in the array (here called option) with its value (option.value).
Dense, but it seems to work.
Watch out, selectedOptions isn't supported by IE!
You can get as an array the values from the <select> at the submit of the form as this example :
const form = document.getElementById('form-upload');
form.addEventListener('change', (e) => {
const formData = new FormData(form);
const selectValue = formData.getAll('pets');
console.log(selectValue);
})
<form id="form-upload">
<select name="pets" multiple id="pet-select">
<option value="">--Please choose an option--</option>
<option value="dog">Dog</option>
<option value="cat">Cat</option>
<option value="hamster">Hamster</option>
<option value="parrot">Parrot</option>
<option value="spider">Spider</option>
<option value="goldfish">Goldfish</option>
</select>
</form>
Something like the following would be my choice:
let selectElement = document.getElementById('categorySelect');
let selectedOptions = selectElement.selectedOptions || [].filter.call(selectedElement.options, option => option.selected);
let selectedValues = [].map.call(selectedOptions, option => option.value);
It's short, it's fast on modern browsers, and we don't care whether it's fast or not on 1% market share browsers.
Note, selectedOptions has wonky behavior on some browsers from around 5 years ago, so a user agent sniff isn't totally out of line here.
You Can try this script
<!DOCTYPE html>
<html>
<script>
function getMultipleSelectedValue()
{
var x=document.getElementById("alpha");
for (var i = 0; i < x.options.length; i++) {
if(x.options[i].selected ==true){
alert(x.options[i].value);
}
}
}
</script>
</head>
<body>
<select multiple="multiple" id="alpha">
<option value="a">A</option>
<option value="b">B</option>
<option value="c">C</option>
<option value="d">D</option>
</select>
<input type="button" value="Submit" onclick="getMultipleSelectedValue()"/>
</body>
</html>
You can use [].reduce for a more compact implementation of RobG's approach:
var getSelectedValues = function(selectElement) {
return [].reduce.call(selectElement.options, function(result, option) {
if (option.selected) result.push(option.value);
return result;
}, []);
};
My template helper looks like this:
'submit #update': function(event) {
event.preventDefault();
var obj_opts = event.target.tags.selectedOptions; //returns HTMLCollection
var array_opts = Object.values(obj_opts); //convert to array
var stray = array_opts.map((o)=> o.text ); //to filter your bits: text, value or selected
//do stuff
}
Same as the earlier answer but using underscore.js.
function getSelectValues(select) {
return _.map(_.filter(select.options, function(opt) {
return opt.selected; }), function(opt) {
return opt.value || opt.text; });
}
Works everywhere without jquery:
var getSelectValues = function (select) {
var ret = [];
// fast but not universally supported
if (select.selectedOptions != undefined) {
for (var i=0; i < select.selectedOptions.length; i++) {
ret.push(select.selectedOptions[i].value);
}
// compatible, but can be painfully slow
} else {
for (var i=0; i < select.options.length; i++) {
if (select.options[i].selected) {
ret.push(select.options[i].value);
}
}
}
return ret;
};
Here ya go.
const arr = Array.from(el.features.selectedOptions) //get array from selectedOptions property
const list = []
arr.forEach(item => list.push(item.value)) //push each item to empty array
console.log(list)
$('#application_student_groups option:selected').toArray().map(item => item.value)
You can create your own function like this and use it everywhere
Pure JS
/**
* Get values from multiple select input field
* #param {string} selectId - the HTML select id of the select field
**/
function getMultiSelectValues(selectId) {
// get the options of select field which will be HTMLCollection
// remember HtmlCollection and not an array. You can always enhance the code by
// verifying if the provided select is valid or not
var options = document.getElementById(selectId).options;
var values = [];
// since options are HtmlCollection, we convert it into array to use map function on it
Array.from(options).map(function(option) {
option.selected ? values.push(option.value) : null
})
return values;
}
you can get the same result using jQuery in a single line
$('#select_field_id').val()
and this will return the array of values of well.

How to get all selected values of a multiple select box?

I have a <select> element with the multiple attribute. How can I get this element's selected values using JavaScript?
Here's what I'm trying:
function loopSelected() {
var txtSelectedValuesObj = document.getElementById('txtSelectedValues');
var selectedArray = new Array();
var selObj = document.getElementById('slct');
var i;
var count = 0;
for (i=0; i<selObj.options.length; i++) {
if (selObj.options[i].selected) {
selectedArray[count] = selObj.options[i].value;
count++;
}
}
txtSelectedValuesObj.value = selectedArray;
}
No jQuery:
// Return an array of the selected opion values
// select is an HTML select element
function getSelectValues(select) {
var result = [];
var options = select && select.options;
var opt;
for (var i=0, iLen=options.length; i<iLen; i++) {
opt = options[i];
if (opt.selected) {
result.push(opt.value || opt.text);
}
}
return result;
}
Quick example:
<select multiple>
<option>opt 1 text
<option value="opt 2 value">opt 2 text
</select>
<button onclick="
var el = document.getElementsByTagName('select')[0];
alert(getSelectValues(el));
">Show selected values</button>
With jQuery, the usual way:
var values = $('#select-meal-type').val();
From the docs:
In the case of <select multiple="multiple"> elements, the .val() method returns an array containing each selected option;
Actually, I found the best, most-succinct, fastest, and most-compatible way using pure JavaScript (assuming you don't need to fully support IE lte 8) is the following:
var values = Array.prototype.slice.call(document.querySelectorAll('#select-meal-type option:checked'),0).map(function(v,i,a) {
return v.value;
});
UPDATE (2017-02-14):
An even more succinct way using ES6/ES2015 (for the browsers that support it):
const selected = document.querySelectorAll('#select-meal-type option:checked');
const values = Array.from(selected).map(el => el.value);
You can use selectedOptions property
var options = document.getElementById('select-meal-type').selectedOptions;
var values = Array.from(options).map(({ value }) => value);
console.log(values);
<select id="select-meal-type" multiple="multiple">
<option value="1">Breakfast</option>
<option value="2" selected>Lunch</option>
<option value="3">Dinner</option>
<option value="4" selected>Snacks</option>
<option value="5">Dessert</option>
</select>
ES6
[...select.options].filter(option => option.selected).map(option => option.value)
Where select is a reference to the <select> element.
To break it down:
[...select.options] takes the Array-like list of options and destructures it so that we can use Array.prototype methods on it (Edit: also consider using Array.from())
filter(...) reduces the options to only the ones that are selected
map(...) converts the raw <option> elements into their respective values
If you wanna go the modern way, you can do this:
const selectedOpts = [...field.options].filter(x => x.selected);
The ... operator maps iterable (HTMLOptionsCollection) to the array.
If you're just interested in the values, you can add a map() call:
const selectedValues = [...field.options]
.filter(x => x.selected)
.map(x => x.value);
Check-it Out:
HTML:
<a id="aSelect" href="#">Select</a>
<br />
<asp:ListBox ID="lstSelect" runat="server" SelectionMode="Multiple" Width="100px">
<asp:ListItem Text="Raj" Value="1"></asp:ListItem>
<asp:ListItem Text="Karan" Value="2"></asp:ListItem>
<asp:ListItem Text="Riya" Value="3"></asp:ListItem>
<asp:ListItem Text="Aman" Value="4"></asp:ListItem>
<asp:ListItem Text="Tom" Value="5"></asp:ListItem>
</asp:ListBox>
JQUERY:
$("#aSelect").click(function(){
var selectedValues = [];
$("#lstSelect :selected").each(function(){
selectedValues.push($(this).val());
});
alert(selectedValues);
return false;
});
CLICK HERE TO SEE THE DEMO
First, use Array.from to convert the HTMLCollection object to an array.
let selectElement = document.getElementById('categorySelect')
let selectedValues = Array.from(selectElement.selectedOptions)
.map(option => option.value) // make sure you know what '.map' does
// you could also do: selectElement.options
suppose the multiSelect is the Multiple-Select-Element, just use its selectedOptions Property:
//show all selected options in the console:
for ( var i = 0; i < multiSelect.selectedOptions.length; i++) {
console.log( multiSelect.selectedOptions[i].value);
}
$('#select-meal-type :selected') will contain an array of all of the selected items.
$('#select-meal-type option:selected').each(function() {
alert($(this).val());
});
​
Pretty much the same as already suggested but a bit different. About as much code as jQuery in Vanilla JS:
selected = Array.prototype.filter.apply(
select.options, [
function(o) {
return o.selected;
}
]
);
It seems to be faster than a loop in IE, FF and Safari. I find it interesting that it's slower in Chrome and Opera.
Another approach would be using selectors:
selected = Array.prototype.map.apply(
select.querySelectorAll('option[selected="selected"]'),
[function (o) { return o.value; }]
);
Update October 2019
The following should work "stand-alone" on all modern browsers without any dependencies or transpilation.
<!-- display a pop-up with the selected values from the <select> element -->
<script>
const showSelectedOptions = options => alert(
[...options].filter(o => o.selected).map(o => o.value)
)
</script>
<select multiple onchange="showSelectedOptions(this.options)">
<option value='1'>one</option>
<option value='2'>two</option>
<option value='3'>three</option>
<option value='4'>four</option>
</select>
If you need to respond to changes, you can try this:
document.getElementById('select-meal-type').addEventListener('change', function(e) {
let values = [].slice.call(e.target.selectedOptions).map(a => a.value));
})
The [].slice.call(e.target.selectedOptions) is needed because e.target.selectedOptions returns a HTMLCollection, not an Array. That call converts it to Array so that we can then apply the map function, which extract the values.
Check this:
HTML:
<select id="test" multiple>
<option value="red" selected>Red</option>
<option value="rock" selected>Rock</option>
<option value="sun">Sun</option>
</select>
Javascript one line code
Array.from(document.getElementById("test").options).filter(option => option.selected).map(option => option.value);
if you want as you expressed with breaks after each value;
$('#select-meal-type').change(function(){
var meals = $(this).val();
var selectedmeals = meals.join(", "); // there is a break after comma
alert (selectedmeals); // just for testing what will be printed
})
Try this:
$('#select-meal-type').change(function(){
var arr = $(this).val()
});
Demo
$('#select-meal-type').change(function(){
var arr = $(this).val();
console.log(arr)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="select-meal-type" multiple="multiple">
<option value="1">Breakfast</option>
<option value="2">Lunch</option>
<option value="3">Dinner</option>
<option value="4">Snacks</option>
<option value="5">Dessert</option>
</select>
fiddle
Here is an ES6 implementation:
value = Array(...el.options).reduce((acc, option) => {
if (option.selected === true) {
acc.push(option.value);
}
return acc;
}, []);
Building on Rick Viscomi's answer, try using the HTML Select Element's selectedOptions property:
let txtSelectedValuesObj = document.getElementById('txtSelectedValues');
[...txtSelectedValuesObj.selectedOptions].map(option => option.value);
In detail,
selectedOptions returns a list of selected items.
Specifically, it returns a read-only HTMLCollection containing HTMLOptionElements.
... is spread syntax. It expands the HTMLCollection's elements.
[...] creates a mutable Array object from these elements, giving you an array of HTMLOptionElements.
map() replaces each HTMLObjectElement in the array (here called option) with its value (option.value).
Dense, but it seems to work.
Watch out, selectedOptions isn't supported by IE!
You can get as an array the values from the <select> at the submit of the form as this example :
const form = document.getElementById('form-upload');
form.addEventListener('change', (e) => {
const formData = new FormData(form);
const selectValue = formData.getAll('pets');
console.log(selectValue);
})
<form id="form-upload">
<select name="pets" multiple id="pet-select">
<option value="">--Please choose an option--</option>
<option value="dog">Dog</option>
<option value="cat">Cat</option>
<option value="hamster">Hamster</option>
<option value="parrot">Parrot</option>
<option value="spider">Spider</option>
<option value="goldfish">Goldfish</option>
</select>
</form>
Something like the following would be my choice:
let selectElement = document.getElementById('categorySelect');
let selectedOptions = selectElement.selectedOptions || [].filter.call(selectedElement.options, option => option.selected);
let selectedValues = [].map.call(selectedOptions, option => option.value);
It's short, it's fast on modern browsers, and we don't care whether it's fast or not on 1% market share browsers.
Note, selectedOptions has wonky behavior on some browsers from around 5 years ago, so a user agent sniff isn't totally out of line here.
You Can try this script
<!DOCTYPE html>
<html>
<script>
function getMultipleSelectedValue()
{
var x=document.getElementById("alpha");
for (var i = 0; i < x.options.length; i++) {
if(x.options[i].selected ==true){
alert(x.options[i].value);
}
}
}
</script>
</head>
<body>
<select multiple="multiple" id="alpha">
<option value="a">A</option>
<option value="b">B</option>
<option value="c">C</option>
<option value="d">D</option>
</select>
<input type="button" value="Submit" onclick="getMultipleSelectedValue()"/>
</body>
</html>
You can use [].reduce for a more compact implementation of RobG's approach:
var getSelectedValues = function(selectElement) {
return [].reduce.call(selectElement.options, function(result, option) {
if (option.selected) result.push(option.value);
return result;
}, []);
};
My template helper looks like this:
'submit #update': function(event) {
event.preventDefault();
var obj_opts = event.target.tags.selectedOptions; //returns HTMLCollection
var array_opts = Object.values(obj_opts); //convert to array
var stray = array_opts.map((o)=> o.text ); //to filter your bits: text, value or selected
//do stuff
}
Same as the earlier answer but using underscore.js.
function getSelectValues(select) {
return _.map(_.filter(select.options, function(opt) {
return opt.selected; }), function(opt) {
return opt.value || opt.text; });
}
Works everywhere without jquery:
var getSelectValues = function (select) {
var ret = [];
// fast but not universally supported
if (select.selectedOptions != undefined) {
for (var i=0; i < select.selectedOptions.length; i++) {
ret.push(select.selectedOptions[i].value);
}
// compatible, but can be painfully slow
} else {
for (var i=0; i < select.options.length; i++) {
if (select.options[i].selected) {
ret.push(select.options[i].value);
}
}
}
return ret;
};
Here ya go.
const arr = Array.from(el.features.selectedOptions) //get array from selectedOptions property
const list = []
arr.forEach(item => list.push(item.value)) //push each item to empty array
console.log(list)
$('#application_student_groups option:selected').toArray().map(item => item.value)
You can create your own function like this and use it everywhere
Pure JS
/**
* Get values from multiple select input field
* #param {string} selectId - the HTML select id of the select field
**/
function getMultiSelectValues(selectId) {
// get the options of select field which will be HTMLCollection
// remember HtmlCollection and not an array. You can always enhance the code by
// verifying if the provided select is valid or not
var options = document.getElementById(selectId).options;
var values = [];
// since options are HtmlCollection, we convert it into array to use map function on it
Array.from(options).map(function(option) {
option.selected ? values.push(option.value) : null
})
return values;
}
you can get the same result using jQuery in a single line
$('#select_field_id').val()
and this will return the array of values of well.

set option "selected" attribute from dynamic created option

I have a dynamically created select option using a javascript function. the select object is
<select name="country" id="country">
</select>
when the js function is executed, the "country" object is
<select name="country" id="country">
<option value="AF">Afghanistan</option>
<option value="AL">Albania</option>
...
<option value="ID">Indonesia</option>
...
<option value="ZW">Zimbabwe</option>
</select>
and displaying "Indonesia" as default selected option. note : there is no selected="selected" attribute in that option.
then I need to set selected="selected" attribute to "Indonesia", and I use this
var country = document.getElementById("country");
country.options[country.options.selectedIndex].setAttribute("selected", "selected");
using firebug, I can see the "Indonesia" option is like this
<option value="ID" selected="selected">Indonesia</option>
but it fails in IE (tested in IE 8).
and then I have tried using jQuery
$( function() {
$("#country option:selected").attr("selected", "selected");
});
it fails both in FFX and IE.
I need the "Indonesia" option to have selected="selected" attribute so when I click reset button, it will select "Indonesia" again.
changing the js function to dynamically create "country" options is not an option. the solution must work both in FFX and IE.
thank you
You're overthinking it:
var country = document.getElementById("country");
country.options[country.options.selectedIndex].selected = true;
Good question. You will need to modify the HTML itself rather than rely on DOM properties.
var opt = $("option[val=ID]"),
html = $("<div>").append(opt.clone()).html();
html = html.replace(/\>/, ' selected="selected">');
opt.replaceWith(html);
The code grabs the option element for Indonesia, clones it and puts it into a new div (not in the document) to retrieve the full HTML string: <option value="ID">Indonesia</option>.
It then does a string replace to add the attribute selected="selected" as a string, before replacing the original option with this new one.
I tested it on IE7. See it with the reset button working properly here: http://jsfiddle.net/XmW49/
Instead of modifying the HTML itself, you should just set the value you want from the relative option element:
$(function() {
$("#country").val("ID");
});
In this case "ID" is the value of the option "Indonesia"
So many wrong answers!
To specify the value that a form field should revert to upon resetting the form, use the following properties:
Checkbox or radio button: defaultChecked
Any other <input> control: defaultValue
Option in a drop down list: defaultSelected
So, to specify the currently selected option as the default:
var country = document.getElementById("country");
country.options[country.selectedIndex].defaultSelected = true;
It may be a good idea to set the defaultSelected value for every option, in case one had previously been set:
var country = document.getElementById("country");
for (var i = 0; i < country.options.length; i++) {
country.options[i].defaultSelected = i == country.selectedIndex;
}
Now, when the form is reset, the selected option will be the one you specified.
// get the OPTION we want selected
var $option = $('#SelectList').children('option[value="'+ id +'"]');
// and now set the option we want selected
$option.attr('selected', true);​​
What you want to do is set the selectedIndex attribute of the select box.
country.options.selectedIndex = index_of_indonesia;
Changing the 'selected' attribute will generally not work in IE. If you really want the behavior you're describing, I suggest you write a custom javascript reset function to reset all the other values in the form to their default.
This works in FF, IE9
var x = document.getElementById("country").children[2];
x.setAttribute("selected", "selected");
Make option defaultSelected
HTMLOptionElement.defaultSelected = true; // JS
$('selector').prop({defaultSelected: true}); // jQuery
HTMLOptionElement MDN
If the SELECT element is already added to the document (statically or dynamically), to set an option to Attribute-selected and to make it survive a HTMLFormElement.reset() - defaultSelected is used:
const EL_country = document.querySelector('#country');
EL_country.value = 'ID'; // Set SELECT value to 'ID' ("Indonesia")
EL_country.options[EL_country.selectedIndex].defaultSelected = true; // Add Attribute selected to Option Element
document.forms[0].reset(); // "Indonesia" is still selected
<form>
<select name="country" id="country">
<option value="AF">Afghanistan</option>
<option value="AL">Albania</option>
<option value="HR">Croatia</option>
<option value="ID">Indonesia</option>
<option value="ZW">Zimbabwe</option>
</select>
</form>
The above will also work if you build the options dynamically, and than (only afterwards) you want to set one option to be defaultSelected.
const countries = {
AF: 'Afghanistan',
AL: 'Albania',
HR: 'Croatia',
ID: 'Indonesia',
ZW: 'Zimbabwe',
};
const EL_country = document.querySelector('#country');
// (Bad example. Ideally use .createDocumentFragment() and .appendChild() methods)
EL_country.innerHTML = Object.keys(countries).reduce((str, key) => str += `<option value="${key}">${countries[key]}</option>`, '');
EL_country.value = 'ID';
EL_country.options[EL_country.selectedIndex].defaultSelected = true;
document.forms[0].reset(); // "Indonesia" is still selected
<form>
<select name="country" id="country"></select>
</form>
Make option defaultSelected while dynamically creating options
To make an option selected while populating the SELECT Element, use the Option() constructor MDN
var optionElementReference = new Option(text, value, defaultSelected, selected);
const countries = {
AF: 'Afghanistan',
AL: 'Albania',
HR: 'Croatia',
ID: 'Indonesia', // <<< make this one defaultSelected
ZW: 'Zimbabwe',
};
const EL_country = document.querySelector('#country');
const DF_options = document.createDocumentFragment();
Object.keys(countries).forEach(key => {
const isIndonesia = key === 'ID'; // Boolean
DF_options.appendChild(new Option(countries[key], key, isIndonesia, isIndonesia))
});
EL_country.appendChild(DF_options);
document.forms[0].reset(); // "Indonesia" is still selected
<form>
<select name="country" id="country"></select>
</form>
In the demo above Document.createDocumentFragment is used to prevent rendering elements inside the DOM in a loop. Instead, the fragment (containing all the Options) is appended to the Select only once.
SELECT.value vs. OPTION.setAttribute vs. OPTION.selected vs. OPTION.defaultSelected
Although some (older) browsers interpret the OPTION's selected attribute as a "string" state, the WHATWG HTML Specifications html.spec.whatwg.org state that it should represent a Boolean selectedness
The selectedness of an option element is a boolean state, initially false. Except where otherwise specified, when the element is created, its selectedness must be set to true if the element has a selected attribute.
html.spec.whatwg.org - Option selectedness
one can correctly deduce that just the name selected in <option value="foo" selected> is enough to set a truthy state.
Comparison test of the different methods
const EL_select = document.querySelector('#country');
const TPL_options = `
<option value="AF">Afghanistan</option>
<option value="AL">Albania</option>
<option value="HR">Croatia</option>
<option value="ID">Indonesia</option>
<option value="ZW">Zimbabwe</option>
`;
// https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/MutationObserver
const mutationCB = (mutationsList, observer) => {
mutationsList.forEach(mu => {
const EL = mu.target;
if (mu.type === 'attributes') {
return console.log(`* Attribute ${mu.attributeName} Mutation. ${EL.value}(${EL.text})`);
}
});
};
// (PREPARE SOME TEST FUNCTIONS)
const testOptionsSelectedByProperty = () => {
const test = 'OPTION with Property selected:';
try {
const EL = [...EL_select.options].find(opt => opt.selected);
console.log(`${test} ${EL.value}(${EL.text}) PropSelectedValue: ${EL.selected}`);
} catch (e) {
console.log(`${test} NOT FOUND!`);
}
}
const testOptionsSelectedByAttribute = () => {
const test = 'OPTION with Attribute selected:'
try {
const EL = [...EL_select.options].find(opt => opt.hasAttribute('selected'));
console.log(`${test} ${EL.value}(${EL.text}) AttrSelectedValue: ${EL.getAttribute('selected')}`);
} catch (e) {
console.log(`${test} NOT FOUND!`);
}
}
const testSelect = () => {
console.log(`SELECT value:${EL_select.value} selectedIndex:${EL_select.selectedIndex}`);
}
const formReset = () => {
EL_select.value = '';
EL_select.innerHTML = TPL_options;
// Attach MutationObserver to every Option to track if Attribute will change
[...EL_select.options].forEach(EL_option => {
const observer = new MutationObserver(mutationCB);
observer.observe(EL_option, {attributes: true});
});
}
// -----------
// LET'S TEST!
console.log('\n1. Set SELECT value');
formReset();
EL_select.value = 'AL'; // Constatation: MutationObserver did NOT triggered!!!!
testOptionsSelectedByProperty();
testOptionsSelectedByAttribute();
testSelect();
console.log('\n2. Set HTMLElement.setAttribute()');
formReset();
EL_select.options[2].setAttribute('selected', true); // MutationObserver triggers
testOptionsSelectedByProperty();
testOptionsSelectedByAttribute();
testSelect();
console.log('\n3. Set HTMLOptionElement.defaultSelected');
formReset();
EL_select.options[3].defaultSelected = true; // MutationObserver triggers
testOptionsSelectedByProperty();
testOptionsSelectedByAttribute();
testSelect();
console.log('\n4. Set SELECT value and HTMLOptionElement.defaultSelected');
formReset();
EL_select.value = 'ZW'
EL_select.options[EL_select.selectedIndex].defaultSelected = true; // MutationObserver triggers
testOptionsSelectedByProperty();
testOptionsSelectedByAttribute();
testSelect();
/* END */
console.log('\n*. Getting MutationObservers out from call-stack...');
<form>
<select name="country" id="country"></select>
</form>
Although the test 2. using .setAttribute() seems at first the best solution since both the Element Property and Attribute are unison, it can lead to confusion, specially because .setAttribute expects two parameters:
EL_select.options[1].setAttribute('selected', false);
// <option value="AL" selected="false"> // But still selected!
will actually make the option selected
Should one use .removeAttribute() or perhaps .setAttribute('selected', ???) to another value? Or should one read the state by using .getAttribute('selected') or by using .hasAttribute('selected')?
Instead test 3. (and 4.) using defaultSelected gives the expected results:
Attribute selected as a named Selectedness state.
Property selected on the Element Object, with a Boolean value.
select = document.getElementById('selectId');
var opt = document.createElement('option');
opt.value = 'value';
opt.innerHTML = 'name';
opt.selected = true;
select.appendChild(opt);
// Get <select> object
var sel = $('country');
// Loop through and look for value match, then break
for(i=0;i<sel.length;i++) { if(sel.value=="ID") { break; } }
// Select index
sel.options.selectedIndex = i;
Begitu loh.
This should work.
$("#country [value='ID']").attr("selected","selected");
If you have function calls bound to the element just follow it with something like
$("#country").change();
You could search all the option values until it finds the correct one.
var defaultVal = "Country";
$("#select").find("option").each(function () {
if ($(this).val() == defaultVal) {
$(this).prop("selected", "selected");
}
});
Vanilla JS
Use this for Vanilla Javascript, keeping in mind that you can feed the example "numbers" array with any data from a fetch function (for example).
The initial HTML code:
<label for="the_selection">
<select name="the_selection" id="the_selection_id">
<!-- Empty Selection -->
</select>
</label>
Some values select tag:
const selectionList = document.getElementById('the_selection_id');
const numbers = ['1','3','5'];
numbers.forEach(number => {
const someOption = document.createElement('option');
someOption.setAttribute('value', number);
someOption.innerText = number;
if (number == '3') someOption.defaultSelected = true;
selectionList.appendChild(someOption);
})
You'll get:
<label for="the_selection">
<select name="the_selection" id="the_selection_id">
<!-- Empty Selection -->
<option value="1">1</option>
<option value="3" selected>3</option>
<option value="5">5</option>
</select>
</label>
You can solve this on ES6 like this:
var defaultValue = "ID";
[...document.getElementById('country').options].map(e => e.selected = (e.value == defaultValue));
I haven't test in other browsers but in Chrome works just fine.
...document.getElementById('country').options using the spread operator you cast options as an array.
.map allows you to apply a function to each element of your array.
e represents each <option> element of your object so you can access its attributes like .select and .value as getter and setter.
Because you .select receives a boolean option you want to assign when its value is equal to your default value.
To set the input option at run time try setting the 'checked' value. (even if it isn't a checkbox)
elem.checked=true;
Where elem is a reference to the option to be selected.
So for the above issue:
var country = document.getElementById("country");
country.options[country.options.selectedIndex].checked=true;
This works for me, even when the options are not wrapped in a .
If all of the tags share the same name, they should uncheck when the new one is checked.
Realize this is an old question, but with the newer version of JQuery you can now do the following:
$("option[val=ID]").prop("selected",true);
This accomplishes the same thing as Box9's selected answer in one line.
The ideas on this page were helpful, yet as ever my scenario was different. So, in modal bootstrap / express node js / aws beanstalk, this worked for me:
var modal = $(this);
modal.find(".modal-body select#cJourney").val(vcJourney).attr("selected","selected");
Where my select ID = "cJourney" and the drop down value was stored in variable: vcJourney
I was trying something like this using the $(...).val() function, but the function did not exist. It turns out that you can manually set the value the same way you do it for an <input>:
// Set value to Indonesia ("ID"):
$('#country').value = 'ID'
...and it get's automatically updated in the select. Works on Firefox at least; you might want to try it out in the others.
To set value in JavaScript using set attribute , for selected option tag
var newvalue = 10;
var x = document.getElementById("optionid").selectedIndex;
document.getElementById("optionid")[x].setAttribute('value', newvalue);

Categories