Change <select> options with javascript dynamically - javascript

Can I use a javascript if/else function to change the select options of a form? I don't want to use CSS to hide/display different dropdown menus, so here is what I've ccome up with:
function getType() {
var x = document.getElementById("food").value;
var items;
if (x === "fruit") {
items = "Apple" || items = "Oranges" || items = "Bananas";
else {
items = "Eggplants" || items = "Olives"
}
document.getElementById("pickone").value;
}
<input type="text" id="food">
<select id="pickone">
<option id="1"></option>
<option id="2"></option>
</select>
I can't seem to find any documentation about how to do this, so any help would be great.

You could append a string for the options and set it as innerHTML of your select field afterwards:
function getType() {
var x = document.getElementById("food").value;
var items;
if (x === "fruit") {
items = ["Apple", "Oranges", "Bananas"];
} else {
items = ["Eggplants", "Olives"]
}
var str = ""
for (var item of items) {
str += "<option>" + item + "</option>"
}
document.getElementById("pickone").innerHTML = str;
}
document.getElementById("btn").addEventListener("click", getType)
<input type="text" id="food">
<button id="btn">click</button>
<select id="pickone">
</select>

Your logic is not very right, specially where you try to do this
items = "Apple" || items = "Oranges" || items = "Bananas";
with the above statement you are saying that itens are Apple OR Oranges OR Bananas, only one at once...
you'll need an array of elements, like this:
var itens = ["Apple", "Oranges", "Bananas"];
Then, you will need to loop through it to add them to the select, like this:
var itens = ["Apple", "Orange", "Banana"];
var selectElem = document.getElementById("mySelect");
for (var i = 0; i < itens.length; i++){
var item = itens[i];
var element = document.createElement("option");
element.innerText = item;
selectElem.append(element);
}
<select id="mySelect"></select>
With that, now you can achieve what you want, just follow this logic...
you can also, if you want, add an `if` statement to check what is the input value, then set the options based on the input value, as you are already trying to do.

You can change options easily with JavaScript. I would advise to use an additional library to ease DOM manipulation, such as JQuery. An example code would look like the example below. You have to make sure to define an event on which the options should be changed. The example listens to changes within the input field.
<input type="text" id="food" value="vegetables"/>
<select id="pickone"></select>
<script src="https://cdn.jsdelivr.net/npm/jquery#3.3.1/dist/jquery.min.js"></script>
<script>
var fruits = ["Apple", "Oranges", "Bananas"];
var vegetables = ["Eggplants", "Olives"];
vegetables.forEach(function(item){
$('#pickone').append("<option>" + item + "</option>");
});
$('body').on('keyup', '#food', function (){
if ($('#food').val() === 'fruits') {
$('#pickone').html("");
fruits.forEach(function(item){
$('#pickone').append("<option>" + item + "</option>");
});
}
});
</script>

Related

Append List of <select> Elements

I am trying to create a button that calls a function which creates new list items with selection boxes. The code below create a select element however, the button disappears and it doesn't create one list item after another. Any idea how I can persist the button and add one select element after another?
<button type="button" onclick="createTable()">Add Item</button>
function createTable()
{
var itemName = "Selections: ";
document.write(itemName);
for (var i=0;i<7;i++)
{
var myTable = " ";
myTable+="<select name='test' id='mySelect"+i+"' style='font-size:10px' onchange='Calculate()'>";
myTable+="<option value='zeroPoint'>0</option>";
myTable+="<option value='halfPoint'>1/2</option>";
myTable+="<option value='onePoint'>1</option>";
myTable+="</select>";
document.write(myTable);
}
}
I made some changes to the documnet.write way you have. However, I would strongly recommend dynamically creating html dom nodes. I added another method, createTable2, which does the required. It will also be easier for you to preserve the html content you have, which can be easily written over with document.write way.
Edit:
I added one more method, createTable2, to allow adding multiple selects. There is a model you can pass in with the select and option information you have. There is a flag, empty, which is set to true if you would like to empty the div before adding new selects; i.e. createTable3(true).
function createTable()
{
var itemName = "Selections: ";
var selectElement = document.getElementById("render");
for (var i=0;i<7;i++)
{
var myTable = " ";
myTable+="<select name='test' id='mySelect"+i+"' style='font-size:10px' onchange='Calculate()'>";
myTable+="<option value='zeroPoint'>0</option>";
myTable+="<option value='halfPoint'>1/2</option>";
myTable+="<option value='onePoint'>1</option>";
myTable+="</select>";
selectElement.innerHTML = myTable;
}
}
function createTable2(){
var myDiv = document.getElementById("render");
//Create array of options to be added
var array = ["zeroPoint","halfPoint","onePoint"];
var texts = ["1","1/2","1"];
var selectList = document.createElement("select");
selectList.id = "mySelect";
selectList.style.fontSize = "10px";
selectList.onChange = 'Calculate()';
myDiv.appendChild(selectList);
//Create and append the options
for (var i = 0; i < array.length; i++) {
var option = document.createElement("option");
option.value = array[i];
option.text = texts[i];
selectList.appendChild(option);
}
}
function createTable3(empty){
var myDiv = document.getElementById("render");
if(empty){
myDiv.innerHTML = "";
}
let model = {
"select1": [{value: "zeroPoint", label: "1"},
{value: "halfPoint", label: "1/2"},
{value: "onePoint", label: "1"}],
"select2": [{value: "zeroPoint1", label: "11"},
{value: "halfPoint1", label: "11/22"},
{value: "onePoint1", label: "11"}]
};
Object.keys(model).forEach(function(key){
let entry = model[key];
var selectList = document.createElement("select");
selectList.id = key;
selectList.style.fontSize = "10px";
myDiv.appendChild(selectList);
//Create and append the options
for (var i = 0, item; item = entry[i]; i++) {
var option = document.createElement("option");
option.value = item.value;
option.text = item.label;
selectList.appendChild(option);
}
});
}
<button type="button" onclick="createTable3()">Add Item</button>
<div id= "render"/>
If you use document.write("") the entire web page content will be replace by the content you pass inside the document.write function. Instead create a div element under button element like
<div id="list"></div>
then in the javascript file change as
function createTable()
{
var itemName = "Selections: ";
var selectElement = document.getElementById(list);
for (var i=0;i<7;i++)
{
var myTable = " ";
myTable+="<select name='test' id='mySelect"+i+"' style='font-size:10px' onchange='Calculate()'>";
myTable+="<option value='zeroPoint'>0</option>";
myTable+="<option value='halfPoint'>1/2</option>";
myTable+="<option value='onePoint'>1</option>";
myTable+="</select>";
selectElement.innerHTML = myTable;
}
}
I am unsure what you are exactly trying to achieve, but having DOM elements in strings and then modifying an elements innerHTML or using document.write is just a hack. You need to leverage the DOM apis.
While that means my code is maybe double or triple the the size of your code. Its the more maintainable version long term.
function createTable() {
var selectMenu = document.querySelector('#selectionsContainer');
// Array of options elements
var myTable = [];
// Pushing some elements to our my table array
//
myTable.push(
createOption('zeroPoint', 0),
createOption('halfPoint', 0.5),
createOption('onePoint', 1)
)
// Looping through all elements and adding them to the //selections container
//
myTable.forEach( element => {
selectionsContainer.appendChild(element);
});
}
/** Creates an option element and returns it for usage */
function createOption(value, label) {
var option = document.createElement('option');
option.value = value;
option.innerText = label;
return option;
}
function Calculate(value) {
console.log('do whatever you want to with the value: ', value);
}
select {
font-size:10px
}
<button type="button" onclick="createTable()">Add Item</button>
<label for="selectionsContainer">
Selections
<label>
<select id="selectionsContainer" onchange='Calculate(this.value)'>
<option value=5> 5 </option>
<select>
All the answers so far are pointing that OP might be doing something wrong by not creating select dynamically. But we don't know his requirements.
Also everybody already explained document.write will write on you entire document thus deleting everything, you don't want that.
document.write --> https://developer.mozilla.org/en-US/docs/Web/API/Document/write
appendChild should be used but you wanted a string and appendChild expect Node not string.
appendChild --> https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild
node --> https://developer.mozilla.org/en-US/docs/Web/API/Node
So the only way to solve this is by using innerHTML and summing up inner Html by adding new ones.
Or by creating node from sting, which requires some more logic, see here --> Creating a new DOM element from an HTML string using built-in DOM methods or prototype
innerHTML --> https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML
const selectTamplate = (selectId, onChangeCallbackName) => {
return `
<select name='test' id='mySelect${selectId}' style='font-size:10px' onchange='${onChangeCallbackName}()'>
<option value='zeroPoint'>0</option>
<option value='halfPoint'>1/2</option>
<option value='onePoint'>1</option>
</select>
`
};
const appendStringHtml = (elementTargetHtml, elemenAppend) => {
elemenAppend.innerHTML += elementTargetHtml;
}
const doSomethingOnChange = () => {
console.log('I am the KING!');
};
const placeToAppend = document.querySelector('.append-selects-here');
const buttonAppender = document.querySelector('.btn-append');
let selectID = 1;
buttonAppender.addEventListener('click', ()=>{
const selectHTML = selectTamplate(selectID, 'doSomethingOnChange');
appendStringHtml(selectHTML, placeToAppend);
selectID ++;
});
<button class="btn-append">Add Selects</button>
<div class="append-selects-here"></div>
see the working code here --> https://codepen.io/nikolamitic/pen/PEpEbj
I used template string so that interpolation is possible, little bit more clear. And separate the logic while still keeping yours.

How to get element by name with $key

PHP
//Here is my html for qty
<p>Qty : <input type="number" value="" name="qty<?php echo $key ?> onChange="findTotal()"/>
JS function
function findTotal() {
var arr = document.getElementsByName('qty');
...
document.getElementById('result').value = decimalPlaces(tot, 2);
}
My qty name needs key for post array. How do I get name inside js function to calculate quantities?
You can use
document.querySelector("input['name^='qty']").value
if you don't have jQuery.
This will select an input with name attribute starting with "qty". If you have multiple inputs which match the criteria you can select them all using
document.querySelectorAll("input[name^='qty']")
which will return a NodeList. You can read more about this here.
You can do something like this
var myVar = document.getElementsByTagName("somename");
//do something else
If you are using jquery
value = $( "input[name^='qtd']" ).val();
//it will pick the input wich name starts with 'qtd'
In pure DOM, you could use getElementsByTagName to grab all input elements, and loop through the resulting array. Elements with name starting with 'qty' get pushed to another array:
var eles = [];
var inputs = document.getElementsByTagName("input");
for(var i = 0; i < inputs.length; i++) {
if(inputs[i].name.indexOf('qty') == 0) {
eles.push(inputs[i]);
}
}
Don't query the element by the name attribute's value. I'm not sure what's the purpose of the key and why you need it in the findTotal method, but here's an example:
<p>Qty : <input type="number" value="" name="qtyMyKey" onChange="findTotal(event)" /></p>
<script>
function findTotal(e) {
var inputEl = e.target,
inputName = inputEl.getAttribute('name'),
myKey;
if (typeof inputName === 'string') {
myKey = inputName.replace('qty', '');
}
console.log(myKey);
//var arr = document.getElementsByName('qty');
//document.getElementById('result').value = decimalPlaces(inputEl.value(), 2);
}
</script>
Here's the jsFiddle demo.

javascript dynamic drop down list - two forms depend of one

I want to create a dynamic drop down list with javascript.
Right now it works like this:
- if I choose first option, then second, then third.
I want to change this code to:
- when I choose first option, it shows second and third option in the same time(second and third option depends of first)
I want to do something like:
Choose name:
John Doe(first option)
Choose proffesion:
Dentist(second option)
Choose gender:
male(third option)
Is it possible?
Thanks for reply.
<!doctype html>
<html>
<head>
<script>
var modelsArray = new Array(
["Chevy","","Camaro","Corvette","Impala"],
["Dodge","","Avenger","Challenger","Charger"],
["Ford","","Mustang","Shelby"]
);
var colorsArray = new Array(
["Camaro","","White","Black","Red"],
["Corvette","","White","Purple","Blue","Fawn"],
["Impala","","White","Black","Red","Chrome Yellow"],
["Avenger","","White","Acid Green","Alice Blue"],
["Challenger","","White","Violet","Blue-Green"],
["Charger","","White","Dark Pastel Red"],
["Mustang","","White","Debian red","Impala","Flame"],
["Shelby","","White","Deep Spring Bud"]
);
function populate1(s1,s2,s3){
var optionArray = [];
var s1 = document.getElementById(s1);
var s2 = document.getElementById(s2);
s2.innerHTML = "";
var s3 = document.getElementById(s3);
s3.innerHTML = "";
for(var i = 0; i < modelsArray.length; i++){
if(s1.value == modelsArray[i][0]){
for(var x = 1; x < modelsArray[i].length; x++){
optionArray.push(modelsArray[i][x]);
}
}
}
optionArray.sort();
for(var option in optionArray){
var newOption = document.createElement("option");
newOption.value = optionArray[option];
newOption.innerHTML = optionArray[option];
s2.options.add(newOption);
}
}
function populate2(s1,s2){
var optionArray = [];
var s1 = document.getElementById(s1);
var s2 = document.getElementById(s2);
s2.innerHTML = "";
for(var i = 0; i < colorsArray.length; i++){
if(s1.value == colorsArray[i][0]){
for(var x = 1; x < colorsArray[i].length; x++){
optionArray.push(colorsArray[i][x]);
}
}
}
optionArray.sort();
for(var option in optionArray){
var newOption = document.createElement("option");
newOption.value = optionArray[option];
newOption.innerHTML = optionArray[option];
s2.options.add(newOption);
}
}
</script>
</head>
<body>
<h2>Choose Your Car</h2>
<hr />
Choose Car Make:
<select id="slct1" name="slct1" onchange="populate1(this.id,'slct2','slct3')">
<option value=""></option>
<option value="Chevy">Chevy</option>
<option value="Dodge">Dodge</option>
<option value="Ford">Ford</option>
</select>
<hr />
Choose Car Model:
<select id="slct2" name="slct2" onchange="populate2(this.id,'slct3')"></select>
<hr />
Choose Car Color:
<select id="slct3" name="slct3"></select>
<hr />
</body>
</html>
I've created a jsfiddle here which implements a rudimentary example.
You can create DOM event listeners to respond to the change event of the select elements. When these events are triggered, pass the value of the selected option to a function which can extract the models/colours from the data.
Ideally you will setup your server side code to return the data in a format such as:
{
"makes": {
"ford": {
"models": {
"focus": {
"colours": [
"blue",
"black"
]
},
"probe": {
"colours": [
"green",
"grey"
]
}
}
}
}
Using this data format you can easily drill down the object tree e.g.
carData.makes.ford.models.focus.colours
Once you have the data you can then use jQuery to append options to your select e.g.
for (var model in models) {
$('select').append('<option value="'
+ model + '">' + model +
'</option>');
}
*EDIT: If you want to use the combination of the first two selects then you can do something like this:
var mapCombinations = {canada: {toronto: {mapName: "canada"}}};
var mapName = mapCombinations[selectValue1][selectValue2].mapName);
showMap(mapName);
function showMap(mapName) {
// Call server to get map
$.ajax({
type: "GET",
url: "http://yoururl.com/api/map/" + mapName,
success: function(data){
// display map
}
});
}
EDIT2: You can use the same principle if you want the third select to contain an action. I've replaced the colours array with actions. This third select will change depending on the first 2 select values.
Updated jsfiddle which doesn't use jquery.
You can then set up an event listener to process that action.
I need to repeat third value all the time.
I try to give you an example.
First value = Country
Second value = City
Third value = option
And I want to do something like:
If First value = Canada then Second value = Toronto
If First value = Canada then Third value = Show canada map
Second Value and third value don't depend of themselve, only of first value.

Automatically Load the option to drop down menu

I am trying to load the first available option to the third drop-down.
The code is as below.
var categories = [];
categories["startList"] = ["C.","C#.","D.","Eb.","E.","F.","F#.","G.","Ab.","A.","Bb.","B."]; // Level 1
categories["C."] = ["C","C7","Cm","Cm7","Cmaj7","Csus4","Caug","Cdim"];
categories["C"] = ["032010","335553","133211","543210",""];
var nLists = 3; // number of lists in the set
function fillSelect(currCat,currList){
var step = Number(currList.name.replace(/\D/g,""));
for (i=step; i<nLists+1; i++) {
document.forms[0]['List'+i].length = 1;
document.forms[0]['List'+i].selectedIndex = 0;
}
var nCat = categories[currCat];
for (each in nCat) {
var nOption = document.createElement('option');
var nData = document.createTextNode(nCat[each]);
nOption.setAttribute('value',nCat[each]);
nOption.appendChild(nData);
currList.appendChild(nOption);
}
}
function init() { fillSelect('startList',document.forms[0]['List1']);
fillSelect('startList',document.forms[0]['List4']);
fillSelect('startList',document.forms[0]['List7']);
}
navigator.appName == "Microsoft Internet Explorer"
? attachEvent('onload', init, false)
: addEventListener('load', init, false);
function getValues() {
var str = '';
for(i = 1; i < 6; i++) {
document.createElement('select')
str += document.getElementById('List' + i).value+'\n';
document.getElementById('creation').innerHTML=""; }
}
<select name='List4' id="List4" onchange="fillSelect(this.value,this.form['ch2'])"><option selected></option></select>
<select name='ch2' id="ch2" onchange="fillSelect(this.value,this.form['tb2'])"><option selected></option></select>
<select name='tb2' id="tb2"><option selected></option></select>
<input id="f2" type="text" size="1" value=1 class=copystuff>
<button onclick="do2()">Do2</button><br>
Now the problem is that when I try to select the second drop down menu "ch2", I want the first value to be loaded automatically in the third dropdown "tb2" according to the selection that I make in the second menu. For eg, if I select C. in the first menu, C in the second menu, I want 032010 to be already selected in the next menu. Is there any simple way to do this?
I have changed your code up a good bit. But I think it's a bit more readable, and may be easier to extend to more forms, categories, and selects.
First here is the working JSFiddle: http://jsfiddle.net/z1sw2bfq/
Second, here is the Fiddle code. Please see the comments for additional context.
<script>
//create a blank object to hold the select lists
var lists = { };
//create an object to hold the categories text arrays
var categories = {
"startList": ["C.","C#.","D.","Eb.","E.","F.","F#.","G.","Ab.","A.","Bb.","B."], // Level 1
"C.": ["C","C7","Cm","Cm7","Cmaj7","Csus4","Caug","Cdim"],
"C": ["032010","335553","133211","543210",""]
};
function init() {
//load the SELECT element from the form into lists
//Get all of the selects in forms[0]...
var selects = document.forms[0].getElementsByTagName("select");
for (var i in selects) {
//...and load those into lists.
lists[selects[i].id] = selects[i];
//Ex: creates a property like "lists.List4" also referenced by "list['List4']")
// which equals the select element with id List4
}
//enter the list name and the select id
fillSelect('startList', 'List4');
}
function fillSelect(currCatName, currListName){
//get the category
var cat = categories[currCatName];
//verify the category is valid
if (cat) {
//get the select
var select = lists[currListName];
//verify the select is valid
if (select) {
//clear the select
for (var i = select.options.length-1; i>=0; i--)
select.remove(i);
//check the data-first attribute
var datafirst = select.getAttribute("data-first");
if (datafirst == "blank") {
var opt = document.createElement('option');
opt.value = "";
opt.text = "";
select.add(opt);
}
//load the select
for (var j in cat) {
var opt = document.createElement('option');
opt.value = cat[j];
opt.text = cat[j];
select.add(opt);
}
}
}
}
//best to use feature detection instead of browser detection
if (window.attachEvent)
window.attachEvent('onload', init, false);
else
window.addEventListener('load', init, false);
</script>
<form action="#" method="get">
<!--
I added a "data-first" attribute to the selects. This will be used to determine if the
first option in the select is a blank or the first item in the list.
-->
<select name='List4' id="List4" onchange="fillSelect(this.value,'ch2')" data-first="blank"></select>
<select name='ch2' id="ch2" onchange="fillSelect(this.value,'tb2')" data-first="blank"></select>
<select name='tb2' id="tb2" data-first="first"></select>
</form>

HTML select: how to set drop down text

How do I set the text values of a HTML drop down list to a value/variable from a external text or .js file. ( The value that will be displayed in the drop down list )
for example:
<select id="usernameDropDown">
<option value="username1">name1</option>
<option value="username2">name2</option>
<option value="username3">name3</option>
</select>
I'm trying to dynamically change the values as above "name1" and "name2" and so on to the values from a local .js file.
Currently I have the values from the .js files written on the html page successfully with the following code segment:
<script src="jstest.js" type="text/javascript"></script>
<script Language='JavaScript'>
document.write(name1)
document.write(name2)
document.write(name3)
document.write(CSRUsername1)
document.write(CSRUsername2)
document.write(CSRUsername3)
</script>
currently the .js file is setup something like this:
var name1="Alpha"
var name2="Bravo"
var name3="Charlie"
var name4="Delta"
var name5="Echo"
Is there any method to set this text value using values from a text file or .js file?
If possible, I would like to keep the solution in html / java script only..
Here's how to load a drop down dynamically [Fiddle].
HTML
<select id="usernameDropDown">
<option>Choose a user</option>
</select>
Javascript
var select = document.getElementById("usernameDropDown");
var unames = ["Alpha", "Bravo", "Charlie", "Delta", "Echo"];
for (var i = 0; i < unames.length; i++) {
var opt = unames[i];
var el = document.createElement("option");
el.textContent = opt;
el.value = opt;
select.appendChild(el);
}
You can try setting the innerText property of each of the option elements:
var s = document.getElementById('names');
s.children[0].innerText = name1;
s.children[1].innerText = name2;
s.children[2].innerText = name3;
See this Fiddle.
Note that here you would need to know which child is where (e.g. the first child of the select is name1, etc.).
An alternative way to pick the children is to set ID attributes for each option, and use document.selectElementById on each option element.
Creates the options from scratch and adds them to the drop down list. The label is the text and the value is the value.
var dropdown = document.getElementById('usernameDropDown');
// if dropdown exists
if(dropdown) {
var usernames = [
{ label: 'name1', value: 'username1' },
{ label: 'name2', value: 'username2' },
{ label: 'name3', value: 'username3' }
];
for(var i=0,l=usernames.length; i<l; i++) {
var username = usernames[i];
var option = document.createElement('option');
option.setAttribute('value',username.value);
var optionText = document.createTextNode(username.label);
option.appendChild(optionText);
dropdown.appendChild(option);
}
}
My idea:
HTML:
<select id="usernameDropDown">
<option value="username1">name1</option>
<option value="username2">name2</option>
<option value="username3">name3</option>
</select>
Javascript:
window.onload = init;
var names=["Alpha", "Bravo", "Charlie", "Delta", "Echo"];
function init(){
var opts = document.getElementById("usernameDropDown").childNodes;
for (var i=0, i<opts.length, i++){
opts[i].innerHTML = names[i];
}
}
The javascript sets the 'innerHTML' property to the name string taken from the array. Not as elegant as Dissident Rage's version but shorter :D
Here is a really quick jQuery method that you could use
UPDATED version:
It updates your select dynamically from your array
fiddle
Your HTML
<select id="usernameDropDown">
<option value="username1">Username</option>
</select>
Your javascript
var name = ["Alpha","Bravo","Charlie","Delta","Echo"];
for(i=0;i<name.length;i++){
$("#usernameDropDown").append("<option value='name" + i + "'>" + name[i] + "</option>");
}
$("#usernameDropDown option").each(function(){
if($(this).html() == "name1")
{
$(this).html(name1)
}
if($(this).html() == "name2")
{
$(this).html(name2)
}
if($(this).html() == "name3")
{
$(this).html(name3)
}
});

Categories

Resources