How to set element value of dynamically created drop down? - javascript

I used arrays of strings to populate drop downs. How do I set the value of each drop down option to the same as the text content?
el.value = opt; doesn't appear to work.
var validCoursesKeys = ['opt 1','opt 2','opt 3','opt 4']
var validKeys = document.getElementsByClassName("validKeys");
setFields("courses");
function setFields(browser) {
//document.getElementById("result").value = browser;
var menuCounter = 1;
if (browser == "courses") {
for (var i = 0; i < validCoursesKeys.length; i++) {
var opt = validCoursesKeys[i];
var el = document.createElement("option");
el.textContent = opt;
el.value = opt;
for (var j = 0; j < validKeys.length; j++) {
var elementClone = el.cloneNode(true);
elementClone.id = menuCounter;
menuCounter++;
validKeys[j].appendChild(elementClone);
}
}
} else if (browser == "rooms") {
var menuCounter = 1;
for (var i = 0; i < validRoomsKeys.length; i++) {
var opt = validRoomsKeys[i];
var el = document.createElement("option");
el.textContent = opt;
el.value = opt;
for (var j = 0; j < validKeys.length; j++) {
var elementClone = el.cloneNode(true);
elementClone.id = menuCounter;
menuCounter++;
validKeys[j].appendChild(elementClone);
}
}
}
};
<select class="validKeys"></select>
<select class="validKeys"></select>
<select class="validKeys"></select>

You can achieve this using jquery. See below updated code using jquery
var validKeys = document.getElementsByClassName("validKeys");
function setFields(browser) {
//document.getElementById("result").value = browser;
var menuCounter = 1;
if (browser == "courses") {
$.each(validCoursesKeys , function(index, keys) {
var content='<option value="' + keys + '">' + keys + '</option>';
validKeys.append(content);
});
} else if (browser == "rooms") {
var menuCounter = 1;
$.each(validRoomsKeys , function(index, keys) {
var content='<option value="' + keys + '">' + keys + '</option>';
validKeys.append(content);
});
}
};

Related

JS select correct line in select list

I am using this JS code to do some magic. Working perfect to get a variabele and remove unwanted text and display the correct text in a text field.
values 2 or 3 or 5 or 7 etc. in <input type="text" id="calc_dikte[0][]" name="calc_dikte[]" value="">
function copy_dikte()
{
var i;
var elems = document.getElementsByName('dxf_var_dikte_copy[]');
var elems_1 = document.getElementsByName('dxf_vars[]');
var elems_2 = document.getElementsByName('calc_dikte[]');
var elems_3 = document.getElementsByName('calc_ext[]');
var l = elems.length;
var z;
z=0;
for(i=0; i<l; i++)
{
if(elems_3[i].value == 'dxf')
{
elems[i].value = document.getElementById('dxf_var_dikte').value;
var elems_1_split_1 = (elems_1[i].value).split(elems[i].value+'=');
var elems_1_split_2 = (elems_1_split_1[1]).split(',');
if(isNaN(elems_1_split_2[0])) { elems_2[i].value = ''; }
else { elems_2[i].value = parseFloat(elems_1_split_2[0]); }
}
}
}
So this works, but now the form field has changed from text to select like:
<select id="calc_dikte[0][]" name="calc_dikte[]">
<option value="">
<option value="2|2000">2</option>
<option value="3|2000">3</option>
<option value="5|2000">5</option>
<option value="7|2000">7</option>
</select>
Therefore I have changed my JS code (with some tips from here) to:
function copy_dikte()
{
var i;
var elems = document.getElementsByName('dxf_var_dikte_copy[]');
var elems_1 = document.getElementsByName('dxf_vars[]');
var elems_2 = document.getElementsByName('calc_dikte[]');
var elems_3 = document.getElementsByName('calc_ext[]');
var l = elems.length;
var z;
z=0;
for(i=0; i<l; i++)
{
if(elems_3[i].value == 'dxf')
{
elems[i].value = document.getElementById('dxf_var_dikte').value;
var elems_1_split_1 = (elems_1[i].value).split(elems[i].value+'=');
var elems_1_split_2 = (elems_1_split_1[1]).split(',');
var sel = elems_2[i];
var val = parseFloat(elems_1_split_2[0]);
for(var m=0, n=sel.options.length; m<n; m++)
{
if(sel.options[i].innerHTML === val)
{
sel.selectedIndex = m;
break;
}
}
}
}
}
But this is not working, no item is selected in the select list, no errors are shown.
Please help me out change to a working code to have the correct line selected. It should not select on the value but in the text between the ><
option value="5|2000">5</option
If I check with
for(var m=0, n=sel.options.length; m<n; m++) {
alert('sel = '+sel.options[i].innerHTML+'\nval = '+val);
}
I see that val is correct. But sel is just the number as used in $i so 0 1 2
You are using a strict equals operator to compare a Number (parseFloat) agains .innerHTML, which is always a string.
Convert sel.options[i].innerHTML to a Number aswell:
if (parseFloat(sel.options[i].innerHTML) === val) {
sel.selectedIndex = m;
break;
}
If you want to filter out invalid numbers (NaNs), use !isNaN(val) aswell.
Code to get this working:
function copy_dikte()
{
var i;
var elems = document.getElementsByName('dxf_var_dikte_copy[]');
var elems_1 = document.getElementsByName('dxf_vars[]');
var elems_2 = document.getElementsByName('calc_dikte[]');
var elems_3 = document.getElementsByName('calc_ext[]');
var l = elems.length;
var z;
z=0;
for(i=0; i<l; i++)
{
if(elems_3[i].value == 'dxf')
{
elems[i].value = document.getElementById('dxf_var_dikte').value;
var elems_1_split_1 = (elems_1[i].value).split(elems[i].value+'=');
var elems_1_split_2 = (elems_1_split_1[1]).split(',');
var val = parseFloat(elems_1_split_2[0]);
var sel = elems_2[i];
var opts = sel.options;
for (var opt, j = 0; opt = opts[j]; j++)
{
if (opt.text == val)
{
sel.selectedIndex = j;
break;
}
}
}
}
}

adding inputs in for loop

I have code like that https://jsfiddle.net/Lcfnxxtv/ and i'd like to labels look like that eg.
Number of children
ages 5 - 18"
I want it in two separate lines and NOT all in one line(of course, if it's possible) 'Number of children ages 5 - 18' but i don't know how to do this in my code.
jQuery(document).ready(function() {
var array1 = [];
var array2 = [];
var array_typ = [];
var array_dla = [];
var array_wie = [];
var array_cen = [];
var array_licz = [];
var str = jQuery("#all_str").val();
array1 = str.split('#');
var size = array1.length;
var str1 = "Tax A - child";
var str2 = "Tax A - elder";
var str1w = "Number of children";
var str2w = "Number of elders";
var html = "</div>";
var html2 = "";
for (i = 0; i < size; i++) {
array2 = array1[i].split('#');
array_typ[i] = array2[0];
array_dla[i] = array2[1];
array_wie[i] = array2[2];
array_cen[i] = array2[3];
}
for (j = 0; j < size; j++) {
if (array_dla[j] == str1) {
if (jQuery.inArray(str1w, array_licz) == -1) {
array_licz[j] = str1w;
}
}
if (array_dla[j] == str2) {
if (jQuery.inArray(str2w, array_licz) == -1) {
array_licz[j] = str2w;
}
}
}
var size2 = array_licz.length;
for (k = 0; k < size2; k++) {
html += ' <label for="field[' + k + ']">' + array_licz[k] + ' ages ' + array_wie[k] + ' </label> ';
}
for (l = 0; l < size2; l++) {
html2 += '<input type="text" id="field' + l + '" value=""></input> ';
}
html += '</br>';
html += html2;
html += '</div>';
jQuery("#addon").append(html);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="addon"></div>
<input type="hidden" id="all_str" value="XYZ#Tax A - elder#65-99#1#XYZ#Tax A - child#5-18#2#">
Please help
You have invalid tags. Input is a void element and does not needs a closing </input> tag.
<br>, <br/> are valid. </br> is not.
You have one useless for(l=0; l<size2; l++){
Use only the first k one.
Than in CSS set your label to display: block;
jQuery(function( $ ) {
var array1 = [];
var array2 = [];
var array_typ = [];
var array_dla = [];
var array_wie = [];
var array_cen = [];
var array_licz = [];
var str = $("#all_str").val();
array1 = str.split('#');
var size = array1.length;
var str1 = "Tax A - child";
var str2 = "Tax A - elder";
var str1w = "Number of children";
var str2w = "Number of elders";
var html = ""; // </div> ?? You mean Start of a <div>. BTW you have <label> already so ""
// html2 why??
for (i = 0; i < size; i++) {
array2 = array1[i].split('#');
array_typ[i] = array2[0];
array_dla[i] = array2[1];
array_wie[i] = array2[2];
array_cen[i] = array2[3];
}
for (j = 0; j < size; j++) {
if (array_dla[j] == str1) {
if ($.inArray(str1w, array_licz) == -1) {
array_licz[j] = str1w;
}
}
if (array_dla[j] == str2) {
if ($.inArray(str2w, array_licz) == -1) {
array_licz[j] = str2w;
}
}
}
var size2 = array_licz.length;
// Why loop twice size2. Loop once
for (k = 0; k < size2; k++) {
html += '<label for="field[' + k + ']">' +
array_licz[k] + '<br>ages ' + array_wie[k] +
'<br><input type="text" id="field' + k + '" value="">'+
' </label>';
}
$("#addon").append(html);
});
label{
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="addon"></div>
<input type="hidden" id="all_str" value="XYZ#Tax A - elder#65-99#1#XYZ#Tax A - child#5-18#2#">
The other part of your code can be also improved, but I have no idea what you're after with all those arrays...
$(document).ready(function() {
var array1 = [];
var array2 = [];
var array_typ = [];
var array_dla = [];
var array_wie = [];
var array_cen = [];
var array_licz = [];
var str = $("#all_str").val();
array1 = str.split('#');
var size = array1.length;
var str1 = "Tax A - child";
var str2 = "Tax A - elder";
var str1w = "Number of children";
var str2w = "Number of elders";
var html = "</div>";
var html2 = [];
var html3 = [];
for(i=0; i<size; i++){
array2= array1[i].split('#');
array_typ[i] = array2[0];
array_dla[i] = array2[1];
array_wie[i] = array2[2];
array_cen[i] = array2[3];
}
for(j=0; j<size; j++){
if(array_dla[j]==str1){
if($.inArray(str1w, array_licz) == -1){
array_licz[j]=str1w;
}
}
if(array_dla[j]==str2){
if($.inArray(str2w, array_licz) == -1){
array_licz[j]=str2w;
}
}
}
var size2 = array_licz.length;
for(k=0; k<size2; k++){
html3[k]='<label for="field['+ k +']">'+array_licz[k]+' ages <br>' +array_wie[k] +' </label> <br>';
}
for(l=0; l<size2; l++){
html2[l]='<input type="text" id="field'+l+'" value=""</input> <br></br>';
}
for(var j=0;j<size2;j++){
html += html3[j]+html2[j];
}
//html+='</br>';
//html+=html2;
html+='</div>';
$("#addon").append(html);
});
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="addon">
</div>
<input type="hidden" id="all_str" value="XYZ#Tax A - elder#65-99#1#XYZ#Tax A - child#5-18#2#">
Your problem was the way you put the strings together. An easy solution is to use arrays and in the end you can manipulate them more easily

Perfoming formulas/calculations based off of selections on a dropdown menu?

var stocks = [
['Apple',100,8998,723,7212],
['Microsoft',928,1992,821,2381]
];
var select = document.getElementById("selectStock");
for(var i = 0; i < stocks.length; i++) {
var opt = stocks[i][0];
var el = document.createElement("option");
el.textContent = opt;
el.value = opt;
select.appendChild(el);
}
<select id="selectStock">
<option>Choose a stock</option>
</select>
I have multiple Javascript arrays of data (pulled from Excel) and have different functions that basically make calculations based on the row of the array. For example:
var stocks = [['Apple',100,8998,723,7212]['Microsoft,928,1992,821,2381]]
What I need to do is make a dropdown menu that will allow a user to select an option (Microsoft or Apple) and then based on this selection, will pull this value into the formula to make the calculations
document.write(Math.round(stocks[i][1] * 100)/100 + " dollars per share");
where i is the variable based off dropdown menu selection. Does this make sense? I'm not sure how to approach this, it's for a personal project. Thanks for the help!
https://jsfiddle.net/b22y3v85/
var select = document.getElementById("selectStock");
select.onchange = (e) => {
let index = stocks.indexOf(stocks.find(a => a.indexOf(e.target.value) > -1));
document.write(Math.round(stocks[index][1] * 100)/100 + " dollars per share");
};
Here is a working example, although you'll probably want to do something other than document.write the result.
var stocks = [
['Apple',100,8998,723,7212],
['Microsoft',928,1992,821,2381]
];
var select = document.getElementById("selectStock");
for(var i = 0; i < stocks.length; i++) {
var opt = stocks[i][0];
var el = document.createElement("option");
el.textContent = opt;
el.value = opt;
select.appendChild(el);
}
function getPrice(stock) {
var price = false;
for (var a = 0; a < stocks.length; a++) {
if (stocks[a][0] == stock) {
price = stocks[a][1];
break;
}
}
if (!price) { alert("Incorrect choice."); return; }
document.getElementById("result").innerText = stock + " is currently " + (Math.round(price * 100)/100 + " dollars per share");
}
<select id="selectStock" onchange="getPrice(this.value);">
<option>Choose a stock</option>
</select>
<br><br>
<div id="result"></div>
EDIT: Shows result in a div on the page, instead of overwriting the page with document.write().
<select id="selectStock"></select>
<script type="text/javascript">
var stocks = [
['Apple',100,8998,723,7212],
['Microsoft',928,1992,821,2381]
];
var select = document.getElementById("selectStock");
for(var i = 0; i < stocks.length; i++) {
var opt = stocks[i][0];
var el = document.createElement("option");
el.innerHTML = opt;
el.value =stocks[i]+'';
select.appendChild(el);
}
select.addEventListener('change', function(e){
var val = e.currentTarget.value;
val = val.split(',');
val.shift();
callYourMethod(val);
});
</script>

Not able add multiple option to select

function successCallback(caRecords) {
var x = document.getElementById("custAccount"); // select
var option1 = document.createElement("option"); //options
//var accno = 0;
// caRecords i am fetch from MS CRM
var count = caRecords[0].results.length;
if (caRecords != null && count > 0) {
alert("records are not null");
for (var i = 0 ; i < count; i++)
{
var text = caRecords[0].results[i].new_name;
// alert(text + "J=" + j);
option1.text = text;
option1.value = j;
x.add(option1);
j++;
}
}
I got six records and try to insert that values into select as option. It showing last value of my 6 values.
Can anyone help me to improve my code?
You can iterate your values like this...
function successCallback(caRecords) {
var x = document.getElementById("custAccount"); // select
var options = "";
var count = caRecords[0].results.length;
if (caRecords != null && count > 0) {
alert("records are not null");
for (var i = 0; i < count; i++) {
options += "<option value=" + j + ">" + caRecords[0].results[i].new_name + "</option>";
j++;
}
x.innerHTML = options;
}

document.createElement Performance: Edge/IE11 too slow v/s Chrome/Firefox

Some of the web portals that I maintain use document.createElement to create options in a dropdownlist at runtime. All was well till IE10 but in IE11 or Edge suddenly the performance has gone down dramatically.
I have created a Fiddle: https://jsfiddle.net/nitinph/ej5p65um/
Please run it using both the sets of browsers (IE11/Edge and Chrome/Firefox). You will notice that IE11/Edge takes 10+ seconds whereas Chrome/Firefox takes less than a second.
My question is that is there any alternate way for using document.createElement so that performance is similar in IE11/Edge.
var pTime = document.getElementById("pTime");
var d = new Date();
var n = d.getTime();
var ddl = document.getElementById("TestDDL");
for (var i = 0; i < 5000; i++) {
var opt = document.createElement("option");
opt.text = i;
opt.value = i;
ddl.options.add(opt);
}
d = new Date();
var n1 = d.getTime();
pTime.innerHTML = 'Time: ' + (n1 - n) / 1000 + ' sec.';
<select id="TestDDL">
</select>
<p id="pTime">
</p>
Update: Courtesy #Squint, here are the four alternatives to achieve performance in IE11/Edge:
var ddl = document.getElementById("TestDDL");
console.time("html")
var s = ""
for (var i = 0; i < 5000; i++) {
s += "<option value='" + i + '>' + i + "</option>"
}
ddl.innerHTML = s;
console.timeEnd("html")
clearContent()
console.time("insertAdjacentHTML")
for (var i = 0; i < 5000; i++) {
ddl.insertAdjacentHTML("beforeend", "<option value='" + i + '>' + i + "</option>")
}
console.timeEnd("insertAdjacentHTML")
clearContent()
console.time("frag")
var frag = document.createDocumentFragment();
for (var i = 0; i < 5000; i++) {
var opt = document.createElement("option");
opt.text = i;
opt.value = i;
frag.appendChild(opt);
}
ddl.appendChild(frag);
console.timeEnd("frag")
clearContent()
console.time("direct add")
for (var i = 0; i < 5000; i++) {
var opt = document.createElement("option");
opt.text = i;
opt.value = i;
ddl.options.add(opt);
}
console.timeEnd("direct add")
function clearContent() {
while (ddl.firstChild) {
ddl.removeChild(ddl.firstChild)
}
}
clearContent()
console.time("direct append")
for (var i = 0; i < 5000; i++) {
var opt = document.createElement("option");
opt.text = i;
opt.value = i;
ddl.appendChild(opt);
}
console.timeEnd("direct append")
function clearContent() {
while (ddl.firstChild) {
ddl.removeChild(ddl.firstChild)
}
}
<select id="TestDDL">
</select>
<p id="pTime">
</p>
You could construct the element HTML with strings:
var optionList = ["foo", "bar", "baz"];
var elementHTML = "";
for (var index = 0; index < optionList.length; index++) {
elementHTML += "<option>" + optionList[index] + "</option>";
}
Then create the element and set the innerHTML
var element = document.createElement("select");
element.innerHTML = elementHTML;
This usually offers much better performance as you only call document.createElement() once. Direct dynamic DOM processing, sadly, is usually pretty slow and is recommended against.

Categories