Converting repetative javascript statements to arrays in loops - javascript

I am dynamically changing the options in 8 selects based on a separate selected option.
The process handles counties in a state and updating all 8 selects for each county in a state is terribly repetitive as each option can only exist in one select.
My original code was thrown together quickly but worked fine:
FLCounties = [
"Alachua",
"Baker",
"Bay",
"etc."];
//Get the selects
var countyDrop1 = document.getElementById("county1");
var countyDrop2 = document.getElementById("county2");
var countyDrop3 = document.getElementById("county3");
var countyDrop4 = document.getElementById("county4");
var countyDrop5 = document.getElementById("county5");
var countyDrop6 = document.getElementById("county6");
var countyDrop7 = document.getElementById("county7");
var countyDrop8 = document.getElementById("county8");
//Get the default state if any
var initialState = document.getElementById("state").value;
getState(initialState);
//Called from onchange on the state select
function getState(sel) {
//Clear previous options and add a notice to select a state
while (countyDrop1.firstChild) {
countyDrop1.removeChild(countyDrop1.firstChild);
};
var defaultEl1= document.createElement("option");
defaultEl1.textContent = "Select a state above first.";
defaultEl1.value = "";
countyDrop1.appendChild(defaultEl1);
while (countyDrop2.firstChild) {
countyDrop2.removeChild(countyDrop2.firstChild);
};
var defaultEl2= document.createElement("option");
defaultEl2.textContent = "Select a state above first.";
defaultEl2.value = "";
countyDrop2.appendChild(defaultEl2);
while (countyDrop3.firstChild) {
countyDrop3.removeChild(countyDrop3.firstChild);
};
var defaultEl3= document.createElement("option");
defaultEl3.textContent = "Select a state above first.";
defaultEl3.value = "";
countyDrop3.appendChild(defaultEl3);
while (countyDrop4.firstChild) {
countyDrop4.removeChild(countyDrop4.firstChild);
};
var defaultEl4= document.createElement("option");
defaultEl4.textContent = "Select a state above first.";
defaultEl4.value = "";
countyDrop4.appendChild(defaultEl4);
while (countyDrop5.firstChild) {
countyDrop5.removeChild(countyDrop5.firstChild);
};
var defaultEl5= document.createElement("option");
defaultEl5.textContent = "Select a state above first.";
defaultEl5.value = "";
countyDrop5.appendChild(defaultEl5);
while (countyDrop6.firstChild) {
countyDrop6.removeChild(countyDrop6.firstChild);
};
var defaultEl6= document.createElement("option");
defaultEl6.textContent = "Select a state above first.";
defaultEl6.value = "";
countyDrop6.appendChild(defaultEl6);
while (countyDrop7.firstChild) {
countyDrop7.removeChild(countyDrop7.firstChild);
};
var defaultEl7= document.createElement("option");
defaultEl7.textContent = "Select a state above first.";
defaultEl7.value = "";
countyDrop7.appendChild(defaultEl7);
while (countyDrop8.firstChild) {
countyDrop8.removeChild(countyDrop8.firstChild);
};
var defaultEl8= document.createElement("option");
defaultEl8.textContent = "Select a state above first.";
defaultEl8.value = "";
countyDrop8.appendChild(defaultEl8);
//if no state is selected, do nothing
if (sel != ""){
switch (sel){
//value of option Florida
case "FL":
//change "select a state first" to "select a county"
countyDrop1.firstChild.textContent = "- Select a County -";
countyDrop2.firstChild.textContent = "- Select a County -";
countyDrop3.firstChild.textContent = "- Select a County -";
countyDrop4.firstChild.textContent = "- Select a County -";
countyDrop5.firstChild.textContent = "- Select a County -";
countyDrop6.firstChild.textContent = "- Select a County -";
countyDrop7.firstChild.textContent = "- Select a County -";
countyDrop8.firstChild.textContent = "- Select a County -";
for(var i = 0; i < FLCounties.length; i++) {
var opt = FLCounties[i];
var el1 = document.createElement("option");
el1.textContent = opt;
el1.value = opt;
var el2 = document.createElement("option");
el2.textContent = opt;
el2.value = opt;
var el3 = document.createElement("option");
el3.textContent = opt;
el3.value = opt;
var el4 = document.createElement("option");
el4.textContent = opt;
el4.value = opt;
var el5 = document.createElement("option");
el5.textContent = opt;
el5.value = opt;
var el6 = document.createElement("option");
el6.textContent = opt;
el6.value = opt;
var el7 = document.createElement("option");
el7.textContent = opt;
el7.value = opt;
var el8 = document.createElement("option");
el8.textContent = opt;
el8.value = opt;
countyDrop1.appendChild(el1);
countyDrop2.appendChild(el2);
countyDrop3.appendChild(el3);
countyDrop4.appendChild(el4);
countyDrop5.appendChild(el5);
countyDrop6.appendChild(el6);
countyDrop7.appendChild(el7);
countyDrop8.appendChild(el8);
}
break;
[rinse and repeat, 49 times]
I tried condensing it into a series of arrays and for loops, which really shortens the code, but it breaks the page (an infinite loop somewhere I'm sure).
New code (does not work):
var FLCounties = [
//same as above
];
var dropdowns = [
countyDrop1 = document.getElementById("county1"),
countyDrop2 = document.getElementById("county2"),
countyDrop3 = document.getElementById("county3"),
countyDrop4 = document.getElementById("county4"),
countyDrop5 = document.getElementById("county5"),
countyDrop6 = document.getElementById("county6"),
countyDrop7 = document.getElementById("county7"),
countyDrop8 = document.getElementById("county8")
];
var defaultOptions = [
defaultEl1 = document.createElement("option"),
defaultEl2 = document.createElement("option"),
defaultEl3 = document.createElement("option"),
defaultEl4 = document.createElement("option"),
defaultEl5 = document.createElement("option"),
defaultEl6 = document.createElement("option"),
defaultEl7 = document.createElement("option"),
defaultEl8 = document.createElement("option")
];
var options = [
el1 = document.createElement("option"),
el2 = document.createElement("option"),
el3 = document.createElement("option"),
el4 = document.createElement("option"),
el5 = document.createElement("option"),
el6 = document.createElement("option"),
el7 = document.createElement("option"),
el8 = document.createElement("option")
];
var initialState = document.getElementById("state").value;
getState(initialState);
function getState(sel) {
//new clear list
for(i=0;i<8;i++){
while (dropdowns[i].firstChild) {
dropdowns[i].removeChild(dropdowns[i].firstChild);
}
defaultOptions[i].textContent = "Select a state above first.";
defaultOptions[i].value = "";
dropdowns[i].appendChild(defaultOptions[i]);
}
if (sel != ""){
var opt;
switch (sel){
case "FL":
//new change "select a state first" to "select a county"
for (i=0;i<8;i++){
dropdowns[i].firstChild.textContent = "- Select a County -";
}
//new create 8 unique options and add them to the selects
for(i=0;i<FLCounties.length;i++){
opt = FLCounties[i];
for (i=0;i<8;i++){
options[i].textContent = opt;
options[i].value = opt;
for(i=0;i<8;i++){
dropdowns[i].appendChild(options[i]);
}
}
}
break;
}
}
}
Am I missing something? This should execute quicker right? Instead its holding the page from loading indefinitely.
Edit: I did find one glaring problem. The dropdowns[i].appendChild(options[i]); loop should not be in the loop above it. It should run after options has been set.
New snippet:
//new create 8 unique options and add them to the selects
for(i=0;i<FLCounties.length;i++){
opt = FLCounties[i];
for (i=0;i<8;i++){
options[i].textContent = opt;
options[i].value = opt;
}
for(i=0;i<8;i++){
dropdowns[i].appendChild(options[i]);
}
}
Edit 2:
I ran into a problem when taking a step back.
It stems from using the array of options in a loop. I knew each option element could only exist in a select once, but didn't follow that logic when writing the loop. The same option element (options[i]) is being changed and reused in each iteration, which wont work, you only get the last iteration's results. I believe this worked in the old code because it redefined the element in each iteration, not just changed it's attributes
Does this rule an array out for this use?

That's not how you add elements to an array
var dropdowns = [
countyDrop1 = document.getElementById("county1"),
countyDrop2 = document.getElementById("county2"),
countyDrop3 = document.getElementById("county3")
];
should be
var dropdowns = [
document.getElementById("county1"),
document.getElementById("county2"),
document.getElementById("county3")
];
which you would then access like so
dropdown[0] // gives county1
you may want to use an object instead (note the difference [] becomes {})
var dropdowns = {
'county1':document.getElementById("county1"),
'county2':document.getElementById("county2"),
'county3':document.getElementById("county3")
};
which you can then access like so
dropdown.county1

As I noted in the comments above, when adding the options to the select, I cannot use an array. II ended up using a two dimensional array for the counties, and a second array for the state codes that my php script submits to the form.
I realize that the arrays would be better defined as objects, but the deadline for the project is up and this code is efficient enough for production use. Here is a condensed version of my final code (until things slow down and I find time to revisit the code):
ALCounties = ["Autauga","Baldwin","Barbour","Bibb",etc];
AKCounties = ["Anchorage Borough","Bethel Census Area",etc];
etc
stateCountyList = [ALCounties,AKCounties,etc];
stateCode = [ "AL","AK","AZ","AR",etc];
countyDrops = [
document.getElementById("county1"),
document.getElementById("county2"),
document.getElementById("county3"),
document.getElementById("county4"),
document.getElementById("county5"),
document.getElementById("county6"),
document.getElementById("county7"),
document.getElementById("county8")
];
defaultOpts = [
document.createElement("option"),
document.createElement("option"),
document.createElement("option"),
document.createElement("option"),
document.createElement("option"),
document.createElement("option"),
document.createElement("option"),
document.createElement("option")
];
//If a user loads the page with a state previously stored in the db
var initialState = document.getElementById("state").value;
getState(initialState);
// Replaces the switch in the old code.
// Passed value of option in state select on the page, matches it to a var in stateCode, calls updateState to create a list for that state
function getState(sel) {
clearSetFirst(" - Select a state above first. - ");
if (sel != ""){
var valid = false;
for (i=0;i<stateCode.length;i++){
if(sel == stateCode[i]){
updateState(stateCountyList[i]);
valid = true;
break;
}
}
if(!valid){
clearSetFirst(" - Not available for this state. - ")
}
}
}
//Creates the list
function updateState(state){
clearSetFirst("- Select a County -");
for(var i = 0; i < state.length; i++) {
var opt = state[i];
//These CANNOT be a reused array, options must be unique, so they are redecalred each iteration.
var el1 = document.createElement("option");
el1.textContent = opt;
el1.value = opt;
var el2 = document.createElement("option");
el2.textContent = opt;
el2.value = opt;
var el3 = document.createElement("option");
el3.textContent = opt;
el3.value = opt;
var el4 = document.createElement("option");
el4.textContent = opt;
el4.value = opt;
var el5 = document.createElement("option");
el5.textContent = opt;
el5.value = opt;
var el6 = document.createElement("option");
el6.textContent = opt;
el6.value = opt;
var el7 = document.createElement("option");
el7.textContent = opt;
el7.value = opt;
var el8 = document.createElement("option");
el8.textContent = opt;
el8.value = opt;
//I thought about
countyDrops[0].appendChild(el1);
countyDrops[1].appendChild(el2);
countyDrops[2].appendChild(el3);
countyDrops[3].appendChild(el4);
countyDrops[4].appendChild(el5);
countyDrops[5].appendChild(el6);
countyDrops[6].appendChild(el7);
countyDrops[7].appendChild(el8);
}
}
// Clears the list if no value is selected and sets the first options text to msg
function clearSetFirst(msg){
for (var i=0;i<8;i++){
if (countyDrops[i].value == "") {
while (countyDrops[i].firstChild) {
countyDrops[i].removeChild(countyDrops[i].firstChild);
}
defaultOpts[i].textContent = msg;
defaultOpts[i].value = "";
countyDrops[i].appendChild(defaultOpts[i]);
}
}
}
Thank you all for your support. I am definitely open to suggestions for further optimizations, as the code is still 31 KB due to the size of the arrays.

Related

Get values of multiple select boxes in PHP and add them to an array

I have a button which allows an ingredient to be added to a database. When the button is clicked, the user can add the name, measurement and unit for the ingredient which is done using Javascript:
function addIngredient() {
var area = document.getElementById("addedIngredient");
var num = document.createElement("p");
numText = document.createTextNode(countIngredient + ". ");
num.appendChild(numText);
area.appendChild(num);
//Ingredient Name
var ingredientNameLabel = document.createElement("p");
ingredientNameLabelText = document.createTextNode("Name");
ingredientNameLabel.appendChild(ingredientNameLabelText);
area.appendChild(ingredientNameLabel);
countIngredient++;
var ingredientNameInput = document.createElement("INPUT");
ingredientNameInput.setAttribute("name", "ingredient_name[]");
ingredientNameInput.setAttribute("type", "text");
ingredientNameInput.setAttribute("class", "form-control");
ingredientNameInput.setAttribute("class", "ingName");
area.appendChild(ingredientNameInput);
//Ingredient Measure
var ingredientMeasureLabel = document.createElement("p");
ingredientMeasureLabelText = document.createTextNode("Measure");
ingredientMeasureLabel.appendChild(ingredientMeasureLabelText);
area.appendChild(ingredientMeasureLabel);
var ingredientMeasureInput = document.createElement("INPUT");
ingredientMeasureInput.setAttribute("name", "ingredient_measure[]");
ingredientMeasureInput.setAttribute("type", "text");
ingredientMeasureInput.setAttribute("class", "form-control");
ingredientMeasureInput.setAttribute("class", "ingMeasure");
area.appendChild(ingredientMeasureInput);
//Ingredient Unit
var ingredientUnitLabel = document.createElement("p");
ingredientUnitLabelText = document.createTextNode("Unit");
ingredientUnitLabel.appendChild(ingredientUnitLabelText);
area.appendChild(ingredientUnitLabel);
var select = document.createElement("SELECT");
select.setAttribute("name", "ingredient_unit[]");
area.appendChild(select);
var option = document.createElement("option");
option.setAttribute("value", "grams");
var value = document.createTextNode("g");
option.appendChild(value);
select.appendChild(option);
var option = document.createElement("option");
option.setAttribute("value", "milimeters");
var value = document.createTextNode("ml");
option.appendChild(value);
select.appendChild(option);
var option = document.createElement("option");
option.setAttribute("value", "kilograms");
var value = document.createTextNode("kg");
option.appendChild(value);
select.appendChild(option);
var option = document.createElement("option");
option.setAttribute("value", "litres");
var value = document.createTextNode("litre(s)");
option.appendChild(value);
select.appendChild(option);
var option = document.createElement("option");
option.setAttribute("value", "slice");
var value = document.createTextNode("slice");
option.appendChild(value);
select.appendChild(option);
var option = document.createElement("option");
option.setAttribute("value", "whole");
var value = document.createTextNode("whole");
option.appendChild(value);
select.appendChild(option);
var option = document.createElement("option");
option.setAttribute("value", "pinch");
var value = document.createTextNode("pinch");
option.appendChild(value);
select.appendChild(option);
}
I am looking to get the unit selected for every ingredient added.
Can anyone tell me how I could do this using PHP?
I am trying the following way:
$units = [];
foreach ($_POST["ingredient_unit[]"] as $key => $unit) {
array_push($units, $unit);
}
This does not work nor does it give an error.
Thanks.
Change the following code:
foreach ($_POST["ingredient_unit[]"] as $key => $unit) {
array_push($units, $unit);
}
And use this instead:
foreach ($_POST["ingredient_unit"] as $key => $unit) {
array_push($units, $unit);
}
And you should be getting a notice when you try to access $_POST["ingredient_unit[]"] since its not defined. If you are not seeing a notice, maybe the error_reporting level is too low. You could use something like the following to active all errors except the deprecated ones:
error_reporting(E_ALL &~ E_DEPRECATED);

How to create Check Boxes in dynamic drop down box using JavaScript?

function fetchList(ss){
var select = document.getElementById("storeid");
var options = ss;
while (select.options[1]) {
select.removeChild(select.options[1]);
}
for(var i = 0; i < options.length; i++) {
var opt = options[i];
var el = document.createElement("option");
el.textContent = opt;
el.value = opt;
select.appendChild(el);
}
}
This way I am able to display the list in the drop down,so how can I display check boxes in the options for multiple selection?

Replacing option in select field (not adding)

I have a select field as follows:
<select id="field">
I add options based on values found in another div (OtherDiv) on my page like this:
window.onload = function onload()
{
var OtherDiv = document.getElementById('OtherDiv').innerHTML;
var result = OtherDiv.match(/SomeRegex/gi);
var select = document.getElementById("field");
for(var i = 0; i < result.length; i++)
{
var option = document.createElement("option");
option.value = i+1;
option.innerHTML = result[i];
select.add(option);
}
}
However, I would like to set up some alternative value for the field to show, if there are no matches to the regex. How would I best achieve that?
Use if condition
window.onload = function onload()
{
var OtherDiv = document.getElementById('OtherDiv').innerHTML;
var result = OtherDiv.match(/SomeRegex/gi);
var select = document.getElementById("field");
if(result.length){
for(var i = 0; i < result.length; i++)
{
var option = document.createElement("option");
option.value = i+1;
option.innerHTML = result[i];
select.add(option);
}
}else{
//add alternative options here
var option = document.createElement("option");
option.innerHTML = "No records found"; //whatever text you want to show
select.add(option);
}
}

Object Drop Down List

I have an empty drop down list in HTML. I am trying to add new attribute into the list using .createElement('option') method. However, the item i want to add has name, address, and phone number so how can i add,as an object, into drop down list? Thank you for reading it.
Im not sure if this is what you wanted, I got it from https://developer.mozilla.org/en-US/docs/Web/API/HTMLSelectElement/add
var sel = document.getElementById("existingList");
var opt = document.createElement("option");
opt.value = "3";
opt.text = "Option: Value 3";
sel.add(opt, sel.options[1]);
[Edit]
Im pretty tierd and the code is not the best. Maybe you can play around with it and see if it fits your code.
var sel = document.createElement("droplist");
var opt1 = document.createElement("OPTION");
var opt2 = document.createElement("OPTION");
var opt3 = document.createElement("OPTION");
var information = {
names: ["nameOne", "nameTwo"],
addresses: ["adressOne", "adressTwo"],
names: ["phoneOne", "phoneTwo"],
informationFunction: function additem(){
opt1.value = "1";
opt1.text = this.addresses[0];
opt2.value = "2";
opt2.text = this.addresses[1];
opt3.value = "3";
opt3.text = this.addresses[3];
sel.appendChild(opt1);
sel.appendChild(opt2);
sel.appendChild(opt3);
}
};
information.informationFunction();

Select Specific Elements in Array for Dropdown

I am trying to use JavaScript and jQuery to generate a dropdown list from the values in one particular element of an array.
My array is defined as a variable and looks like this:
var ht_parties = [
{
"id_Group": "41DC3C63-F423-4941-ACF7-63118BD9CE19",
"name": "Ayiti An Aksyon",
"nameAbbreviated": "AAA",
"nameAcronym": "AAA"
},
{
"id_Group": "9AF9E215-0376-460F-B69A-F380F35729CA",
"name": "ACAAU",
"nameAbbreviated": "ACAAU",
"nameAcronym": "ACAAU"
}
]
The code to generate the dropdown is as follows:
var select = document.getElementById("selectNumber");
var options = ht_parties;
for ( var i = 0; i < options.length; i++) {
var opt = options[i];
var el = document.createElement("option");
el.text = opt;
el.value = opt;
select.appendChild(el);
};
I want the dropdown to populated with the values of the array element "name". However, this is currently generating a dropdown with the list items as "[object Object]". How do I select only the element "name" from the array and populate the dropdown with it?
you need to specify which key on opts you want to set to the el's text and value
el.text = opt;
el.value = opt;
needs to be something like
el.text = opt.name;
el.value = opt.name;
(or whichever keys you want to set)
use this
var select = document.getElementById("selectNumber");
var options = ht_parties;
for ( var i = 0; i < options.length; i++) {
var opt = options[i];
var el = document.createElement("option");
el.text = opt.name;
el.value = opt.name;
select.appendChild(el);
};

Categories

Resources