How would I dynamically create input boxes on the fly? - javascript

I want to use the value of a HTML dropdown box and create that number of input boxes underneath. I'm hoping I can achieve this on the fly. Also if the value changes it should add or remove appropriately.
What programming language would I need to do this in? I'm using PHP for the overall website.

Here is an example that uses jQuery to achieve your goals:
Assume you have following html:
<div>
<select id="input_count">
<option value="1">1 input</option>
<option value="2">2 inputs</option>
<option value="3">3 inputs</option>
</select>
<div>
<div id="inputs"> </div>
And this is the js code for your task:
$('#input_count').change(function() {
var selectObj = $(this);
var selectedOption = selectObj.find(":selected");
var selectedValue = selectedOption.val();
var targetDiv = $("#inputs");
targetDiv.html("");
for(var i = 0; i < selectedValue; i++) {
targetDiv.append($("<input />"));
}
});
You can simplify this code as follows:
$('#input_count').change(function() {
var selectedValue = $(this).val();
var targetDiv = $("#inputs").html("");
for(var i = 0; i < selectedValue; i++) {
targetDiv.append($("<input />"));
}
});
Here is a working fiddle example: http://jsfiddle.net/melih/VnRBm/
You can read more about jQuery: http://jquery.com/

I would go for jQuery.
To start with look at change(), empty() and append()
http://api.jquery.com/change/
http://api.jquery.com/empty/
http://api.jquery.com/append/

Doing it in javascript is quite easy. Assuming you've got a number and an html element where to insert. You can obtain the parent html element by using document.getElementById or other similar methods. The method assumes the only children of the parentElement is going to be these input boxes. Here's some sample code:
function addInput = function( number, parentElement ) {
// clear all previous children
parentElement.innerHtml = "";
for (var i = 0; i < number; i++) {
var inputEl = document.createElement('input');
inputEl['type'] = 'text';
// set other styles here
parentElement.appendChild(inputEl);
}
}
for the select change event, look here: javascript select input event

you would most likely use javascript(which is what jquery is), here is an example to show you how it can be done to get you on your way
<select name="s" onchange="addTxtInputs(this)" onkeyup="addTxtInputs(this)">
<option value="0">Add</option>
<option value="1">1</option>
<option value="3">3</option>
<option value="7">7</option>
</select>
<div id="inputPlaceHolder"></div>
javascript to dynamically create a selected number of inputs on the fly, based on Mutahhir answer
<script>
function addTxtInputs(o){
var n = o.value; // holds the value from the selected option (dropdown)
var p = document.getElementById("inputPlaceHolder"); // this is to get the placeholder element
p.innerHTML = ""; // clears the contents of the place holder each time the select option is chosen.
// loop to create the number of inputs based apon `n`(selected value)
for (var i=0; i < n; i++) {
var odiv = document.createElement("div"); //create a div so each input can have there own line
var inpt = document.createElement("input");
inpt['type'] = "text"; // the input type is text
inpt['id'] = "someInputId_" + i; // set a id for optional reference
inpt['name'] = "someInputName_" + i; // an unique name for each of the inputs
odiv.appendChild(inpt); // append the each input to a div
p.appendChild(odiv); // append the div and inputs to the placeholder (inputPlaceHolder)
}
}
</script>

Related

How to generate multiple <select> elements with option tags?

I'm trying to append the defined select element to the document.
This answer, describes quite well about fixed arrays, but in my case I have a slice which is applied to the template by ExecuteTemplate method, so the value of <option> tags are defined by slice values.
Here is my code which does not work, as it should:
<html>
<input type="number" id="count">
<select id="select">
{{ range .Slice }}
<option value="{{ .Name }}">{{ .Name }}</option>
{{ end }}
</select>
<div class="test"></div>
<button onclick="generateSelects();">Test</button>
</html>
<script>
function generateSelects() {
var count = document.getElementById("count").value;
var i;
var select = document.getElementById("select");
var divClass = document.getElementsByClassName("test");
for (i = 0; i < Number(count); i++) {
divclass[0].appendChild(select);
)
}
</script>
What am I looking for is about generating select list based on the user's input. For example if the user enters 2, so two select menu going to appear on the screen.
How can I do this?
First of all make sure that generated selects all have different IDs, in your example they all have the same id which is "select".
Then instead of appending the "original" select element, try to clone it then add its clone to your div.
What I would do is :
function generateSelects() {
var count = document.getElementById("count").value;
var i;
var select = document.getElementById("select");
var divClass = document.getElementsByClassName("test");
for (i = 0; i < Number(count); i++) {
var clone = select.cloneNode(true); // true means clone all childNodes and all event handlers
clone.id = "some_id";
divclass[0].appendChild(clone);
}
}
Hope it helps!
To append multiple select elements, first you have create a select element. You can not directly get an elementById and append different element as child.
<script>
function generateSelects() {
var count = document.getElementById("count").value;
var i;
var divClass = document.getElementsByClassName("test");
for (i = 0; i < Number(count); i++) {
var option = document.createElement("OPTION");
option.setAttribute("value", "optionvalue");
var select = document.createElement("SELECT");
select.appendChild(option);
divclass[0].appendChild(select);
)
}
</script>

how to fill two or more selects with the same option elements

I'd like to add the same options elements to more than one select, using one JavaScript function.
<select id="select1" name="select1"></select>
<select id="select2" name="select2"></select>
I want selects become:
<select id="select1" name="select1">
<option value="0">Txt1</option>
<option value="1">Txt2</option>
<option value="2">Txt3</option>
</select>
<select id="select2" name="select2">
<option value="0">Txt1</option>
<option value="1">Txt2</option>
<option value="2">Txt3</option>
</select>
Here is part of function to fill selects with options:
function window_onload(){
var SpecTxt = new Array("Txt1","Txt2","Txt3");
for(var i=0; i<SpecTxt.length; i++) {
var oOption = document.createElement("OPTION");
oOption.text = SpecTxt[i];
oOption.value=i;
select1.add(oOption); // Option to first SELECT
select2.add(oOption); // Option to second SELECT
}
}
But I've got Internet Explorer Script Error "Invalid argument", result is only one first option in "select1" and no options in "select2". If I remove from function window_onload() the last string select2.add(oOption);, there are no IE errors and "select1" is filled as must be, but "select2" is empty. How is it possible in JS to add the same options to different SELECTs?
Update
The reason why the Demo didn't work for IE is because it doesn't recognize the property .valueAsNumber.
From:
var opts = qty.valueAsNumber;
To:
var opts = parseInt(qty.value, 10);
When you create an option within the loop:
var oOption = document.createElement("OPTION");
That is only one <option> not two <option>s. So that is the reason why:
select1.add(oOption); // Succeeds
select2.add(oOption); // Fails
You can either make 2 <option>s per loop:
var oOption1 = document.createElement("OPTION");
var oOption2 = document.createElement("OPTION");
OR try cloneNode(). See Demo below:
Demo
// See HTMLFormControlsCollection
var form = document.forms.ui;
var ui = form.elements;
var qty = ui.qty0;
var s0 = ui.sel0;
var s1 = ui.sel1;
// Declare a counter variable outside of loop
var cnt = 0;
// Add event handler to the change event of the input
qty.onchange = addOpt;
/* Get the value of user input as a number
|| within the for loop...
|| create an <option> tag...
|| add text to it with an incremented offset...
|| add a incremented value to it...
|| then clone it...
|| add original <option> to the first <select>...
|| add duplicate <option> to the second <select>
*/
function addOpt(e) {
var opts = parseInt(qty.value, 10);
for (let i = 0; i < opts; i++) {
var opt = document.createElement('option');
opt.text = 'Txt' + (cnt + 1);
opt.value = cnt;
var dupe = opt.cloneNode(true);
s0.add(opt);
s1.add(dupe);
cnt++;
}
}
input,
select,
option {
font: inherit
}
input {
width: 4ch;
}
<form id='ui'>
<fieldset>
<legend>Enter a number in the first form field</legend>
<input id='qty0' name='qty0' type='number' min='0' max='30'>
<select id="sel0" name="sel0"></select>
<select id="sel1" name="sel1"></select>
</fieldset>
</form>
Reference
HTMLFormControlsCollection

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>

How to set selectedIndex of select element using display text?

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

Search a dropdown

I have this HTML dropdown:
<form>
<input type="text" id="realtxt" onkeyup="searchSel()">
<select id="select" name="basic-combo" size="1">
<option value="2821">Something </option>
<option value="2825"> Something </option>
<option value="2842"> Something </option>
<option value="2843"> _Something </option>
<option value="15999"> _Something </option>
</select>
</form>
I need to search trough it using javascript.
This is what I have now:
function searchSel() {
var input=document.getElementById('realtxt').value.toLowerCase();
var output=document.getElementById('basic-combo').options;
for(var i=0;i<output.length;i++) {
var outputvalue = output[i].value;
var output = outputvalue.replace(/^(\s| )+|(\s| )+$/g,"");
if(output.indexOf(input)==0){
output[i].selected=true;
}
if(document.forms[0].realtxt.value==''){
output[0].selected=true;
}
}
}
The code doesn't work, and it's probably not the best.
Can anyone show me how I can search trough the dropdown items and when i hit enter find the one i want, and if i hit enter again give me the next result, using plain javascript?
Here's the fixed code. It searches for the first occurrence only:
function searchSel() {
var input = document.getElementById('realtxt').value;
var list = document.getElementById('select');
var listItems = list.options;
if(input === '')
{
listItems[0].selected = true;
return;
}
for(var i=0;i<list.length;i++) {
var val = list[i].value.toLowerCase();
if(val.indexOf(input) == 0) {
list.selectedIndex = i;
return;
}
}
}
You should not check for empty text outside the for loop.
Also, this code will do partial match i.e. if you type 'A', it will select the option 'Artikkelarkiv' option.
Right of the bat, your code won't work as you're selecting the dropdown wrong:
document.getElementById("basic-combo")
is wrong, as the id is select, while "basic-combo" is the name attribute.
And another thing to note, is that you have two variable named output. Even though they're in different scopes, it might become confusing.
For stuff like this, I'd suggest you use a JavaScript library like jQuery (http://jquery.com) to make DOM interaction easier and cross-browser compatible.
Then, you can select and traverse all the elements from your select like this:
$("#select").each(function() {
var $this = $(this); // Just a shortcut
var value = $this.val(); // The value of the option element
var content = $this.html(); // The text content of the option element
// Process as you wish
});

Categories