"Mastering the art of event delegation: A guide to effectively engaging with various

I have data that is generated dynamically, as shown in the snippet below:

const resultsDiv = document.getElementById("results");
const getList = document.getElementById("example");

document.querySelector(".container").addEventListener("click", function(e) {
  const tgt = e.target;
  if (tgt.type && tgt.type === "radio") {
    const hide = tgt.classList.contains("verify-no");
    [...tgt.closest(".card-body").querySelectorAll("p.card-text")].forEach(par => par.classList.toggle("d-none", hide))
  }
})

getList.addEventListener("click", e => {

  let results = ['a', 'b', 'c'];

  results.forEach((el, idx) => {
  
    // code for generating carousel items ... 
      
  });
})
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
  <link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/cropper/2.3.4/cropper.min.css'>
  <link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='css/advisory-new.css') }}" />
  <link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet'>
</head>

<body>

  <button id="example">Show results</button>

  <section class="pt-5 pb-5">
    <div class="container">
      <div class="row m-auto">
        <div class="col-6">
          <h3 class="mb-3">Some heading</h3>
        </div>
        <div class="col-6 text-right">
          <a class="btn btn-primary mb-3 mr-1" href="#carouselExampleIndicators2" role="button" data-slide="prev">
            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-right" viewBox="0 0 16 16">
              <path fill-rule="evenodd" d="M1 8a.5.5 0 0 1 .5-.5h11.793l-3.147-3.146a.5.5 0 0 1 .708-.708l4 4a.5.5 0 0 1 0 .708l-4 4a.5.5 0 0 1-.708-.708L13.293 8.5H1.5A.5.5 0 0 1 1 8z" />
            </svg>
          </a>
          <a class="btn btn-primary mb-3 " href="#carouselExampleIndicators2" role="button" data-slide="next">
            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-left" viewBox="0 0 16 16">
              <path fill-rule="evenodd" d="M15 8a.5.5 0 0 0-.5-.5H2.707l3.147-3.146a.5.5 0 1 0-.708-.708l-4 4a.5.5 0 0 0 0 .708l4 4a.5.5 0 0 0 .708-.708L2.707 8.5H14.5A.5.5 0 0 0 15 8z" />
            </svg>
          </a>
        </div>
        <div class="col-md-6 col-lg-4 col-xs-12 col-sm-12 m-auto shadow-lg p-3">
          <div id="carouselExampleIndicators2" class="carousel slide" data-interval="false" data-ride="carousel">
            <div class="carousel-inner" id="results"></div>
          </div>
        </div>
      </div>
    </div>
  </section>
  <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="93e3fce3e3f6e1bdf9e0d3a2bda2a5bda3">[email protected]</a>/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</body>

</html>

In my current setup, I have a click listener for dynamically created radio buttons. However, I am struggling with implementing a change listener for dynamically created Select elements.

  • Please click on the show results button to view the carousel items.

Any assistance on this matter would be highly appreciated...

Answer №1

Here is a simple vanilla JavaScript implementation:

const resultsDiv = document.getElementById("results");
const getList = document.getElementById("example");

document.querySelector(".container").addEventListener("click", function(e) {
  const tgt = e.target;
  if (tgt.type && tgt.type === "radio") {
    const hide = tgt.classList.contains("verify-no");
    [...tgt.closest(".card-body").querySelectorAll("p.card-text")].forEach(par => par.classList.toggle("d-none", hide))
  }
})

getList.addEventListener("click", e => {

  let results = ['a', 'b', 'c'];

  results.forEach((el, idx) => {
    //carousel
    const carouselItem = document.createElement("div");
    if (idx === 1) {
      carouselItem.classList.add("carousel-item", "active");
    }
    carouselItem.classList.add("carousel-item");

    //row below carousel
    const row = document.createElement("div");
    row.classList.add("row");

    //column for rows
    const column = document.createElement("div");
    column.classList.add("col-md-12", "mb-3");

    // card for each carousel inside column
    const card = document.createElement("div");
    card.classList.add("card");

    // card body for card
    const cardBody = document.createElement("div");
    cardBody.classList.add("card-body", "text-center");

    // card text (upload info)
    const cardTextUploadedOn = document.createElement("p");
    cardTextUploadedOn.classList.add("card-text");
    cardTextUploadedOn.innerText = "adsadad";

    const cardTextUploadedBy = document.createElement("p");
    cardTextUploadedBy.classList.add("card-text");
    cardTextUploadedBy.innerText = "adsadad";

    // show predictions
    const formGroup = document.createElement("div");
    formGroup.classList.add("form-group", "row");

    const predLabel = document.createElement("div");
    predLabel.classList.add("col-lg-12");
    predLabel.innerText = "Select";

    const dummy = document.createElement("div");
    dummy.classList.add("col-sm-10");

    formGroup.appendChild(predLabel);
    formGroup.appendChild(dummy);

    // yes / no options
    const verifyRow = document.createElement("div");
    verifyRow.classList.add("row");

    const verifyLegend = document.createElement("legend");
    verifyLegend.classList.add("col-form-label", "col-lg-12", "pt-0");
    verifyLegend.innerText = "Is this correct ?";

    const verifyDummy = document.createElement("div");
    verifyDummy.classList.add("col-sm-10");

    const verifyYesFormCheck = document.createElement("div");
    verifyYesFormCheck.classList.add("form-check");

    const verifyNoFormCheck = document.createElement("div");
    verifyNoFormCheck.classList.add("form-check");

    const yesInput = document.createElement("input");
    yesInput.classList.add("form-check-input", "verify-yes");
    yesInput.type = "radio";
    yesInput.checked = true;
    yesInput.name = "choosePred" + idx;
    yesInput.value = "Yes";

    const verifyYesLabel = document.createElement("label");
    verifyYesLabel.classList.add("form-check-label", "verify-yes");
    verifyYesLabel.innerText = "Yes";

    const verifyNoLabel = document.createElement("label");
    verifyNoLabel.classList.add("form-check-label", "verify-no");
    verifyNoLabel.innerText = "No";

    const noInput = document.createElement("input");
    noInput.classList.add("form-check-input", "verify-no");
    noInput.type = "radio";
    noInput.name = "choosePred" + idx;
    noInput.value = "No";

    // select //
    const selectForm = document.createElement("div");
    selectForm.classList.add("form-group", "selectGroup");

    const selectCLabel = document.createElement("label");
    selectCLabel.innerText = "Select C";

    const selectPLabel = document.createElement("label");
    selectPLabel.innerText = "Select P";

    //select for crop options
    const selectC = document.createElement("select");
    selectC.classList.add("form-control", "c-select");
    selectC.addEventListener("change", e => {
      alert('changedC');
    });

    //select for pest options
    const selectP = document.createElement("select");
    selectP.classList.add("form-control", "p-select");
    selectP.addEventListener("change", e => {
      alert('changedP');
    });

    const c_names = ['abc', 'abcd', 'gef']

    for (const c of c_names) {
      const option = document.createElement("option");
      option.innerText = c;
      if (c === "Select") {
        option.selected = true;
      }
      selectC.appendChild(option);
    }

    // append elements to create the structure dynamically
    resultsDiv.appendChild(carouselItem);
    carouselItem.appendChild(row);
    row.appendChild(column);
    column.appendChild(card);
    card.appendChild(cardBody);
    cardBody.appendChild(cardTextUploadedBy);
    cardBody.appendChild(cardTextUploadedOn);
    cardBody.appendChild(formGroup);
    cardBody.appendChild(verifyRow);
    verifyRow.appendChild(verifyLegend);
    verifyRow.appendChild(verifyDummy);
    verifyDummy.appendChild(verifyYesFormCheck);
    verifyDummy.appendChild(verifyNoFormCheck);
    verifyYesFormCheck.appendChild(yesInput);
    verifyYesFormCheck.appendChild(verifyYesLabel);
    verifyNoFormCheck.appendChild(noInput);
    verifyNoFormCheck.appendChild(verifyNoLabel);
    cardBody.appendChild(selectForm);
    selectForm.appendChild(selectCLabel);
    selectForm.appendChild(selectC);
    selectForm.appendChild(selectPLabel);
    selectForm.appendChild(selectP);

  });
})
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
  <link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/cropper/2.3.4/cropper.min.css'>
  <link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='css/advisory-new.css') }}" />
  <link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet'>
</head>

<body>

  <button id="example">Show results</button>

  <section class="pt-5 pb-5">
    <div class="container">
      <div class="row m-auto">
        <div class="col-6">
          <h3 class="mb-3">Some heading</h3>
        </div>
        <div class="col-6 text-right">
          <a class="btn btn-primary mb-3 mr-1" href="#carouselExampleIndicators2" role="button" data-slide="prev">
            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-right" viewBox="0 0 16 16">
              <path fill-rule="evenodd" d="M1 8a.5.5 0 0 1 .5-.5h11.793l-3.147-3.146a.5.5 0 0 1 .708-.708l4 4a.5.5 0 0 1 0 .708l-4 4a.5.5 0 0 1-.708-.708L13.293 8.5H1.5A.5.5 0 0 1 1 8z" />
            </svg>
          </a>
          <a class="btn btn-primary mb-3 " href="#carouselExampleIndicators2" role="button" data-slide="next">
            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-left" viewBox="0 0 16 16">
              <path fill-rule="evenodd" d="M15 8a.5.5 0 0 0-.5-.5H2.707l3.147-3.146a.5.5 0 1 0-.708-.708l-4 4a.5.5 0 0 0 0 .708l4 4a.5.5 0 0 0 .708-.708L2.707 8.5H14.5A.5.5 0 0 0 15 8z" />
            </svg>
          </a>
        </div>
        <div class="col-md-6 col-lg-4 col-xs-12 col-sm-12 m-auto shadow-lg p-3">
          <div id="carouselExampleIndicators2" class="carousel slide" data-interval="false" data-ride="carousel">
            <div class="carousel-inner" id="results"></div>
          </div>
        </div>
      </div>
    </div>
  </section>
  <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</body>

</html>

Answer №2

You're able to attach numerous listeners to a single element without removing any previously added ones

Just like you would for a click event:


document.querySelector(".container").addEventListener("change", function(e) {
  const tgt = e.target;
  if (tgt.type && tgt.type === "select-one" /* && additional checks to correctly identify the element, such as class, name, … */) {
     // perform an action
  }
})

The type of a select is:

select-multiple if multiple values can be selected.
select-one if only one value can be selected.

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

Apply a CSS class when the tab key is pressed by the user

Currently in my Angular 14 project, I am working on a feature where I need to apply "display: block" to an element once the user reaches it using the tab key. However, I am struggling with removing the "display: block" when the user tabs out of the element ...

Utilizing JSON data as a variable for handling in a Handlebars view within a Node.js/Express application

I am currently seeking a solution to display a view that includes a variable with data fetched from an API. My technology stack involves express, handlebars, and request. Here is the code for the web server's router: const express = require('ex ...

Storing Radio Buttons and Checkboxes Using LocalStorage: A Simple Guide

Is there a way to save and retrieve values from localStorage for input types "radio" and "checkbox"? I've tried using the same code that works for text and select elements, but it doesn't seem to be saving the values for radio and checkbox. Can s ...

Using TypeScript with Watermelondb

I'm currently developing a React App and I want to implement Watermelondb for Offline Storage, but I'm unsure about using it with TypeScript. I have already set up the database and created Course and Lesson model files from the Watermelondb libra ...

Counting Clicks with the Button Counter

I'm having an issue with my jQuery code that is supposed to count button clicks - it stops after just one click. I need help fixing this problem. $(function() { $('.btn').click(function() { $(this).val(this.textContent + 1); }); } ...

What are the ideal scenarios for implementing React.Fragments?

Today I discovered React Fragments and their benefits. I learned that fragments are more efficient by reducing the number of tree nodes and improving cleanliness in the inspector. However, is there still a need to use div tags as containers in React compo ...

Skip a single test from a suite in Firefox using Protractor automation framework

I have a collection of tests in my tests folder, all named with the convention ending in spec.js. By using the */spec.js option in the Config file, I am able to run all tests seamlessly. However, I encountered an issue where I needed to skip running a spe ...

Trigger is not activated by dynamically created element

I am dealing with a block of code that is dynamic and looks like this. var li3 = document.createElement('li'); li3.classList.add("col-sm-3"); li3.classList.add("no_padding"); var inner = ""; inner = inner ...

Issues with reactivity are present in certain items within Vue.js cards

Can someone please assist me with this issue that has been causing me trouble for days? I am working on updating the quantity and total price in a checkout card: The parent component: <template> <div> <upsell-checkout-product ...

connect the validation of forms to different components

I am currently working on components to facilitate the user addition process. Below is an example of my form component: createForm(): void { this.courseAddForm = this.formBuilder.group({ name: ['', [ Validators.required, ...

Create an Array with a dynamic name derived from the values of other variables

In my JavaScript project, I am facing a challenge in naming arrays based on dynamic data such as room numbers and user IDs. As the rooms and users are constantly changing, I need to create multiple arrays accordingly. Although this code is incorrect, it s ...

How to Pause or Temporarily Halt in Jquery?

Looking to lift the object up, wait 1000ms, and then hide it. I found this snippet of code: $("#test").animate({"top":"-=80px"},1500) .animate({"top":"-=0px"},1000) .animate({"opacity":"0"},500); However, using ".animate({"to ...

Information is not appearing in the dropdown menu

As a beginner in JavaScript, this is my first program. I have written HTML and JavaScript code to display data in a dropdown menu from a Python Django database. However, when I run it, the data is not showing up. Here is my code: <!DOCTYPE html> < ...

What steps can be taken to stop 'type-hacking'?

Imagine owning a popular social media platform and wanting to integrate an iframe for user signups through third-party sites, similar to Facebook's 'like this' iframes. However, you are concerned about the security risks associated with ifra ...

JavaScript code that triggers a function when the mouse is moved over a description box on a

As a beginner in the field of Computer Science, I recently embarked on a project to create a website for sharing science articles with students. The goal is to spark curiosity and interest in science through this platform. One key feature I wanted to inclu ...

Utilize the power of Request.JSON to send an HTML array as a post

I have a piece of HTML code that includes form elements: First name: <input type='text' name='first_name' value='' /><br/> Last name: <input type='text' name='last_name' value='' / ...

Having trouble reaching the elements stored in an array?

As a beginner in Angular and JavaScript, I may be making some obvious mistakes so please bear with me. I have written this code that allows the selection of 2 text files and then combines them into a single array. $scope.textArray = []; $scope.textUpload ...

Having trouble navigating through multiple layers of nested array data in react js

I need help understanding how to efficiently map multiple nested arrays of data in a React component and then display them in a table. The table should present the following details from each collection: title, location, description, and keywords. Below ...

Ensuring the presence of a bootstrap angular alert with protractor and cucumberJS

I am currently utilizing protractor, cucumberJS, and chai-as-promised for testing. There is a message (bootstrap alert of angularJS) that displays in the DOM when a specific button is clicked. This message disappears from the DOM after 6000 milliseconds. ...

Tips for real-time editing a class or functional component in Storybook

Hey there, I am currently utilizing the storybook/react library to generate stories of my components. Everything has been going smoothly so far. I have followed the guide on https://www.learnstorybook.com/react/en/get-started and added stories on the left ...