Selecting Item from First Select Box to Populate Second Select Box - javascript

I have a form with two select fields. The first select field will list items, the second select field will start empty but be populated by selecting an item from the first and pressing the add button. You would also be able to do the same. You can select an item from the second select field and hit the remove to add it back to the first select field. In the end, I want all the values of the second select field to be in a hidden form box separated by commas.
I've come across examples of this with javascript in the past, but now that I need them I can't seem to find them. Does anyone know of any sources that could show me how to accomplish something like this? At first, I was thinking of doing it using ajax but I would rather do it without loading another page. Any help in pointing me in the right direction would be greatly appreciated! Thanks in advance!
<form name="SelectItem">
<select name="SelectItem">
<option value="item1">Item 1</option>
<option value="item2">Item 2</option>
<option value="item3">Item 3</option>
</select>
<button>Add =></button>
<button><= Remove</button>
<select name="SelectedItems">
<option value=""></option>
</select>
</form>

You can use jquery append() to do it:
$(document).ready(function(){
$('.add').click(function(){
$('#select1').find('option:selected').appendTo('#select2');
});
$('.remove').click(function(){
$('#select2').find('option:selected').appendTo('#select1');
});
});
Working pen

You can use the add() and remove() methods on the select element:
const select1 = document.getElementById('select1')
const select2 = document.getElementById('select2')
const addItem = () => {
event.preventDefault();
if(select1.length === 0) return;
let itemIndex = select1.selectedIndex;
let item = select1.options[itemIndex];
select1.remove(itemIndex)
select2.add(item);
}
const removeItem = () => {
event.preventDefault();
if(select2.length === 0) return;
let itemIndex = select2.selectedIndex;
let item = select2.options[itemIndex];
select2.remove(itemIndex)
select1.add(item);
}
document.getElementById('addButton').addEventListener('click', addItem);
document.getElementById('removeButton').addEventListener('click', removeItem);
<form name="SelectItem">
<select name="SelectItem" id="select1">
<option value="item1">Item 1</option>
<option value="item2">Item 2</option>
<option value="item3">Item 3</option>
</select>
<button id="addButton">Add =></button>
<button id="removeButton"><= Remove</button>
<select name="SelectedItems" id="select2">
</select>
</form>

Below is one relatively simple approach you can take that takes advantage of event delegation technique:
const inSelectEl = document.querySelector('#in-item-list');
const outSelectEl = document.querySelector('#out-item-list');
const optionQuantity = inSelectEl.options.length;
const onClick = e => {
if (e.target.tagName !== 'BUTTON') {
return;
}
let a, b;
if (e.target.id === 'add') {
a = inSelectEl;
b = outSelectEl;
} else {
a = outSelectEl;
b = inSelectEl;
}
const selectedOption = a.options[a.selectedIndex];
b.options[b.options.length] = selectedOption;
}
document.querySelector('#container').addEventListener('click', onClick);
<!-- Added container to enable event delegation -->
<div id="container">
<select name="SelectItem" id="in-item-list">
<option value="item1">Item 1</option>
<option value="item2">Item 2</option>
<option value="item3">Item 3</option>
</select>
<button id="add">Add =></button>
<button id="remove"><= Remove</button>
<select name="SelectedItems" id="out-item-list" />
</div>

Related

How to refresh a select list in html

I have a drop-down list where depending on the selected value, the next drop-down list shows specific values. when changing the value of the first list and then going back to the old value, the second list does not update. keeps the same value selected before. How can I make the second list update to the value I marked as selected by default whenever I change the value of the first list?
I hope you guys were able to understand me, and I thank you for your time.
Here's the code:
<select onchange="showprd('hidevalue', this), showprd2('hidevalue2', this)">
<option value="" disabled selected hidden>Selecione</option>
<option value="0">São Francisco</option>
<option value="1">Bradesco</option>
</select>
<br>
<br>
<select hidden id="hidevalue">
<option value="" disabled selected hidden>Selecione o produto</option>
<option value="pleno">Pleno</option>
<option value="integrado">Integrado</option>
</select>
<select hidden id="hidevalue2">
<option value="" disabled selected hidden>Selecione o produto</option>
<option value="junior">Junior</option>
<option value="senior">Senior</option>
</select>
</body>
<script>
function showprd(id, elementValue) {
document.getElementById(id).style.display = elementValue.value == 0 ? 'block' : 'none';
}
function showprd2(id, elementValue) {
document.getElementById(id).style.display = elementValue.value == 1 ? 'block' : 'none';
}
</script>
TL;DR. Control the input value changes in one place.
Please see the updated snippet below. html structure hasn't been changed, but I've removed the inline js call and updated the id names. JavaScript blocks are commented in details.
In a nut-shell, this code listens for any change to the parent select dropdown. Whenever a change occurs, its child dropdowns will reset their values and toggle their visibility accordingly.
// Assign each dom element to a variable
const primarySelect = document.querySelector('#primary');
const childSelect1 = document.querySelector('#child1');
const childSelect2 = document.querySelector('#child2');
const defaultValues = document.querySelectorAll('.default');
function resetInputs() {
// Reset the child select options to default
defaultValues.forEach(option => option.selected = true);
}
function handlePrimary(e) {
// Reset the child select values whenever the parent value changes
resetInputs();
// `input` value is always a string. Here we're converting it to a number
const val = parseFloat(e.target.value);
// Toggle visibility of child select dropdowns
[childSelect1, childSelect2].
forEach((select, i) => select.style.display = val === i ? 'block' : 'none');
}
primarySelect.addEventListener('change', handlePrimary);
<select id="primary">
<option value="" disabled selected hidden>Selecione</option>
<option value="0">São Francisco</option>
<option value="1">Bradesco</option>
</select>
<br>
<br>
<select hidden id="child1">
<option class="default" value="" disabled selected hidden>Selecione o produto</option>
<option value="pleno">Pleno</option>
<option value="integrado">Integrado</option>
</select>
<select hidden id="child2">
<option class="default" value="" disabled selected hidden>Selecione o produto</option>
<option value="junior">Junior</option>
<option value="senior">Senior</option>
</select>
If I understood correctly, the expected behavior is when the second or third <select> is hidden, the <select> should go back to default (the first <option>?). If so, then remove disabled and hidden from the first <option> of the second and third <select> then add the following:
selectObj.hidden = true;
selectObj.selectedIndex = 0;
The example below has a <form> wrapped around everything (always use a form if you have more than one form control. By using HTMLFormElement interface I rewrote the code and can reference all form controls with very little code. Inline event handlers are garbage so don't do this:
<select id='sel' onchange="lame(this)">
Instead do this:
selObj.onchange = good;
OR
selObj.addEventListener('change', better)
Read about events and event delegation
const UI = document.forms.UI;
UI.onchange = showSelect;
function showSelect(e) {
const sel = e.target;
const IO = this.elements;
if (sel.id === "A") {
if (sel.value === '0') {
IO.B.hidden = false;
IO.C.hidden = true;
IO.C.selectedIndex = 0;
} else {
IO.B.hidden = true;
IO.B.selectedIndex = 0;
IO.C.hidden = false;
}
}
}
<form id='UI'>
<select id='A'>
<option disabled selected hidden>Pick</option>
<option value="0">0</option>
<option value="1">1</option>
</select>
<br>
<br>
<select id="B" hidden>
<option selected>Pick B</option>
<option value="0">0</option>
<option value="1">1</option>
</select>
<select id="C" hidden>
<option selected>Pick C</option>
<option value="0">0</option>
<option value="1">1</option>
</select>
</form>
I give you an example for your reference:
let secondList = [
[{
value: "pleno",
text: "Pleno"
},
{
value: "integrado",
text: "Integrado"
}
],
[
{
value: "junior",
text: "Junior"
},
{
value: "senior",
text: "Senior"
}
]
]
function update(v){
let secondSelectBox=document.getElementById("second");
secondSelectBox.style.display="none";
let optionList=secondList[v.value];
if (optionList){
let defaultOption=new Option("Selecione o produto","");
secondSelectBox.innerHTML="";
secondSelectBox.options.add(defaultOption);
optionList.forEach(o=>{
let vv=new Option(o.text,o.value);
secondSelectBox.options.add(vv);
})
secondSelectBox.style.display="block";
}
}
<select onchange="update(this)">
<option value="" disabled selected hidden>Selecione</option>
<option value="0">São Francisco</option>
<option value="1">Bradesco</option>
</select>
<select hidden id="second">
</select>

Hide submit button based on select with multiple classes

I have a form with 4 dependent select dropdowns. What I want is, to hide/disable the submit button until option from the last select is chosen.
const select = document.getElementsByClassName("f_select f_select_product_cat f_select_product_cat_3")[0];
const submitButton = document.querySelectorAll(".button, .woof_submit_search_form");
document.getElementsByClassName("f_select f_select_product_cat f_select_product_cat_3")[0].addEventListener('change', () => {
if (select.value === '0') {
submitButton.disabled = true;
} else {
submitButton.disabled = false;
}
});
<select class="f_select f_select_product_cat f_select_product_cat_0" name="product_cat">
<option value="0">Select cat 1</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
<select class="f_select f_select_product_cat f_select_product_cat_1" name="product_cat">
<option value="0">Select cat 2</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
<select class="f_select f_select_product_cat f_select_product_cat_2" name="product_cat">
<option value="0">Select cat 3</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
<select class="f_select f_select_product_cat f_select_product_cat_3" name="product_cat">
<option value="0">Select cat 4</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
<button class="button f_submit_search_form">SEARCH</button>
I don't have much control over form rendering, so my best option is to get both the button and the last select by class name, but as you can see they have multiple classes.
Tried also to get the select with getElementsByName("product_cat")[0] but also doesn't make it to work.
Any help appreciated.
The first issue I see is that you're setting the submitButton to disabled when the value is 0. But you perform that verification only when the value of it changes as you listen to change.
You have only one button, why would you use document.querySelectorAll to retrieve it? Simply uses querySelector. More than that, it is an issue here as you are trying to set a NodeList to disabled = true and not an element! For you to understand, here are both output.
querySelectorAll
NodeList [button.button.f_submit_search_form, disabled: true]
0: button.button.f_submit_search_form
Excellent, we now see why it did not work! We are trying to set disabled = true to a NodeList which form is similar to an array!
So, in our case, we just need one element, so we can just fix that by using querySelector.
querySelector
<button class="button f_submit_search_form" disabled="">SEARCH</button>
That looks much more like what we need: the button alone.
And now, our .disabled makes sense and works!
const select = document.getElementsByClassName("f_select f_select_product_cat f_select_product_cat_3")[0];
const submitButton = document.querySelector(".button, .woof_submit_search_form");
select.addEventListener("change", () => {
if (select.value === '0') {
submitButton.disabled = true
} else {
submitButton.disabled = false
}
})
That logic has a little flaw though: we are only setting submitButton to be displayed when the addEventListener occurs.
So we need in the HTML to add disabled by default, as per default, it will for sure not be set to anything else than default value.
<button class="button f_submit_search_form" disabled>SEARCH</button>
It now works, the button will be enabled ONLY if the last field value is anything else than 0.

How to switch between HTML Select options with js

I have a HTML select with 3 options as following -
<select id="list">
<option value="environment" selected>Environment Facing (default)</option>
<option value="user">User Facing</option>
<option value="member">Member Facing</option>
</select>
what I want to do is to toggle between these values with a button. is that possible? How can I toggle like if first option is selected and if I click button second option get selected and if second is selected after clicking again third gets selected. is there any way I can do it.
One approach could be getting the available values into an array, and finding the currently selected value's index in that array, increase it by one and see if you get a value. If you get undefined (which is what you get if you try to access an array element at a non-existing index), you instead go with the arrays's first element.
const list = document.getElementById('list');
const values = [...list.options].map(({value}) => value);
document.getElementById("button").addEventListener("click", function() {
const currentValue = list.value;
list.value = values[values.indexOf(currentValue)+1] ?? values[0];
});
<select id="list">
<option value="environment" selected>Environment Facing (default)</option>
<option value="user">User Facing</option>
<option value="member">Member Facing</option>
</select>
<button id="button" type="button">Toggle</button>
Increment the selectedIndex of the select, wrapping around when you get to the end.
document.getElementById("button").addEventListener("click", function() {
let list = document.getElementById("list");
let selected = list.selectedIndex;
selected = (selected + 1) % list.length;
list.selectedIndex = selected;
});
document.getElementById("show").addEventListener("click", function() {
let list = document.getElementById("list");
console.log(`Selected = ${list.value}`);
});
<select id="list">
<option value="environment" selected>Environment Facing (default)</option>
<option value="user">User Facing</option>
<option value="member">Member Facing</option>
</select>
<button id="button" type="button">Toggle</button>
<button id="show" type="button">Show selected</button>

How do I disable, hide, or remove selected option in other selects with the same options?

I'm writing a form with 4 <select> elements. They all have the same options and I would like to disable, hide, or remove the selected option from one <select> in the other <select> elements with the same options in order to prevent the user to select the same option in multiple <select> elements.
No jQuery, only plain JavaScript please.
If possible I would like the first option to always display in all <select> elements:
<option class="select-items" selected>Sélectionnez..</option>
Here is the HTML for one <select>:
<select class="custom-select mb-3" id="name_typage_0">
<option class="select-items" selected>Sélectionnez..</option>
<option class="select-items" value="designation">Désignation</option>
<option class="select-items" value="email">Email</option>
<option class="select-items" value="ville">Ville</option>
<option class="select-items" value="secteur_activite">Secteur d'activité</option>
</select>
Here is part of my JavaScript:
const custSelec = document.querySelectorAll('.custom-select');
custSelec.forEach(function(item){
item.addEventListener('change', function(){
if(item.options[item.selectedIndex].text == 'Sélectionnez..'){
count = -1;
}else{
count = 1;
total += count;
compteur.textContent = ` ${total}/${custSelec.length -1}`;
In your change event listener, you can get the current set of selected values from all <select> elements in the group, and then loop through each element's options to both disable the options currently selected elsewhere in the group as well as re-enable any options that were previously selected but have since been changed. You can avoid disabling the first "label" option in each of your selects by checking the value before disabling / enabling options.
You could use this same approach to hide or remove options keeping in mind that there are some browser compatibility issues when trying to hide <option> elements and that you would need some additional code to store the complete list of options if you were going to remove and restore them.
const selects = document.querySelectorAll('.select-group');
selects.forEach((elem) => {
elem.addEventListener('change', (event) => {
const values = Array.from(selects).map((select) => select.value);
for (const select of selects) {
select.querySelectorAll('option').forEach((option) => {
const value = option.value;
if (value && value !== select.value && values.includes(value)) {
option.disabled = true;
} else {
option.disabled = false;
}
});
}
});
});
<select class="select-group">
<option value="">Select...</option>
<option value="first">First Value</option>
<option value="second">Second Value</option>
<option value="third">Third Value</option>
</select>
<select class="select-group">
<option value="">Select...</option>
<option value="first">First Value</option>
<option value="second">Second Value</option>
<option value="third">Third Value</option>
</select>
<select class="select-group">
<option value="">Select...</option>
<option value="first">First Value</option>
<option value="second">Second Value</option>
<option value="third">Third Value</option>
</select>
Thanks a lot for your help! I added a small 'if' to fix my bug and it works perfectly (until the next bug ^^):
if(value !== ""){
option.disabled = true;
}
Or I could just :
if (value && value !== select.value && values.includes(value) && value !== "") {
option.disabled = true;
}
Another difficulty when you begin : learn to write simple code ^^z

JavaScript - Dropdown value dependent

I have two dropdown right now. I want to when the user selects "NO" the other automatically selects "YES" and vice versa.
I'm assuming I use JS here to make this occur, but not sure where to start. Below is my dropdown html code. If someone could help me get started, it would be helpful.
Code:
<div class="cmicrophone" id="cmicrophone">Currently:
<select id="cmicrophone" name="cmicrophone">
<option value=" " selected = "selected"> </option>
<option value="on">ON</option>
<option value="off">OFF</option>
</select>
</div>
<div class="microphone" id="microphone">Microphone:
<select id="microphone" name = "microphone">
<option value=" " selected="selected"> </option>
<option value="on" >ON</option>
<option value="off">OFF</option>
</select>
</div
You can assign a same class to each select element and bind change event listener.
$('.elem').on('change', function() {
if ($(this).val() == 'on') {
$('.elem').not(this).val('off');
} else {
$('.elem').not(this).val('on');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="cmicrophone" id="cmicrophone">Currently:
<select id="cmicrophone" class='elem' name="cmicrophone">
<option value="" selected = "selected"></option>
<option value="on">ON</option>
<option value="off">OFF</option>
</select>
</div>
<div class="microphone" id="microphone">Microphone:
<select id="microphone" class='elem' name="microphone">
<option value="" selected = "selected"></option>
<option value="on">ON</option>
<option value="off">OFF</option>
</select>
</div>
A good starting point might be listening for changes on one select, and when the change happens, selecting the other <select> and setting the right value
Here's a vanilla JS solution (no jquery required).
The idea here is to:
select both <select> elements and save them into variables to refer to later using document.querySelector
add input event listeners on both elements that call a function to handle the event
then use inside the function selectElement.selectedIndex to check the selected index of one element and use that to set the value of the other.
// select the `<select>` elements
const cmicrophone = document.querySelector('#cmicrophone');
const microphone = document.querySelector('#microphone');
// define function to handler the events
function inputHandler(thisSelect, otherSelect) {
if (thisSelect.selectedIndex == 1) {
otherSelect.selectedIndex = 2;
} else if (thisSelect.selectedIndex == 2) {
otherSelect.selectedIndex = 1;
} else {
thisSelect.selectedIndex = 0;
otherSelect.selectedIndex = 0;
}
}
// add event listeners that will 'fire' when the input of the <select> changes
cmicrophone.addEventListener('input', event => {
inputHandler(cmicrophone, microphone);
});
microphone.addEventListener('input', event => {
inputHandler(microphone, cmicrophone);
});
<div>Currently:
<select id="cmicrophone" name="cmicrophone">
<option value=" " selected = "selected"> </option>
<option value="on">ON</option>
<option value="off">OFF</option>
</select>
</div>
<div>Microphone:
<select id="microphone" name="microphone">
<option value=" " selected="selected"> </option>
<option value="on" >ON</option>
<option value="off">OFF</option>
</select>
</div>
One more thing to add: You assigned the same value to multiple ids. You should only assign one unique id per element.

Categories