I am trying to create 2 drop down menus, where the first list is linked to the second list (the second list is updated each time I select something in the first one).
I have some code that works, but it seems a little bit confusing to me.
Also this is working only if the script is in the body. If I move it to the head it doesnt work.
Why?
Can the same thing be implemented in some other way for example with the use of a 2d array, with the use on only Javascript?
var sel1 = document.querySelector('#sel1');
var sel2 = document.querySelector('#sel2');
var options2 = sel2.querySelectorAll('option');
function giveSelection(selValue) {
sel2.innerHTML = '';
for (var i = 0; i < options2.length; i++) {
if (options2[i].dataset.option === selValue) {
sel2.appendChild(options2[i]);
}
}
}
giveSelection(sel1.value);
<h1><b>Title</b></h1>
<select id="sel1" onchange="giveSelection(this.value)">
<option value="0"></option>
<option value="a">a</option>
<option value="b">b</option>
</select>
<select id="sel2">
<option data-option="a">apple</option>
<option data-option="a">airplane</option>
<option data-option="b">banana</option>
<option data-option="b">book</option>
</select>
Yes... It should not work. because when the script is in the head section. #self1 object and the #sel2 DOM elements are not on the DOM when it executes. when It's in the body section DOM elements are created on the DOM. one way to make it work is to bring those element referencing variables inside of the function as below.
function giveSelection(selValue) {
var sel1 = document.querySelector('#sel1');
var sel2 = document.querySelector('#sel2');
var options2 = sel2.querySelectorAll('option');
sel2.innerHTML = '';
for (var i = 0; i < options2.length; i++) {
if (options2[i].dataset.option === selValue) {
sel2.appendChild(options2[i]);
}
}
}
And believe me, It is not an efficient way. It's a best practice to include javascript to the bottom of the page and CSS to the top of the page. Including your script in the bottom of the body section is alright.
In order to use that script from head section you need to use window.onload that will fired when the DOM is ready.
In your case you can do something like that:
<head>
<script>
const load = () => {
sel1 = document.querySelector('#sel1');
sel2 = document.querySelector('#sel2');
options2 = sel2.querySelectorAll('option');
giveSelection(sel1.value);
}
function giveSelection(selValue) {
sel2.innerHTML = '';
for (var i = 0; i < options2.length; i++) {
if (options2[i].dataset.option === selValue) {
sel2.appendChild(options2[i]);
}
}
}
window.onload = load;
</script>
</head>
codepen
Related
function populateList(givenID)//givenID from the select tag
{
var select = document.getElementById("givenID"),
listData = ["1","2"];
for(var i = 0; i < listData.length; i++)
//Loops through array and creates a new DOM node and appends array contents to the object
{
var option = document.createElement("OPTION"),
txt = document.createTextNode(listData[i]);
option.appendChild(txt);
option.setAttribute("value",listData[i]);
select.insertBefore(option,select.lastChild);
}
}
<body >
<select id="slt" whenpageloads="populateList">
<!--When the page loads the select tag will be populated -->
<option>
default
</option>
</select>
</body>
You can call onload like Arun has mentioned on body load.
<body onload="populateList('slt')">
or
This will be better choice if you want to load more than one select boxes.
window.onload = function() {
populateList('slt');
};
Apart from that there was one more mistake in your code, as givenID is variable.
var select = document.getElementById(givenID);
instead of
var select = document.getElementById("givenID");
function populateList(givenID)//givenID from the select tag
{
var select = document.getElementById(givenID);
listData = ["1","2"];
for(var i = 0; i < listData.length; i++)
{
var option = document.createElement("OPTION"),
txt = document.createTextNode(listData[i]);
option.appendChild(txt);
option.setAttribute("value",listData[i]);
select.insertBefore(option, select.lastChild);
}
}
window.onload = function() {
populateList('slt');
};
<body>
<select id="slt">
<option>
default
</option>
</select>
</body>
i have array data it call "provinsi" i got array on console like normal array
here's my code
<select id="select">
<option value="default">default</option>
</select>
<script>
console.log(provinsi)
var select = document.getElementById("select");
for(var i = 0; i < provinsi.length; i++)
{
var option = document.createElement("option"),
txt = document.createTextNode(provinsi[i]);
option.appendChild(txt);
option.setAttribute("value",provinsi[i]);
select.insertBefore(option,select.lastChild);
}
</script>
but i got result like this
here's my console "provinsi"
any suggest ? thanks before
I believe the DOM is not ready yet.
Try putting your code inside IIFE.
(function() {
// the DOM will be available here
console.log(provinsi)
var select = document.getElementById("select");
for(var i = 0; i < provinsi.length; i++)
{
var option = document.createElement("option"),
txt = document.createTextNode(provinsi[i]);
option.appendChild(txt);
option.setAttribute("value",provinsi[i]);
select.insertBefore(option,select.lastChild);
}
})();
** Just to clarify as #karthick mentioned, make sure the script is loaded at the end of the body tag.
I hope this will work happy coding :) Note: change your provinces array with orginal values
$(document).ready(()=> {
let provinces = ["test1", "test2", "test3", "test4" ]
$.each(provinces, function(key,item) {
$("#select").append(new Option(item, key));
});
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="select">
<option value="default">default</option>
</select>
The DOM may not have finished loading when your script is run. You should run your function on DOMContentLoaded.
<select id="select">
<option value="default">default</option>
</select>
<script>
var provinsi = ["test1", "test2"];
document.addEventListener("DOMContentLoaded", function(event) {
//DOM fully loaded and parsed
var select = document.getElementById("select");
for(var i = 0; i < provinsi.length; i++)
{
var option = document.createElement("option"),
txt = document.createTextNode(provinsi[i]);
option.appendChild(txt);
option.setAttribute("value",provinsi[i]);
select.insertBefore(option,select.lastChild);
}
});
</script>
<script>
</script>
You can use jquery each function for looping
Javascript Code:
var makers = [
{id: 1, name: 'Toyota'},
{id: 2, name: 'Nissan'},
{id: 3, name: 'Honda'}
]
$.each(makers, function (index, item) {
$('#makers-listing').append(`<option value="${item.id}">${item.name}</option>`);
});
Html Code:
<select id="makers-listing">
<option>Select Maker</option> <!-- This is default value -->
</select>
I have an HTML page in which I have 2 selects.
<select id="field" name="field" onchange="checkValidOption();">
<option />
<option value="Plugin ID">Plugin ID</option>
<option value="Name">Name</option>
</select>
<select id="operator" name="operator" onchange="checkValidOption();">
<option />
<option value="EQUALS">EQUALS</option>
<option value="CONTAINS">CONTAINS</option>
<option value="NOT CONTAINS">NOT CONTAINS</option>
<option value="REGEX">REGEX</option>
</select>
What I'd like to happen is that checkValidOption() could make it so that if "Plugin ID" is selected in field that the only option is EQUALS (and it's selected) and otherwise all the other options are available. Any idea on how to approach this?
I tried changing the innerHTML of the operator select in JS:
document.getElementById("operator").innerHTML =
"<option value='EQUALS'>EQUALS</option>";
However this results in an empty select (this would also include manually setting the many options for going back to having all the ones listed above).
I can't think of another solution, any help would be greatly appreciated.
Try this:
Demo here
var field = document.getElementById('field');
var operator = document.getElementById('operator');
field.onchange = function () { fieldcheck(); }
operator.onchange = function () { fieldcheck(); }
fieldcheck();
function fieldcheck() {
if (field.value == 'Plugin ID') {
for (i = 0; i < operator.options.length; ++i) {
if (operator.options[i].value != 'EQUALS') {
operator.options[i].disabled = true;
}
};
operator.value = 'EQUALS';
} else {
for (i = 0; i < operator.options.length; ++i) {
operator.options[i].disabled = false;
};
}
}
To manipulate options when Plugin ID was selected:
function checkValidOption(){
var x=document.getElementById("field");
var y=document.getElementById("operator");
if (x.options[1].selected === true){
document.getElementById("operator").options[1].selected = true;
for(var i=0; i<y.length; i++){
if (i !== 1){
//disabling the other options
document.getElementById("operator").options[i].disabled = true;
}
}
}
else{
for(var i=0; i<y.length; i++){
//enabling the other options
document.getElementById("operator").options[i].disabled = false;
}
}
}
Here's a link to fiddle
A select field doesn't use the innerHTML method, you need to use value.
document.getElementById("operator").value = "...";
heres a jquery solution.
every time the first select changes, it produces new options from an array for the 2nd select. issue here is i had to change the option values of the first select to 0 and 1 to select which value in the array, you can manipulate those later if you are storing this info somewhere
http://jsfiddle.net/2TZJh/
$(document).ready(function() {
$("#field").change(function() {
var val = $(this).val();
$("#operator").html(options[val]);
});
var options = [
'<option value="EQUALS">EQUALS</option>',
'<option></option><option value="EQUALS">EQUALS</option><option value="CONTAINS">CONTAINS</option> <option value="NOT CONTAINS">NOT CONTAINS</option> <option value="REGEX">REGEX</option>'
];
});
I'm trying to build a two tier drop down menu where the second drop down populates the second. I've found a lot of examples on the site but I want my menu to redirect to a page after the second menu is selected and can't figure that bit out.
I'm not that up to speed with JS so please bear with me.
The code below is an example from another post:
<script type="text/javascript">
function configureDropDownLists(ddl1,ddl2) {
var colours = new Array('Black', 'White', 'Blue');
var shapes = new Array('Square', 'Circle', 'Triangle');
var names = new Array('John', 'David', 'Sarah');
switch (ddl1.value) {
case 'Colours':
document.getElementById(ddl2).options.length = 0;
for (i = 0; i < colours.length; i++) {
createOption(document.getElementById(ddl2), colours[i], colours[i]);
}
break;
case 'Shapes':
document.getElementById(ddl2).options.length = 0;
for (i = 0; i < colours.length; i++) {
createOption(document.getElementById(ddl2), shapes[i], shapes[i]);
}
break;
case 'Names':
document.getElementById(ddl2).options.length = 0;
for (i = 0; i < colours.length; i++) {
createOption(document.getElementById(ddl2), names[i], names[i]);
}
break;
default:
document.getElementById(ddl2).options.length = 0;
break;
}
}
function createOption(ddl, text, value) {
var opt = document.createElement('option');
opt.value = value;
opt.text = text;
ddl.options.add(opt);
}
Then call it
<select id="ddl" onchange="configureDropDownLists(this,'ddl2')">
<option value=""></option>
<option value="Colours">Colours</option>
<option value="Shapes">Shapes</option>
<option value="Names">Names</option>
</select>
<select id="ddl2">
</select>
This all works fine, but I want the page to redirect to somewhere on the site after the person makes a selection in the second drop down.
Could anyone help with how to adapt the code to make that happen?
Thank you
I want the page to redirect to somewhere on the site after the person makes a selection in the second drop down.
Hook on the change event of the second <select> element, and then submit the form from there:
<select id="ddl2" onChange="redirect(this)">
</select>
function redirect(select) {
// The simplest way: call submit on the form element the select belongs to:
select.form.submit();
}
But you could also change the target attribute of the form dynamically before submitting, or just navigate away.
Update: To make the submit work, you of course would need to give your selects some name attributes, like:
<form action="/router.php" method="GET">
<select name="first" onchange="configureDropDownLists(this,'ddl2')">
...
</select>
<select name="second" id="ddl2" onChange="redirect(this)">
</select>
</form>
Although your configureDropDownLists function may work, you might improve it by not using a switch statement, but an object literal, and just select the array of option values before executing the same thing if one was found in the object:
function configureDropDownLists(firstSelect, secondId) {
var map = {
"colours": ['Black', 'White', 'Blue'],
"shapes": ['Square', 'Circle', 'Triangle'],
"names": ['John', 'David', 'Sarah']
};
var value = firstSelect.value.toLowerCase();
var optionsArr = map[value];
var secondSelect = document.getElementById(secondId);
secondSelect.options.length = 0; // remove all options
if (optionsArr) {
for (var i=0; i<optionsArr.length; i++) {
createOption(secondSelect, optionsArr[i], optionsArr[i]);
}
}
}
How to set selectedIndex of select element using display text as reference?
Example:
<input id="AnimalToFind" type="text" />
<select id="Animals">
<option value="0">Chicken</option>
<option value="1">Crocodile</option>
<option value="2">Monkey</option>
</select>
<input type="button" onclick="SelectAnimal()" />
<script type="text/javascript">
function SelectAnimal()
{
//Set selected option of Animals based on AnimalToFind value...
}
</script>
Is there any other way to do this without a loop? You know, I'm thinking of a built-in JavaScript code or something. Also, I don't use jQuery...
Try this:
function SelectAnimal() {
var sel = document.getElementById('Animals');
var val = document.getElementById('AnimalToFind').value;
for(var i = 0, j = sel.options.length; i < j; ++i) {
if(sel.options[i].innerHTML === val) {
sel.selectedIndex = i;
break;
}
}
}
<script type="text/javascript">
function SelectAnimal(){
//Set selected option of Animals based on AnimalToFind value...
var animalTofind = document.getElementById('AnimalToFind');
var selection = document.getElementById('Animals');
// select element
for(var i=0;i<selection.options.length;i++){
if (selection.options[i].innerHTML == animalTofind.value) {
selection.selectedIndex = i;
break;
}
}
}
</script>
setting the selectedIndex property of the select tag will choose the correct item. it is a good idea of instead of comparing the two values (options innerHTML && animal value) you can use the indexOf() method or regular expression to select the correct option despite casing or presense of spaces
selection.options[i].innerHTML.indexOf(animalTofind.value) != -1;
or using .match(/regular expression/)
If you want this without loops or jquery you could use the following
This is straight up JavaScript. This works for current web browsers. Given the age of the question I am not sure if this would have worked back in 2011. Please note that using css style selectors is extremely powerful and can help shorten a lot of code.
// Please note that querySelectorAll will return a match for
// for the term...if there is more than one then you will
// have to loop through the returned object
var selectAnimal = function() {
var animals = document.getElementById('animal');
if (animals) {
var x = animals.querySelectorAll('option[value="frog"]');
if (x.length === 1) {
console.log(x[0].index);
animals.selectedIndex = x[0].index;
}
}
}
<html>
<head>
<title>Test without loop or jquery</title>
</head>
<body>
<label>Animal to select
<select id='animal'>
<option value='nothing'></option>
<option value='dog'>dog</option>
<option value='cat'>cat</option>
<option value='mouse'>mouse</option>
<option value='rat'>rat</option>
<option value='frog'>frog</option>
<option value='horse'>horse</option>
</select>
</label>
<button onclick="selectAnimal()">Click to select animal</button>
</body>
</html>
document.getElementById('Animal').querySelectorAll('option[value="searchterm"]');
in the index object you can now do the following:
x[0].index
Try this:
function SelectAnimal()
{
var animals = document.getElementById('Animals');
var animalsToFind = document.getElementById('AnimalToFind');
// get the options length
var len = animals.options.length;
for(i = 0; i < len; i++)
{
// check the current option's text if it's the same with the input box
if (animals.options[i].innerHTML == animalsToFind.value)
{
animals.selectedIndex = i;
break;
}
}
}
You can set the index by this code :
sel.selectedIndex = 0;
but remember a caution in this practice, You would not be able to call the server side onclick method if you select the previous value selected in the drop down..
Add name attribute to your option:
<option value="0" name="Chicken">Chicken</option>
With that you can use the HTMLOptionsCollection.namedItem("Chicken").value to set the value of your select element.
You can use the HTMLOptionsCollection.namedItem()
That means that you have to define your select options to have a name attribute and have the value of the displayed text.
e.g
California