Retrieving selected values in Materialize CSS multiple select using JavaScript - javascript

I'm using multiple select of Materialize CSS in a form to select multiple values. The UI is working fine, but I couldn't find a way to retrieve all the selected values. I used an onChange event handler to retrieve the values. However instead of an array of selected values it is returning only the first selected value in the list.
Can anybody explain how to do it using JavaScript for a simple multiple select like the one below? (Not by using jQuery)
<select id='mySelect' multiple>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>

You can get the selected in this way:
html:
<select multiple id="option-select">
<option value="" disabled selected>Choose your option</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
<label>Materialize Multiple Select</label>
js
document.addEventListener("DOMContentLoaded", function () {
const selects = document.querySelector("select");
const instances = M.FormSelect.init(selects, {});
const selectOption = document.querySelector("#option-select");
selectOption.addEventListener("change", function () {
const instance = M.FormSelect.getInstance(selectOption);
const selectedValues = instance.getSelectedValues();
console.log(selectedValues);
});
});

Related

Simulate onClick with Enter on form select option

I have a form that passes values to a function.
<TR><TD>Select</TD><TD><select name=k_id>
<OPTION value=1 onClick="myfun('10','0.1','1')">Option 1</OPTION>
<OPTION value=2 onClick="myfun('20','0.2','2')">Option 2</OPTION>
<OPTION value=3 onClick="myfun('30','0.3','3')">Option 3</OPTION>
<OPTION value=4 onClick="myfun('40','0.4','4')">Option 4</OPTION>
</select>
function myfun(id,h,k,g)
{
var h_id=document.getElementById('h_id');
h_id.value=id;
var hind=document.getElementById('hind');
hind.value=h;
var koe=document.getElementById('koe');
koe.value=k;
}
But it doesn't work if the user selects an option using arrow keys and Enter.
How can I pass appropriate values to myfun() with pressing Enter?
I have tried:
<OPTION value=1 onClick="myfun('10','0.1','1')" onkeypress="if(event.key == 'Enter') {myfun('10','0.1','1')}">Option 1</OPTION>
<OPTION value=1 onClick="myfun('10','0.1','1')" onkeyup = "if(event.keyCode == 13){myfun('10','0.1','1')}">Option 1</OPTION>
<OPTION value=1 onClick="myfun('10','0.1','1')" onkeydown = "if(event.keyCode == 13){myfun('10','0.1','1')}">Option 1</OPTION>
I have tried adding onchange to select element in the past but that had other issues. And would require rewriting the code that populates options list.
Use the select.onchange event instead, like this:
function myfun(id,h,k){
console.log(id,h,k)
}
<TR><TD>Select</TD><TD><select name=k_id onchange="myfun(...JSON.parse(this.value))">
<OPTION value='["10","0.1","1"]'>Option 1</OPTION>
<OPTION value='["20","0.2","2"]'>Option 2</OPTION>
<OPTION value='["30","0.3","3"]'>Option 3</OPTION>
<OPTION value='["40","0.4","4"]'>Option 4</OPTION>
</select>
This answer attempted to listen for clicks, and it seems like it worked at the time. But it doesn't work in the current version of Chrome.
Using the onChange call will result in a duplicate code, and more unreable thinks.
Consider placing your data in data- sets, so you can use a onChange event on the select. This event will trigger when your press and when you use your keyboard. So no need to duplicate code.
Then use dataset to get your data back from the new value:
function myfun(event) {
const e = event.target;
const { id, h, k } = e.options[e.selectedIndex].dataset;
console.log('Change: ', id, h, k);
}
<TR><TD>Select</TD><TD>
<select name="k_id" onChange='myfun(event)'>
<OPTION value=1 data-id='10' data-h='0.1' data-k='1'>Option 1</OPTION>
<OPTION value=2 data-id='20' data-h='0.2' data-k='2'>Option 2</OPTION>
<OPTION value=3 data-id='30' data-h='0.3' data-k='3'>Option 3</OPTION>
<OPTION value=4 data-id='40' data-h='0.4' data-k='4'>Option 4</OPTION>
</select>

Materialize CSS returns previously selected value from the EventListener on a Select

document.addEventListener("DOMContentLoaded", function () {
const selects = document.querySelector("select");
const instances = M.FormSelect.init(selects, {});
const selectOption = document.querySelector("#option-select");
selectOption.addEventListener("change", function () {
const instance = M.FormSelect.getInstance(selectOption);
const selectedValues = instance.getSelectedValues();
console.log(selectedValues[0]);
});
});
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<select id="option-select">
<option value="" disabled selected>Choose your option</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
<label>Materialize Multiple Select</label>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
I'm using select of Materialize CSS to return the selected value.
First selection returns the undefined
Second selection returns the first selection
Third selections returns the second and so.....
Image of output from console
The UI is working fine, but I JS is exhibiting the above unusual behaviour. Can anybody explain what's going on here. I'm a bit stumped.
This a bug is in Materialize CSS. There are some workarounds online but none are clean.
The bug has been fixed in the Alpha version at the time of writing so in the end I decided to update stylesheet and script tags to match the same.
document.addEventListener("DOMContentLoaded", function () {
const selects = document.querySelector("select");
const instances = M.FormSelect.init(selects, {});
});
const selectOption = document.querySelector("#option-select");
selectOption.addEventListener("change", function () {
const instance = M.FormSelect.getInstance(selectOption);
const selectedValues = instance.getSelectedValues();
console.log(selectedValues[0]);
});
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/#materializecss/materialize#1.1.0/dist/css/materialize.min.css">
<div class="input-field col s12">
<select id="option-select">
<option value="" disabled selected>Choose your option</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
<label>Materialize Multiple Select</label>
</div>
<script src="https://cdn.jsdelivr.net/npm/#materializecss/materialize#1.1.0/dist/js/materialize.min.js"></script>

How to use getElementByID in JavaScript to connect to my HTML drop down box?

I have a drop-down box in HTML showing three options. I am also using javaScript and want to use the getElementById tool to connect the two. However, I only have one ID for the drop-down box. How does javascript recognize that I have three different options?
There's actually a demo on w3schools.com showing exactly what you're asking. To get the number of options, you could do something like
document.getElementById("mySelect").options.length
Here is an example of how to retrieve the value of a dropdown: https://jsfiddle.net/ykcwgnm8/
You use getElementBy* functions to get the element, however value attribute denotes which item is currently selected.
HTML:
<select id="dropdown">
<option value="1">First option</option>
<option value="2">Second option</option>
<option value="3">Third option</option>
</select>
JS:
function onChangeHandler(e)
{
alert("you have selected item with value "+this.value);
}
document.getElementById("dropdown").addEventListener("change", onChangeHandler);
You can listen for change like this
var list = document.getElementById("mySelect")
list.addEventListener('change', function(e){
console.log(e.target.selectedIndex)
console.log(e.target.options[e.target.selectedIndex].text)
})
<select id="mySelect">
<option>Apple</option>
<option>Orange</option>
<option>Pineapple</option>
<option>Banana</option>
</select>
You can do something like this, here is an example:-
html
<select id="selectBox">
<option value="1">option 1</option>
<option value="2" selected="selected">option 2</option>
<option value="3">option 3</option>
</select>
js
var e = document.getElementById("selectBox");
var selectedValue = e.options[e.selectedIndex].value;
// this will give selectedValue as 2
Hope you find this useful!!

How to set default selection based on another selection

I have multiple dropdown selections on a single page with exact same options but different IDs. I need dropdown A and B to have the same option selected at all times but only if they both share those options.
I'm a javascript noob so I've tried many variations of code but nothing works, I think it's best if someone could write this simple code from scratch.
Imagine these two selections with cloned options:
<select id="california">
<option value="red">red</option>
<option value="yellow">yellow</option>
<option value="blue">blue</option>
</select>
<select id="texas">
<option value="red">red</option>
<option value="yellow">yellow</option>
<option value="blue">blue</option>
</select>
If you select red in ID california it needs to switch to red in ID texas, and vice versa.
You can add a common class and select on the change event something like following
Jquery
$(document).ready(function(){
$(".select").change(function() {
$(".select").not(this).find("option[value="+ $(this).val() + "]").attr('selected', true)
});
});
Pure JavaScript Solution as already written by #Emeeus
const selectElement = [...document.getElementsByClassName("ClassName")];
selectElement.forEach(a => {
a.addEventListener("change", (e) => {
selectElement.forEach(aa => {
if (aa.querySelectorAll(`option[value=${e.target.value}]`).length)
aa.value = e.target.value;
})
})
})
A simple way to get this done is :
reference the select elements in JavaScript and store the two of them in an array.
when looping through the selects we can store the index of the current select, that has to be used to get the other select (a simple mathematical calculation).
loop through that array (that means looping through the selects) and attach a change event listener to each one of the select elements.
fetch the option that has to be selected, if found, after filtering the options of the other select based on the value of the selected option.
if there's an option that has the same value as the selected option, select that option in the other select.
This may still a bit ambiguous, a demo is worth a hundred docs :
the next demo takes into consideration that an/some option(s) may not appear in both of the select elements, simply nothing will happen and the same functionality stays as is.
/** an array that stores the selects **/
const selects = [document.getElementById('california'), document.getElementById('texas')];
/** ## cycle through these selects
* el: current select in the loop.
* idx: its index in the "selects" array.
**/
selects.forEach((el, idx) => {
/** attach change listener **/
el.addEventListener('change', () => {
/** get the option that should be selected in the other select if found there **/
/** "selects[Math.abs(idx - 1)]" gets the other select (the one that isn't changed) **/
const toBeSelected = [...selects[Math.abs(idx - 1)].options].filter(o => o.value === el.options[el.selectedIndex].value);
/** if we have an option from the other select's options that has the same value as the selected one then return in order to be selected **/
/** if ther's an option that matches the above condition simply select it **/
toBeSelected[0] && (selects[Math.abs(idx - 1)].selectedIndex = toBeSelected[0].index);
});
});
<select id="california">
<option value="red">red</option>
<option value="yellow">yellow</option>
<option value="blue">blue</option>
</select>
<select id="texas">
<option value="red">red</option>
<option value="yellow">yellow</option>
<option value="blue">blue</option>
<!-- new option that doesn't exist in the other select element -->
<option value="green">green</option>
</select>
The ideal solution would be using classes, but with that HTML here a solution:
const selects = [...document.getElementsByTagName("select")];
selects.forEach(s => {
s.addEventListener("change", (e) => {
selects.forEach(sl => {
if (sl.querySelectorAll(`option[value=${e.target.value}]`).length)
sl.value = e.target.value;
})
})
})
<select id="california">
<option value="red">red</option>
<option value="yellow">yellow</option>
<option value="blue">blue</option>
<option value="brown">brown</option>
</select>
<select id="texas">
<option value="red">red</option>
<option value="yellow">yellow</option>
<option value="blue">blue</option>
</select>
<select id="las_vegas">
<option value="red">red</option>
<option value="yellow">yellow</option>
<option value="blue">blue</option>
</select>
this is very simple code :
<select id="california" onclick="applyEvent()">
<option value="red">red</option>
<option value="yellow">yellow</option>
<option value="blue">blue</option>
<option value="brown">brown</option>
</select>
<select id="texas" onclick="apply_Event()">
<option value="red"">red</option>
<option value="yellow">yellow</option>
<option value="blue">blue</option>
<option value="brown">brown</option>
</select>
<script type="text/javascript">
function applyEvent() {
document.getElementById("texas").value = document.getElementById('california').value;
}
function apply_Event() {
document.getElementById("california").value = document.getElementById('texas').value;
}
</script>
<select id="california">
<option value="red">red</option>
<option value="yellow">yellow</option>
<option value="blue">blue</option>
</select>
<select id="texas">
<option value="red">red</option>
<option value="yellow">yellow</option>
<option value="blue">blue</option>
</select>
<script>
var californiaSelect = document.getElementById('california');
var texasSelect = document.getElementById('texas');
californiaSelect.addEventListener('change', () => {
texasSelect.value = californiaSelect.value;
})
texasSelect.addEventListener('change', () => {
californiaSelect.value = texasSelect.value;
})
</script>
You can find a working example is this fiddle
getElementById
addEventListener

Auto check saved data in jQuery Multiselect

I am using this jQuery Multiselect plugin https://github.com/nobleclem/jQuery-MultiSelect to convert all my select boxes that have the multiple attribute enabled in to drop down boxes with check boxes.
I load the options in the select box from a database.
Upon the form submission I can save the multiple selected data, but when I retreive data back from the database I cannot display the saved data back in the multi select box by checking matching check boxes.
The multiselect plugin has a loadOptions method, but using that method I have to generate all option data with option name, option value and the check status, and set it to the multiselect plugin. How can I easily do this if I have an array of data which must be checked/selected in the multiple select plugin?
HTML
<select name="abc" id="abc" multiple title="Test Number?">
<option value="1">Test 1</option>
<option value="2">Test 2</option>
<option value="3">Test 3</option>
<option value="4">Test 4</option>
<option value="5">Test 5</option>
</select>
JS (I have more than one multiple select boxes and initiate them as shown below)
$.each($("select[multiple]"), function (key, selectbox) {
$("#" + selectbox.id).multiselect({
texts: {placeholder: $("#" + selectbox.id).attr("title")}
});
});
My saved data array is [1,3,4]
I need to set these saved data to the select box and check the check boxes without going through the loadOptions method.
You could use jQuery .filter() function on your select options to preselect those wanted before initializing the multiselect plugin.
Here,
$('option',this).filter((_,e) => saved_data.includes(+e.value)).prop('selected',true);
Preselects every option, before the .multiselect() call.
let saved_data = [1, 3, 4];
$('select[multiple]').each(function() {
$('option', this).filter((_, e) => saved_data.includes(+e.value)).prop('selected', true);
$(this).multiselect({
texts: {
placeholder: $(this).attr("title")
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://springstubbe.us/projects/demos/jquery-multiselect/scripts/index.js?1523890673"></script>
<link rel="stylesheet" href="https://springstubbe.us/projects/demos/jquery-multiselect/styles/index.css?1518818712">
<select name="abc" id="abc" multiple title="Test Number?">
<option value="1">Test 1</option>
<option value="2">Test 2</option>
<option value="3">Test 3</option>
<option value="4">Test 4</option>
<option value="5">Test 5</option>
</select>

Categories

Resources