Steps for incorporating the getElementByClassName() method

I have developed an application that features a list displayed as shown below:

https://i.stack.imgur.com/BxWF2.png

Upon clicking each tick mark, the corresponding Book name is added to a textbox below. I desire the tick mark to be replaced by a cross symbol which allows users to remove it.

Currently, when I click on any of the tick marks, only the first item in the list changes to a cross like this:

https://i.stack.imgur.com/tftkk.png

However, I want the tick next to the specific book to change into a cross, not just the first one at the top of the list.

I understand that this issue stems from the need for the items to be treated as class elements rather than ID tags, as using an ID tag always selects the first item with that particular ID. However, I am unsure about how to incorporate this change into my code even after attempting to wrap the tick and cross icons in divs with class names.

The JavaScript code involved looks like this:

function saveToList(event) {
    if (event.which == 13 || event.keyCode == 13) { 
    
function saveToFB(bookName) {
  
var user = firebase.auth().currentUser;
var bookList = firebase.database().ref('users/' + uid + '/');
var uid = user.uid;

// This will save data to Firebase
bookList.push({
    book: bookName
    });
};

// This part contains JS responsible for creating the lists based on Firebase data, divided into three lists each holding up to 10 books.
function refreshUI(list) {
var lis = '';
var lis2 = '';
var lis3 = '';

for (var i = 0; i < 10 && i < list.length; i++) {

// Creates the list item by adding the firebase object + genLinks which contains the select, remove, and delete icons. 
lis += '<li data-key="' + list[i].key + '">' + list[i].book + genLinks(list[i].key, list[i].book) +'</li>';
      };
      
for (var i = 10; i < 20 && i < list.length; i++) {
      
lis2 += '<li data-key="' + list[i].key + '">' + list[i].book + genLinks(list[i].key, list[i].book) +'</li>';
      };
      
for (var i = 20; i < 30 && i < list.length; i++) {
      
 lis3 += '<li data-key="' + list[i].key + '">' + list[i].book + genLinks(list[i].key, list[i].book) +'</li>';
      };
      
      // Populates the HTML lists with the JS list items
        document.getElementById('bookList').innerHTML = lis;
        document.getElementById('bookList2').innerHTML = lis2;
        document.getElementById('bookList3').innerHTML = lis3;
    };

...

A helpful suggestion was made to use getElementsByClassName(), however, no explanation was provided on how to implement it. If anyone could offer some guidance or advice on this matter, I would greatly appreciate it.

Thank you, G

Answer №1

Styling the icon display through CSS is a convenient method, especially when using checkboxes for selection indication. Retrieving the checked items becomes easy with a simple query and loop process.

function createList() {
   /* Collect checked checkboxes */
   var checkboxes = document.querySelectorAll('[name="books"]:checked');
   /* Iterate over elements to build value list */
   var out = [];    
   for (var i=0; i<checkboxes.length; i++) {
       out.push(checkboxes[i].value);       
   }
   /* Join values into a list and show them */
   document.getElementById("output").innerHTML = out.join(", ")
}
document.getElementById("booklist").addEventListener("change", createList);
createList();
[name="books"] {  /* Hide checkbox */
  display: none
}

[name="books"]+i+i { /* Hide the x when not checked */
  display: none
}

[name="books"]:checked+i {  /* Hide the check when checked */
  display: none
}

[name="books"]:checked+i+i { /* show the x when checked */
  display: inline
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />

<ul id="booklist">
  <li>
    <label>
      <span>Book 1</span>
      <input type="checkbox" value="book1" name="books" />
      <i class="fa fa-check-square-o" aria-hidden="true"></i>
      <i class="fa fa-times" aria-hidden="true"></i>
    </label>
  </li>
  <li>
    <label>
      <span>Book 2</span>
      <input type="checkbox" value="book2" name="books" checked/>
      <i class="fa fa-check-square-o" aria-hidden="true"></i>
      <i class="fa fa-times" aria-hidden="true"></i>
    </label>
  </li>
  <li>
    <label>
      <span>Book 3</span>
      <input type="checkbox" value="book3" name="books" />
      <i class="fa fa-check-square-o" aria-hidden="true"></i>
      <i class="fa fa-times" aria-hidden="true"></i>
    </label>
  </li>
  <li>
    <label>
      <span>Book 4</span>
      <input type="checkbox" value="book4" name="books" />
      <i class="fa fa-check-square-o" aria-hidden="true"></i>
      <i class="fa fa-times" aria-hidden="true"></i>
    </label>
  </li>
</ul>

<div id="output"></div>

To accommodate multiple lists, slight adjustments can be made. Utilizing data attributes to specify item outputs and applying event listeners to parent elements iteratively streamlines the handling of various lists.

(function() {
  function createList(listId) {
    /* Obtain checked checkboxes */
    var checkboxes = document.querySelectorAll('#' + listId + ' [name="books"]:checked');
    /* Gather values into a list by looping through elements */
    var out = [];
    for (var i = 0; i < checkboxes.length; i++) {
      out.push(checkboxes[i].value);
    }
    var outputId = document.getElementById(listId).dataset.output;
    /* Merge list and display it */
    document.getElementById(outputId).innerHTML = out.join(", ")
  }


  var lists = document.querySelectorAll(".book-list");
  for (var i = 0; i < lists.length; i++) {
    (function(list) {
      list.addEventListener("change", function() {
        createList(list.id)
      });
      createList(list.id);
    }(lists[i]))
  }
}());
[name="books"] {
  /* Hide checkbox */
  display: none
}

[name="books"]+i+i {
  /* Hide the x when not checked */
  display: none
}

[name="books"]:checked+i {
  /* Hide the check when checked */
  display: none
}

[name="books"]:checked+i+i {
  /* show the x when checked */
  display: inline
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />

<ul id="booklist1" class="book-list" data-output="output1">
  <li>
    <label>
      <span>Book 1</span>
      <input type="checkbox" value="book1" name="books" />
      <i class="fa fa-check-square-o" aria-hidden="true"></i>
      <i class="fa fa-times" aria-hidden="true"></i>
    </label>
  </li>
  <li>
    <label>
      <span>Book 2</span>
      <input type="checkbox" value="book2" name="books" checked/>
      <i class="fa fa-check-square-o" aria-hidden="true"></i>
      <i class="fa fa-times" aria-hidden="true"></i>
    </label>
  </li>
  <li>
    <label>
      <span>Book 3</span>
      <input type="checkbox" value="book3" name="books" />
      <i class="fa fa-check-square-o" aria-hidden="true"></i>
      <i class="fa fa-times" aria-hidden="true"></i>
    </label>
  </li>
  <li>
    <label>
      <span>Book 4</span>
      <input type="checkbox" value="book4" name="books" />
      <i class="fa fa-check-square-o" aria-hidden="true"></i>
      <i class="fa fa-times" aria-hidden="true"></i>
    </label>
  </li>
</ul>

<div id="output1"></div>

<ul id="booklist2" class="book-list" data-output="output2">
  <li>
    <label>
      <span>Book 5</span>
      <input type="checkbox" value="book5" name="books" />
      <i class="fa fa-check-square-o" aria-hidden="true"></i>
      <i class="fa fa-times" aria-hidden="true"></i>
    </label>
  </li>
  <li>
    <label>
      <span>Book 6</span>
      <input type="checkbox" value="book6" name="books"/>
      <i class="fa fa-check-square-o" aria-hidden="true"></i>
      <i class="fa fa-times" aria-hidden="true"></i>
    </label>
  </li>
  <li>
    <label>
      <span>Book 7</span>
      <input type="checkbox" value="book7" name="books" />
      <i class="fa fa-check-square-o" aria-hidden="true"></i>
      <i class="fa fa-times" aria-hidden="true"></i>
    </label>
  </li>
  <li>
    <label>
      <span>Book 8</span>
      <input type="checkbox" value="book8" name="books" />
      <i class="fa fa-check-square-o" aria-hidden="true"></i>
      <i class="fa fa-times" aria-hidden="true"></i>
    </label>
  </li>
</ul>

<div id="output2"></div>

Answer №2

To handle multiple boxes, the functions showremove and showadd need to be modified. Instead of targeting a single id, they should target a class by changing selectbook and removebook. This way, an index can be added to access each individual box.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

AngularJS: enhancing $http with custom functionality

I am facing an issue with my simple controller, which looks like this: function MyController($scope, $http) { ... $http.post(url).success(function(data) { console.log(data) }); } MyController.$inject = ['$scope', &ap ...

Should the element be scrolled beyond a fixed-positioned element

Is there a way to determine if an element is scrolled behind another element that is fixed at the top? I am looking to trigger some javascript when an element is positioned below a fixed element and every height or scrollTop thereafter. I am attempting t ...

When is it appropriate to utilize a view in EmberJS?

As a new user of EmberJS, I am navigating through the API and core components of the framework. One aspect that is challenging for me to fully comprehend is knowing when to utilize an Ember.View as opposed to an Ember.Component. My current understanding is ...

Expo background fetch initialized but not activated

During the development of my React Native app, I encountered the need to perform periodic background fetches from another server. To achieve this, I utilized two classes from Expo: import * as BackgroundFetch from 'expo-background-fetch'; import ...

Assigning a class to an li element once the page has finished loading

I am facing an issue with my navigation bar where the links are dynamically loaded from a database using a foreach loop. Although the nav bar is static, I want to apply an 'Active' class to the link when it is currently active. Despite trying to ...

Header stabilization on scroll

On my webpage, I have a table header positioned in the middle of the page. However, due to the length of the page, I am looking for a way to make the header stay fixed at the top of the browser as the user scrolls down. My query is: Is there a method to k ...

Evaluating the functionality of a React JS dropdown using Selenium automation and Java

Could you please advise me on how to select a value from a dynamically populated dropdown using React JS? An example would be greatly appreciated. Below is the HTML code snippet for the page... The division that contains the label "Year" functions as ...

Align the text on the same horizontal line

I have been struggling with this issue for hours. Here is my Header.js <div className="navbar-inner"> <h2>Text1</h2> <h3>Text2</h3> </div> This is the content of my Header.css: .navbar-inner { ...

The challenge of harmonizing variables in PHP and JavaScript

I have a PHP script that generates an HTML table displaying data from a MySQL database. <?php include 'connexion.php'; session_start(); $idfirm = $_REQUEST['idfirm']; $namefirm = $_REQUEST['namefirm']; The table rows are ...

Prevent scrolling on browser resize event

I am working on a basic script that adds a fixed class to a specific div (.filter-target) when the user scrolls beyond a certain point on the page. However, I am wondering how I can prevent the scroll event from triggering if the user resizes their brows ...

The content in tinymce cannot be edited or removed

Is there a method to prevent certain content within the tinyMCE Editor from being edited or removed? While I know that adding a class "mceNonEditable" can make a div non-editable, it can still be deleted. Is there a way to make it unremovable as well? ...

Using Node.js and Typescript to implement a chain of logical AND operations with an array of any length

Setting: I am developing a versatile function that determines a boolean outcome based on logical AND operations. However, the function is designed to handle various types of objects and arrays, each requiring different conditions. Currently, my code look ...

Obtain a transformed mesh that has been displaced using a displacementMap within three.js

Seeking to extract and export the mesh affected by a displacementMap. The displacement of vertexes is determined by this line in the shader (taken from three.js/src/renderers/shaders/ShaderChunk/displacementmap_vertex.glsl): transformed += normalize(obje ...

What is the best method for saving a chosen radio button into an array?

I am currently developing an online examination system where questions are retrieved from a database using PHP and displayed through AJAX. I am facing an issue where I am unable to capture the selected radio button value and store it in an array. Despite e ...

What makes using setInterval with a self-invoking function a smarter choice?

I recently came across an explanation on how to properly use the setInterval() function. Essentially, it was mentioned that (function(){ // perform some actions setTimeout(arguments.callee, 60000); })(); ensures that the subsequent call from setTim ...

What is the process for aligning rows with the selected option from the drop-down menu

Alright, so here's the scenario: I have created a table along with two drop-down filters. The first filter is for selecting the Year, and it offers options like "All", "2023", "2022", and "2021". When I pick a specific year, let's say "2022", onl ...

Is it possible for Vue Router to remember the scroll position on a route and return to the same position when navigating back?

My Vue Router is not saving the scroll position and always loads at the top of the page (0, 0). Any suggestions on what could be causing this issue? Here is my current router code setup: const scrollBehavior = (to, from, savedPosition) => { if (saved ...

Uncovering the Mystery Behind the Repetitive Execution of useEffect in Next.js

I am working on a Time Tracking feature for my Next.js application. In the ./app/components/TimeTracking.tsx file, I have implemented the following component: 'use client'; import React, { useEffect, useState } from 'react'; import { u ...

VueJs does not display the source code of components for users

I've recently delved into working with vueJS2 and am currently learning about components. I have a question for the experts in this field. As far as I understand, VueJS processes HTML using JavaScript, which is why the rest of the HTML code may not b ...

Exploring the benefits of utilizing useState and localStorage in Next.js with server-side

Encountering an error consistently in the code snippet below: "localstorage is not defined" It seems like this issue arises because next.js attempts to render the page on the server. I made an attempt to place the const [advancedMode, setAdvanced ...