How to set default selection based on another selection - javascript

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

Related

How to force a select to keep always the same selected value

Let's say we have multiple forms, each form has 40 selects, the ids of each select have the following structure:
#id_form-X-{field_name}
Let's say for example, of those 40 selects, we want 3 of them to be unmodifiable for each form when we change the value of the select, so it will always show the same selected value.
The 3 selects we want to change have the following field_name: ps2_0, ps2_1 and ps2_3.
So I'm looking for a generic solution that works for:
id_form-0-ps2_0
id_form-0-ps2_1
id_form-0-ps2_3
id_form-1-ps2_0
id_form-1-ps2_1
id_form-1-ps2_3
id_form-N-ps2_0
id_form-N-ps2_1
id_form-N-ps2_3
...
...
...
Dummy example:
<select name="cars" id="cars">
<option selected value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
If, for example, the user clicks on the select and selects, for example Saab, the select will show again the value selected by default: Volvo.
I cannot use the 'readonly' or 'disabled' properties for the selects.
What I've tried so far:
$(document).ready(function() {
var previous = "initial prev value";
$("select").on('click', function () {
previous = $(this).val();
}).change(function() {
$(this).val() = previous;
});
});
I'm trying to 'force' the changed select to keep the previous value but didn't work.
Simple Solution
Reset the value of select with initial value on change.
const selectDD = document.getElementById('cars');
const selectedNode = selectDD.value;
selectDD.onchange = (e) => {
selectDD.value = selectedNode;
}
<select name="cars" id="cars">
<option selected value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
Much Generic Solution
There should be some unique identifier to differentiate between nodes that can be changed and those to be kept unchanged. Here I have added an unchanged custom attribute to select. Pick thode nodes with that custom attribute and on change of that select, reset its value to initial value.
Example
const selectDD = document.querySelectorAll('[unchanged]');
selectDD.forEach((node) => {
node.attributes.initialValue = node.value;
node.onchange = (e) => {
e.target.value = node.attributes.initialValue;
}
})
You cant change this
<select name="cars" id="cars" unchanged>
<option selected value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
<br/>
You cant change this
<select name="gender" id="gender" unchanged>
<option selected value="male">Male</option>
<option value="female">female</option>
</select>
<br/>
You can change this
<select name="age" id="age">
<option selected value="10">10</option>
<option value="15">15</option>
</select>
If you use querySelectorAll to generate a nodelist of all the select menus you could assign a default attribute( using dataset here for instance) and set the value within an event listener so that this default attribute is always selected
document.querySelectorAll('form select').forEach( sel => {
sel.dataset.def=sel.options[sel.selectedIndex].value;
sel.addEventListener('change',function(e){
this.value=this.dataset.def
})
})
<form>
<select name='cars'>
<option selected value='volvo'>Volvo
<option value='saab'>Saab
<option value='mercedes'>Mercedes
<option value='audi'>Audi
</select>
<select name='fruit'>
<option selected value='apple'>Apple
<option value='banana'>Banana
<option value='mango'>Mango
<option value='plum'>Plum
</select>
</form>
Maintain an object which specifies the restricted Select items and the indexes they should always defaults to
let allowedIndexes = {
cars: 0,
bikes: 1
}
function preventChange(e) {
if (Object.keys(allowedIndexes).includes(e.currentTarget.id)) {
let fixedIndex = allowedIndexes[e.currentTarget.id];
e.currentTarget.selectedIndex = fixedIndex;
}
}
<select name="cars" id="cars" onChange="preventChange(event)">
<option selected value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
<select name="bikes" id="bikes" onChange="preventChange(event)">
<option value="honda">honda</option>
<option selected value="kavasaki">kavasaki</option>
<option value="suzuki">suzuki</option>
<option value="yamaha">yamaha</option>
</select>
It's somewhat uncomfortable when one's answer is copied.

Retrieving selected values in Materialize CSS multiple select using 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);
});
});

jquery "clear" value in select box

So I have some markup that looks like this, And some jQuery javascript:
let color_select = $('select#SelectByColor');
color_select.val([]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="SelectByColor" class='filter-select' name='color'>
<option value="">By color</option>
<option value="Red">Red</option>
<option value="Blue">Blue</option>
<option value="Green" selected="selected">Green</option>
<option value="Yellow">Yellow</option>
</select>
<button id="FilterReset">Reset</button>
That gets invoked when the "Reset" button is clicked. It pretty much works - when you
click the reset button. the Select box value gets set to "". BUT.. the visual display
of the select box is also set to blank, not "By color". Why is this the case?
In addition, according to the Chrome DevTools, the selected option is still Green.
Set the value to an empty string, not an array.
$("#FilterReset").click(function() {
let color_select = $('select#SelectByColor');
color_select.val("");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="SelectByColor" class='filter-select' name='color'>
<option value="">By color</option>
<option value="Red">Red</option>
<option value="Blue">Blue</option>
<option value="Green" selected="selected">Green</option>
<option value="Yellow">Yellow</option>
</select>
<button id="FilterReset">Reset</button>
The value you set for the selector in the .val(...) function to needs to match the value="..." in HTML. So that should be color_select.val( "" )
Here's a code that works and a codepen:
jQuery($ => {
$('#FilterReset').on('click', () => {
$("#SelectByColor").val("");
});
});

JQuery Set selected option

I have two selection boxes, the default value is - and i want to pick something else for both, my first problem is both fields have dynamic id like prod-685209-Size so i'm having trouble accessing with id.
I have the following HTML:
<select class="sku-attr" name="Size">
<option value="_def">-</option>
<option value="S">S</option>
<option value="M">M</option>
<option value="L">L</option>
<option value="XL">XL</option>
</select>
<select class="sku-attr" name="Color">
<option value="_def">-</option>
<option value="Black">Black</option>
<option value="Blue">Blue</option>
</select>
So i executed the following:
document.getElementsByTagName('select')[0].selectedIndex = 2
document.getElementsByTagName('select')[1].selectedIndex = 2
It worked on the front side, showing my new options but it didn't prompt the backend as it is not actually selecting the options. Backend works fine when i click to these options by hand, basically i need another solution to choose these options.
If I don't misunderstood your requirement then you need something like this. Just add two different ids to your select element and attach a change event listener. For example size and color
var s = document.getElementById("size");
var c = document.getElementById("color");
function getSize() {
sizeSelected = s.value;
console.log('size=' + sizeSelected);
}
function getColor() {
colorSelected = c.value;
console.log('color=' + colorSelected);
}
s.addEventListener('change', getSize);
c.addEventListener('change', getColor);
<select id="size" class="sku-attr" name="Size">
<option value="_def">-</option>
<option value="S">S</option>
<option value="M">M</option>
<option value="L">L</option>
<option value="XL">XL</option>
</select>
<select id="color" class="sku-attr" name="Color">
<option value="_def">-</option>
<option value="Black">Black</option>
<option value="Blue">Blue</option>
</select>
You need to add .validate() after your dom commands to actually prompt the page.

Swap default selected select options with pure Javascript

I have a select box as follows
<select>
<option value="yes">Yes</option>
<option value="No" selected="selected">No</option>
<option value="Maybe">Maybe</option>
<option value="So">So</option>
</select>
I would like
<select>
<option value="yes">Yes</option>
<option value="No">No</option>
<option value="Maybe" selected="selected">Maybe</option>
<option value="So">So</option>
</select>
*note default selection is now "Maybe" instead of "No"
I learned jquery before really getting comfortable with pure JavaScript. So im trying to learn it.
I would assign an id to the select element:
<select id="choices">
<option value="yes">Yes</option>
<option value="No" selected="selected">No</option>
<option value="Maybe">Maybe</option>
<option value="So">So</option>
</select>
Then, access the options via the standard options array on <select> elements:
var choices = document.getElementById('choices');
choices.options[2].selected = true;
You should assign an id to the select element then do this:
var s = document.getElementById( 'select_box' );
s.options[ 2 ].selected = true;

Categories

Resources