Two Drop Down Menus - javascript

I wish I could use jQuery, but this has to in JavaScript. I'd appreciate the help.
When "empty" (first drop down menu) is selected, I need all values from the second drop down menu (a, b, c).
When "1" is selected, I need just a, b.
When "2" is selected, I need just b, c.
Nothing's wrong with the drop down menu. Just had to change the values. How would I fix this in JavaScript?
First menu
<onchange="first(this);>
<option value="empty"></option>
<option value="1">1</option>
<option value="2">2</option>
Second menu
<id="second">
<option value="a">a</option>
<option value="b">b</option>
<option value="c">c</option>

One solution that I would prefer is to set the style to none via CSS in JS. This way, the element still exists but it is just hidden from the viewer.
You can the get value of an element via [element-here].value and compare the to some value that you want. From there, you would select the second drop down option value you have and run [element-here].style.display = "none"
Another way that is more complicated that I would not recommend is to create and destroy elements entirely. Something like:
var x = document.createElement("option");
x.value = VALUE HERE;
parent.appendChild(document.createTextNode("TEXT HERE"))

This is a bit sloppy, but here's one way to do it. You have an array of data with the valid secondary values per primary value. Then you render them each time the primary list changes.
let dropdownlist = [];
dropdownlist[1] = ['a', 'b', 'c'];
dropdownlist[2] = ['b', 'c'];
let select = document.createElement('select');
document.getElementById('myItemList').appendChild(select);
let x = 1;
document.getElementById('firstddl').addEventListener('change', (e) => {
//console.log(e.target.value);
x = e.target.value;
select.innerHTML = '';
renderDDL(dropdownlist, x)
});
function renderDDL(dropdownlist, x) {
dropdownlist[x].forEach(function(item) {
let option = document.createElement('option');
select.appendChild(option);
option.innerHTML += item;
});
}
renderDDL(dropdownlist, x); // Runs once
<select id="firstddl">
<option value=1>1</option>
<option value=2>2</option>
</select>
<div id="myItemList">
</div>

Related

move option from one select to another select with JS

From two html selects, I would like to move when I click the button to move an option to another select with javascript vanila, and when it has been moved, it is removed from the select from where it was at the beginning. It should also work the other way around.
function move1() {
var x = document.getElementById("select1");
}
function move2() {}
<select id="select1">
<option value="0">1</option>
<option value="0">2</option>
<option value="0">3</option>
</select>
<button type="button" onclick="move1()">>></button>
<button type="button" onclick="move2()"><<</button>
<select id="select2"></select>
You can do it like this:
Fetch both selects with getElementById() and store them in select_1 and select_2 variables.
Check if selected option exists by compering selectedIndex property of the select with -1. It will be equal to -1 only if the user didn't select anything.
If selectedIndex is equal to -1, then do nothing because there is nothing to transfer to second select.
If selectedIndex is different from -1, it means that user selected something and option with that index should be transfered.
Create new option for second select with document.createElement('option') and copy the selected option values to the new option.
Remove the selected option of current select with select.options.remove(select.selectedIndex)
function move1() {
const select_1 = document.getElementById("select1");
const select_2 = document.getElementById("select2");
if(select_1.selectedIndex !== -1) {
const selected_option = select_1.options[select_1.selectedIndex];
let new_option = document.createElement('option');
new_option.value = selected_option.value
new_option.innerHTML = selected_option.innerHTML;
select_2.appendChild(new_option);
select_1.options.remove(select_1.selectedIndex)
}
}
function move2(){
const select_1 = document.getElementById("select1");
const select_2 = document.getElementById("select2");
if(select_2.selectedIndex !== -1) {
const selected_option = select_2.options[select_2.selectedIndex];
let new_option = document.createElement('option');
new_option.value = selected_option.value
new_option.innerHTML = selected_option.innerHTML;
select_1.appendChild(new_option);
select_2.options.remove(select_2.selectedIndex)
}
}
<select id="select1">
<option value="0">1</option>
<option value="0">2</option>
<option value="0">3</option>
</select>
<button type="button" onclick="move1()">>></button>
<button type="button" onclick="move2()"><<</button>
<select id="select2"></select>
Here's a version that can manage more than 2 sets of <select> and <button> pairs. If there are more than 2 pairs, all recieving <select> will add the selcted <option>. In the HTML a data-* attribute is added to each <option>:
<option data-idx="0" value='1'>1</option>
<option data-idx='1' value="2">2</option>
<option data-idx='2' value="3">3</option>
The value of data-idx is the <option>s original index position. In the event handler switchOPt(e) the data-idx value will be used to determine what index it should be placed in:
to.add(copy, +copy.dataset.idx);
All details are commented in the example.
/*
Collect all buttons into a HTMLCollection then convert it
into an Array. Same with all select
*/
const btnArray = [...document.querySelectorAll('button')];
const selArray = [...document.querySelectorAll('select')];
/*
Iterate through the array of buttons. Register each button
to the click event. The event handler is switchOpt(e)
*/
btnArray.forEach(btn => btn.addEventListener('click', switchOpt));
// Event handler always passes the Event Object
function switchOpt(e) {
/*
Determine the select that will send it's option by
matching it's #id vs this.name (the [name] of the button
the user clicked
*/
const from = document.getElementById(this.name);
// if the select doesn't have any options end function
if (from.childElementCount < 1) return;
/*
Determine the select that adds an option by .filter()
under the condition that it is NOT >from<
*/
let to = selArray.filter(sel => sel.id != from.id);
// Rereference >to< to be the select with the array
to = to[0];
// Determine which option has been selected
const opt = from.options[from.selectedIndex];
// Make a copy of the selected option
const copy = opt.cloneNode(true);
/*
Add >copy< to >to< the second parameter is the index
of the element that >copy< will be placed before it so
it'll always be in order
*/
to.add(copy, +copy.dataset.idx);
// Remove the option from >from<
opt.remove();
}
<!-- Assign each option a data attribute wuth the value
of it's index -->
<select id="A">
<option data-idx='0' value="1">1</option>
<option data-idx='1' value="2">2</option>
<option data-idx='2' value="3">3</option>
</select>
<button name='A' type="button">>></button>
<button name='B' type="button"><<</button>
<select id="B"></select>

How to select all options within an optgroup?

I am wondering what the easiest way to select all options within a single optgroup is?
My understanding is that optgroup labels themselves cannot be selected, so my current implementation has an option element immediately following each optgroup label that says something like "All Options in this optgroup". I'm able to detect the event when this "All" option is selected, but I'm lost after that point. Is this the right path to head down, or am I making this harder than it needs to be?
Use the attribute selector:
'[attribute name = "value"]'
const groupA = document.querySelector('[label="A"]');
/*
Using .querySelectorAll() to collect all of optgroup A options into a NodeList
*/
const groupA = document.querySelector('[label="A"]');
const allOptA = groupA.querySelectorAll('option');
allOptA.forEach(opt => opt.style.color = 'tomato')
/*
Using .children and spead operator [...x] to get all options from optgroup B
into an Array
*/
const groupB = document.querySelector('[label="B"]');
const allOptB = groupB.children;
[...allOptB].forEach(opt => opt.style.color = 'lime');
// Gather all optgroups into an Array
const allGroups = [...document.querySelectorAll('optgroup')];
// Gather each optgroups' options into a sub-array
const allOpts = allGroups.flatMap(grp => [grp.querySelectorAll('option')]);
// Get the value of the first optgroup third option
console.log(allOpts[0][2].value);
<select>
<optgroup label='A'>
<option value='0'>0</option>
<option value='2'>2</option>
<option value='4'>4</option>
</optgroup>
<optgroup label='B'>
<option value='1'>1</option>
<option value='3'>3</option>
<option value='5'>5</option>
</optgroup>
</select>

There is a way to get all the option values in the SELECT TAG without an ID?

do you know if there is a way to take all the values in the OPTION VALUE included in a SELECT?
i Will show you an example, I have this code:
<SELECT onChange="chData(this,this.value)">
<OPTION VALUE=MIPS1 >MIPS
<OPTION VALUE=MSU1 >MSU
<OPTION VALUE=PERCEN1 >% CEC
<OPTION VALUE=NUMGCP1 >nCPU
</SELECT>
I only know the first value which is MIPS1, and I need to take the other values. The is a way to write that if I know the first MIPS1 I will search for the other values Included from the ?
Thanks in advance :)
You can get the <select> element that has an option with a specific value using something like this:
const select = document.querySelector('option[value=MIPS1]').closest('select');
Once you have the <select> element you can retrieve it's options using something like this:
const options = select.querySelectorAll('option');
Or:
const options = select.options;
As #charlietfl mentioned, .closest is not supported by all browsers, instead of that, you could use .parentElement.
jQuery version
var opt = "MIPS1";
const $sel = $("option[value='"+opt+"']").parent()
const options = $("option",$sel).map(function() { return this.value }).get()
console.log(options);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<SELECT onChange="chData(this,this.value)">
<OPTION VALUE=MIPS1>MIPS
<OPTION VALUE=MSU1>MSU
<OPTION VALUE=PERCEN1>% CEC
<OPTION VALUE=NUMGCP1>nCPU
</SELECT>
The example below shows how you can do this. The Jquery is fully commented.
Let me know if it isn't what you were hoping for.
Demo
// Create array
var options = [];
// Load option value you're looking for into a variable
var search_term = "MIPS1";
// Find option with known value, travel up DOM tree to select and then find all options within it
$("option[value='" + search_term + "']").closest("select").find("option").each(function() {
// Add values to array
options.push($(this).val());
});
// Print the array
console.log(options);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<SELECT onChange="chData(this,this.value)">
<OPTION VALUE=MIPS1>MIPS
<OPTION VALUE=MSU1>MSU
<OPTION VALUE=PERCEN1>% CEC
<OPTION VALUE=NUMGCP1>nCPU
</SELECT>
I think it is a bad idea not to give id to your html element in the first place, however if you need to do it that way, then the code below assumes you have only one select tag on your page.
let select = document.querySelector('select');
options = select.childNodes.filter((c) => c.tagName==='OPTION')
.map((o) => o.value);
console.log(options)
This will help you get: selected value, selected text and all the values in the dropdown.
$(document).ready(function(){
$("button").click(function(){
var option = $('option[value="MIPS1"]');
var select = option.parent();
var value = $(select).find(":selected").val();
var optionName = $(select).find(":selected").text();
var result = "value = "+value+"\noption name = "+optionName+"\nall values = ";
$(select).each(function(){
result+=($(this).text()+" ");
});
console.log(result);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select>
<option value=MIPS1 >MIPS</option>
<option value=MSU1 >MSU</option>
<option value=PERCEN1 >% CEC</option>
<option value=NUMGCP1 >nCPU</option>
</select>
<button>click</button>

How to populate select options from an array based on a select value?

Trying to get my second select element's options to populate from an array based on the value of the first select element. I can't seem to understand why it only populates the items from the array of the first select element. I know the appendChild is causing the items to keep tacking on at the need, but I've tried to clear the variables, but it seems the option elements that were created stay.
Any help would be great, thanks!
<select id="makeSelect" onChange="modelAppend()">
<option value="merc">Mercedes</option>
<option value="audi">Audi</option>
<option value="bmw">BMW</option>
</select>
<select id="modelSelect">
</select>
<script>
var audiModels = ["TT", "R8", "A4", "A6"]; //audimodels
var mercModels = ["C230", "B28", "LTX",]; //mercmodels
var bmwModels = ["328", "355", "458i",]; //bmwmodels
var selectedMake = document.getElementById("makeSelect"); //grabs the make select
var selectedModel = document.getElementById("modelSelect"); //grabs the model select
var appendedModel = window[selectedMake.value + "Models"]; // appends "Models" to selectedMake.value and converts string into variable
function modelAppend() {
for (var i = 0; i < appendedModel.length; i ++) { // counts items in model array
var models = appendedModel[i]; // // sets "models" to count of model array
var modelOptions = document.createElement("option"); //create the <option> tag
modelOptions.textContent = models; // assigns text to option
modelOptions.value = models; // assigns value to option
selectedModel.appendChild(modelOptions); //appeneds option tag with text and value to "modelSelect" element
}
}
</script>
This line is fishy:
var appendedModel = window[selectedMake.value + "Models"];
You need to get the element when the value has changed, not on page load. Then you need to remove the options on change too, or you will get a very long list if the user selects multiple times. Use an object to store the arrays, that makes it much easier to access them later. Also better use an event listener instead of inline js (though that's not the main problem here).
Try below code:
let models = {
audiModels: ["TT", "R8", "A4", "A6"],
mercModels: ["C230", "B28", "LTX"],
bmwModels: ["328", "355", "458i"]
}
document.getElementById('makeSelect').addEventListener('change', e => {
let el = e.target;
let val = el.value + 'Models';
let appendTo = document.getElementById('modelSelect');
Array.from(appendTo.getElementsByTagName('option')).forEach(c => appendTo.removeChild(c));
if (!models[val] || !Array.isArray(models[val])) {
appendTo.style.display = 'none';
return;
}
models[val].forEach(m => {
let opt = document.createElement('option');
opt.textContent = opt.value = m;
appendTo.appendChild(opt);
});
appendTo.style.display = '';
});
<select id="makeSelect">
<option value=""></option>
<option value="merc">Mercedes</option>
<option value="audi">Audi</option>
<option value="bmw">BMW</option>
</select>
<select id="modelSelect" style="display:none">
</select>

Accessing several form options

How do I access several option values in a form, under two different select ids, with JavaScript?
Here's the code: (JSFiddle: http://jsfiddle.net/sebastianonline/9yL4rv6j/)
(HTML5)
Select your favorite fruit:
<select id="mySelect">
<option value="apple">Apple</option>
<option value="orange">Orange</option>
<option value="pineapple">Pineapple</option>
<option value="banana">Banana</option>
</select>
Click the button to return the value of the selected fruit.
Pick a product
Amount
<label><strong>Amount:</strong></label>
<select id="amount">
<option selected>1</option>
<option>2</option>
<option>3</option>
</select>
<!-- text value here -->
<p id="include"></p>
<p id="include2"></p>
(JavaScript)
function mySelect()
{
var x = document.getElementById("mySelect").selectedIndex;
var p = document.getElementsByTagName("option")[x].value;
document.getElementById("include").innerHTML = p;
}
function myAmount()
{
var a = document.getElementById("amount").selectedIndex;
var b = document.getElementsByTagName("option")[a].value;
document.getElementById("include2").innerHTML = b;
}
Function mySelect() is able to pick the right option value and insert it in the first paragraph, however, the second function (myAmount()) is picking the same options as the first function, even though its id points to select id="amount". I need the second function to pick the options in select id="amount" and print it in p id="include2".
You are using document.getElementsByTagName("option"), which returns all option elements in the document, not all options for the current select. Which of course means your indexing is out.
But you can get the selected option's value in a given select element using the .value property of the select element itself:
function mySelect() {
var x = document.getElementById("mySelect").value;
document.getElementById("include").innerHTML = x;
}
function myAmount() {
document.getElementById("include2").innerHTML =
document.getElementById("amount").value;
}

Categories