I'm trying to learn how to dynamically add n select elements with options to an HTML form using vanilla JS. There are a few related Stack Overflow questions but these focus on instances where you know how many select elements there will be 1 2. I don't know exactly how many select elements will need to be generated; I need to generate them dynamically. I started simpler by learning how to dynamically generate regular text fields:
for (let i = 0; i < res[0].length; i++) {
container.appendChild(document.createTextNode(res[0][i]));
var input = document.createElement("input");
input.type = res[1][i];
input.name = res[0][i];
input.classList.add("input");
container.appendChild(input);
}
where
var res = [["textfield 1","text field 2"],["text","text"],[["none"],["none"]]];
That works fine for regular text fields so then I started working on select elements:
for (let i = 0; i < res[0].length; i++) {
var select = document.getElementById("mySelect");
var options = res[2][i];
for(var j = 0; j < options.length; j++) {
var optn = options[j];
var elmnt = document.createElement("option");
elmnt.name = res[0][i];
elmnt.classList.add("input")
elmnt.text = optn;
elmnt.value = optn;
select.id = res[0][i];
select.add(elmnt);
}
}
where
var res = [["country","language"],["li","li"],[["Canada","Mexico","United States"],["English","Spanish","English"]]];
I thought that using select.id = res[0][i]; would accomplish what I want but I think that's just creating separate sets of options and not actually creating separate select elements. Right now, this yields the first select with countries but the second select for languages doesn't appear.
Here's the HTML:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form name="myTest" id="myTest_frm">
<div id="container"/>
<select multiple = true id="mySelect">
<option>Select an option</option>
</select>
</div>
<br><input type="button" value="Submit" onClick="test()">
</form>
I know that I can modify the HTML to include multiple select tags to make this work as shown below but that requires that I pre-know how many select elements I'll need. Again, I don't pre-know how many select elements there will be, i.e. res[0].length could be two as shown in the examples or it could be any other length.
Working but not dynamic:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form name="myTest" id="myTest_frm">
<div id="container"/>
<select multiple = true id="mySelect">
<option>Select an option</option>
</select>
<select multiple = true id="mySelect">
<option>Select an option</option>
</select>
</div>
<br><input type="button" value="Submit" onClick="test()">
</form>
First you need establish the format of your dynamic data.
var res = [["country","language"],["li","li"],[["Canada","Mexico","United States"],["English","Spanish","English"]]]
This is a difficult to work with format, as it's "hard-coded" position of the list in the array (what's the li are for?)
For your purpose you probably should go with an object which contains list of options (array).
This way, you can use object's key for select name:
var res = {
country: ["Mexico" /*default*/, "Canada","Mexico","United States"],
language: ["French" /*default*/, "English","Spanish","French"]
}
const container = document.getElementById("container");
for(let i in res)
{
const select = document.createElement("select");
select.value = res[i].shift(); //select default item, by removing first item from the array
container.appendChild(select);
for(let o = 0; o < res[i].length; o++)
{
const option = document.createElement("option");
option.textContent = res[i][o];
option.value = res[i][o];
select.appendChild(option);
};
}
<form name="myTest" id="myTest_frm">
<div id="container"></div>
<br><input type="button" value="Submit" onClick="test()">
</form>
Related
I am trying to change 3 text inputs to selects and append options underneath, but the input stays the same.
Here is my js code
let inputSelect=['protons2', 'atomic2', 'neutrons'];
for(let i = 0; i < inputSelect; i++){
document.getElementById(inputSelect[i]).setAttribute("type","select")
const opt = document.createElement("option");
opt.textContent = "orbit";
document.getElementById(inputSelect[i]).appendChild(opt)
}
here is my html code
<label id="pro2" for = "protons2"></label>
<input type = "text" id = "protons2" class='input' autocomplete="off" placeholder="Answer">
<label id="at2" for = "atomic2"></label>
<input type = "text" id = "atomic2" class='input' autocomplete="off" placeholder="Answer">
<label id="new" for = "neutrons"></label>
<input type = "text" id = "neutrons" class='input' autocomplete="off" placeholder="Answer">
The input type does change according to the css selector input[type=text], as none of the styles of that selector is applied once the text input changes to a select input.
It still stays a text input though.
1 - You have to use the length value in the array to use it in the for.
2 - You can't convert an input text into a select. You have to replace the element.
let inputSelect = ['protons2', 'atomic2', 'neutrons'];
for (let i = 0; i < inputSelect.length; i++) {
select_aux = document.createElement("select");
select_aux.id = inputSelect[i];
document.getElementById(inputSelect[i]).replaceWith(select_aux);
const opt = document.createElement("option");
opt.textContent = "orbit";
document.getElementById(inputSelect[i]).appendChild(opt);
}
<input type="text" id="protons2">
<input type="text" id="atomic2">
<input type="text" id="neutrons">
There is no type attribute that is select, instead you need to make a select element.
Note: You forgot to add .length to inputSelect in your loop.
<select>
<option>Option 1</option>
</select>
Creating a select with JS
document.insertAdjacentHTML('beforeend', '<select>
<option>Option 1</option>
</select>')
let inputSelect=['protons2', 'atomic2', 'neutrons'];
for(let i = 0; i < inputSelect.length; i++){
const opt = document.createElement("option");
opt.textContent = "orbit";
document.getElementById(inputSelect[i]).appendChild(opt)
}
<select id="protons2">
</select>
<select id="atomic2">
</select>
<select id="neutrons">
</select>
For my code i need 2 selects, the first select is static (4 options that dont change) and the second select is dependant on what is selected in the first select.
Then depending on what is chosen in de the second list a function is executed.
i found some example code one W3schools that allow me to make the whole list thing:
https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_select_options3
So this works really well but now i dont know how to attach a function to the selected options in the second select since there is no where in the html to do something like an onchange.
Each option from the second select should have a function (in my code the selected option will display an image corresponding with the chosen option)
<!DOCTYPE html>
<html>
<body>
<select id="car" onchange="ChangeCarList()">
<option value="">-- Car --</option>
<option value="VO">Volvo</option>
<option value="VW">Volkswagen</option>
<option value="BMW">BMW</option>
</select>
<select id="carmodel"></select>
<script>
var carsAndModels = {};
carsAndModels['VO'] = ['V70', 'XC60', 'XC90'];
carsAndModels['VW'] = ['Golf', 'Polo', 'Scirocco', 'Touareg'];
carsAndModels['BMW'] = ['M6', 'X5', 'Z3'];
function ChangeCarList() {
var carList = document.getElementById("car");
var modelList = document.getElementById("carmodel");
var selCar = carList.options[carList.selectedIndex].value;
while (modelList.options.length) {
modelList.remove(0);
}
var cars = carsAndModels[selCar];
if (cars) {
var i;
for (i = 0; i < cars.length; i++) {
var car = new Option(cars[i], i);
modelList.options.add(car);
}
}
}
</script>
</body>
</html>
var serviceGroupName = document.querySelectorAll('packageGroupName').value;
var sourceType = document.getElementById("multiple-checkboxes");
if (serviceGroupName !== '')
{
var serviceArray = [];
for (i = 0; i < sourceType.selectedOptions.length; i++)
{
serviceArray.push(parseInt(sourceType.selectedOptions[i].value));
}
var groupName = {};
groupName[serviceGroupName] = serviceArray;
ungroupedServiceArray = [];
}
document.getElementById('addGroup').onclick = duplicate;
var i = 0;
var original = document.getElementById('addService');
function duplicate()
{
var clone = original.cloneNode(true);
clone.id = "addService1" + ++i;
original.parentNode.appendChild(clone);
}
<div id="addService">
<p><b>Service Group Name: </b></p>
<div class="form-group">
<input type="text" class="packageGroupName" id="packageGroupName" minlength= 1 placeholder=" Group Name" >
</div>
<p><b>Add Services</b></p>
<div class="form-group">
<select id="multiple-checkboxes" multiple="multiple" class='packageGroupName'>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
</div>
<div class="form-group">
<label for="exampleFormControlTextarea1"></label>
<button type="button" class="btn btn-primary" onclick="duplicate()" id="addGroup">Add </button>
</div>
</div>
I am trying to loop through an undefined number of HTML elements all with the same id. The reason being, every time the user clicks a button on the form, it creates a new text field and drop down, identical to the original.
I am looking to grab a string value from a text box and multiple values from a multiselect list and associate them where the string value is the key, and the multiple values from the drop down list are the values.
Here is the javascript code I have thus far:
This is grabbing the data from the text field and the multiselect list
var serviceGroupName = document.querySelectorAll('packageGroupName').value;
var sourceType = document.getElementById("multiple-checkboxes");
if (serviceGroupName !== '')
{
var serviceArray = [];
for (i = 0; i < sourceType.selectedOptions.length; i++)
{
serviceArray.push(parseInt(sourceType.selectedOptions[i].value));
}
var groupName = {};
groupName[serviceGroupName] = serviceArray;
ungroupedServiceArray = [];
}
This is how I'd like the final output to look. Basically, however many times the user creates a new textbox and muliselect list it will create this output:
"Textbox value": [
multiselect_values,
multiselect_values,
multiselect_values,
multiselect_values
]
"Textbox value2":[
multiselect_values2,
multiselect_values2,
multiselect_values2
]
As others put it, you need to use a class name instead of using just an id. Instead of <div id="addService">" use <div id="addService" class="service">.
Then in your code you would do something like this:
var servicelist = document.querySelectorAll('.service')
for(var i=0; i<servicelist.length; i++){
var serviceGroupName = servicelist[i].querySelector('input.packageGroupName').value;
var sourceType = document.querySelector("select.packageGroupName");
..... the rest of your code
}
I am adding dropdowns dynamically by code it is rendered in browser like
<select id="contact-type1"></select>
<select id="contact-type2"></select>
...
Now I am trying the below code for dynamically selecting nth number of dropdown in order to fill option values in them.
function fillContactTypes()
{
var types = ["Phone","Whatapp","Facebook","Web","Fax"];
var select = document.getElementById('contact-type[*n]');
for(var i = 0; i < types.length; i++)
{
var option = document.createElement('option');
option.innerHTML = types[i];
option.value = types[i];
select.appendChild(option);
}
}
Please help me in the line "var select = document.getElementById('contact-type[*n]');
".
I have just added common class to all dropdowns and using jquery you can dynamically bind all dropdown as shown below.
var types = ["Phone","Whatapp","Facebook","Web","Fax"];
$(document).ready(function(){
fillContactTypes()
});
function fillContactTypes(){
var myselect = $('<select>');
$.each(types, function(index, key) {
myselect.append( $('<option></option>').val(key).html(key) );
});
$('.contact-type').append(myselect.html());
}
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js">
</script>
<select id="contact-type1" class="contact-type">
</select>
<select id="contact-type2" class="contact-type">
</select>
<select id="contact-type3" class="contact-type">
</select>
<select id="contact-type4" class="contact-type">
</select>
I have a SELECT which looks like this.
<select id="mySelect"><option value="">Please select</option></select>
At a certain point, my javascript sets the OPTION as follows:
var elSel = document.getElementById('mySelect');
elSel.options[0].value = myValue;
elSel.options[0].text = myText;
The problem is that you have to click the select for it to show myText. How do I make it so that myText (with myValue) shows as soon as I run that javascript?
Add elSel.selectedIndex = 0; to the end of your script. Use elSel.options.length-1 if you're going to ever have more than 1 item and you want to select the last item.
<html>
<head>
<script language="javascript">
function addItem() {
var elSel = document.getElementById('test');
elSel.options[0].value = '1';
elSel.options[0].text = 'new value';
elSel.selectedIndex = 0;
}
</script>
</head>
<body>
<form>
<select id="test"><option value="1">- SELECT AN ITEM -</option></select>
<input type="button" value="Add Item" onclick="addItem();" />
</form>
</body>
</html>
Load the script with onLoad attribute of the body tag? e.g.
<body onload="initSelect()">
Or simply put the script after the select tag:
<select>...</select>
<script>//code to generate the options</script>
Try using DOM manipulation:
<select id="mySelect">
<option value="">Please select</option>
</select>
<script>
var elSel = document.getElementById('mySelect');
var opt = {};
opt = document.createElement('option');
opt.value = '1';
opt.text = 'a';
elSel.appendChild(opt);
opt = document.createElement('option');
opt.value = '2';
opt.text = 'b';
opt.selected = true; /* Here is where we update the select element */
elSel.appendChild(opt);
opt = document.createElement('option');
opt.value = '3';
opt.text = 'c';
elSel.appendChild(opt);
</script>
Test it here:
http://dl.dropbox.com/u/186012/demos/stackoverflow/select/index.html
The problem was the jQuery plugin I was using (Uniform), I didn't realize that I had to run $.uniform.update()
http://pixelmatrixdesign.com/uniform/