Javascript - Creating an li element using a checkbox array but with two values per checkbox?

44 Views Asked by At

Alright so I have three checkboxes with the values of Profile, Online, and Storage. I can get all those pushed to an array when checked and I can get the li elements created per checked item.

The issue is that each of those items also has a second "value" being "+$1/mo", "+$2/mo", and "+$2/mo".

Where I'm stuck is figuring out how to attach those second "values" to the first values so that when an item is checked, it creates an li element with one p element being the name value (i.e. Profile) and a second p element with the cost value (i.e. "+$2/mo").

Here is the code for one of the inputs:

 <input
    id="profile-checkbox"
    type="checkbox"
    value="Custom profile"
    name="add-ons"
    onclick="getAddons()"
    class="w-5 h-5 mr-2 text-blue-600 bg-gray-100 border-light-gray rounded"
  />

The JS global variables

const addonsResultList = document.getElementById("add-ons-result-list");
let addonsResult = [];

The function to get the checkbox values

// Step 3, add-ons
function getAddons() {
    let checkboxes = document.getElementsByName("add-ons");

    addonsResult = [];

    for (let i = 0; i < checkboxes.length; i++) {
        if (checkboxes[i].checked) {
            addonsResult.push(checkboxes[i].value);
        }
    }
}

And the function that adds everything to the results page:

function setResultsPage() {
addonsResult.forEach(function (addon) {
        const li = document.createElement("li");
        const pName = document.createElement("p");
        const pAmount = document.createElement("p");
        const text = document.createTextNode(addon);

        li.classList.add("flex", "justify-between");

        pName.appendChild(text);
        pName.classList.add("text-cool-gray", "text-sm");

        pAmount.appendChild();
        pAmount.classList.add("text-sm", "text-marine-blue");

        li.appendChild(pName);
        addonsResultList.appendChild(li);
    });
}

As of right now, I can successfully create an li element for which ever checkboxes were checked but only for the name. Getting the second "value" (amount) to be linked up with the correct first value (name) and added into the pAmount element is where I'm stuck.

1

There are 1 best solutions below

0
Brandon J. Boone On

I would consider creating objects to represent each item you'd like to render and then reference that object via the checkbox's value property.

Alternatively you could store multiple items in the checkbox's value via a delimiter (|, , ex: value="Custom profile|+$1/mo") or via a serialized object as JSON (vaule='{ "name": "Custom profile", "value": "+$1/mo" }'). You would need to split on the delimiter or deserialize the JSON into an object for each item in the addonsResult collection.

I've provided an example that uses a referenced array of objects below along with some comments.

const addonsResultList = document.getElementById("add-ons-result-list");
let addonsResult = [];

// 1. Put your addons in an array
// Note: you can also generate the input controls (checkboxes) from this collection.
// 2. Assign the value of each input to the index of the array
// 3. Use the index stored in the checkbox's value to find the 
// item it represents. 
let addons = [
  { name: "Custom profile", value: "+$1/mo" },
  { name: "Custom profile 2", value: "+$2/mo" },
  { name: "Custom profile 3", value: "+$3/mo" }
];

// Step 3, add-ons
function getAddons() {
    let checkboxes = document.getElementsByName("add-ons");

    addonsResult = [];

    for (let i = 0; i < checkboxes.length; i++) {
        if (checkboxes[i].checked) {
            // pull out the addon from the array by the index
            // stored in the checkbox's value
            addonsResult.push(addons[checkboxes[i].value]);
        }
    }
}

function setResultsPage() {
  addonsResultList.innerHTML = "";
  addonsResult.forEach(function (addon) {
    const li = document.createElement("li");
    const pName = document.createElement("p");
    const pAmount = document.createElement("p");
    const textName = document.createTextNode(addon.name);
    const textAmmount = document.createTextNode(addon.value);

    li.classList.add("flex", "justify-between");
 
    pName.appendChild(textName);
    pName.classList.add("text-cool-gray", "text-sm");

    pAmount.appendChild(textAmmount);
    pAmount.classList.add("text-sm", "text-marine-blue");

    li.appendChild(pName);
    li.appendChild(pAmount);
    addonsResultList.appendChild(li);
  });
}
<label for="profile-checkbox1">Item 1</label>
<input
    id="profile-checkbox"
    type="checkbox"
    value=0
    name="add-ons"
    onclick="getAddons()"
    class="w-5 h-5 mr-2 text-blue-600 bg-gray-100 border-light-gray rounded"
/>

<label for="profile-checkbox2">Item 2</label>
<input
    id="profile-checkbox2"
    type="checkbox"
    value=1
    name="add-ons"
    onclick="getAddons()"
    class="w-5 h-5 mr-2 text-blue-600 bg-gray-100 border-light-gray rounded"
/>

<label for="profile-checkbox3">Item 3</label>
<input
    id="profile-checkbox3"
    type="checkbox"
    value=2
    name="add-ons"
    onclick="getAddons()"
    class="w-5 h-5 mr-2 text-blue-600 bg-gray-100 border-light-gray rounded"
/>
<br />
<button type="button" onclick="setResultsPage()">Set Results Page</button>

<div id="add-ons-result-list"></div>