"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

Switching Out Bootstrap Dropdown with Dropup (Varying functionality on two almost identical implementations)

In the midst of my project on Github Pages, I encountered an interesting issue involving replacing a bootstrap .dropdown with .dropup when the div's overflow-y: scroll causes the dropdown menu to be cut off or overflow. The functionality can be viewed ...

Progress of file uploads on the client side using Vue JS

I'm facing a challenge in creating a loading bar that shows the progress when a file is selected for upload in a form. Most of the examples I come across online demonstrate the loading bar after hitting an 'upload' button, but in my case, I ...

The POST request encountered an error with status code 500 while being processed by the Express.js framework in the IncomingMessage

My current challenge involves creating a HTTP request for a CRUD application using JS. The aim is to add a new user account record to the Logins database. However, every time I attempt this request, it results in a 500 error: To test this, I have written ...

What does the JS Array Filter function return?

Is it necessary to include a return statement in the filter function when NOT using ES6 arrow syntax? Could the two separate filter functions be combined into one for efficiency? cars.filter(function(car, index) { return car[0].setAttribute("data-ori ...

Struggling to determine whether an array contains data or is void in ReactJS?

In the state, I have an array and I set the default value of my state to an empty array []. After loading an API request, I need to display a loader until the data is ready. So, I am using a condition like this: (if the array length === 0, the loader wil ...

Using the SmartSheets API to Iterate Over a List to Determine the Variable of a Function

I have a group of numerical values listed below that are stored in a variable. [700000000084, 100000000051652, 8800000000000072, 280000000000004, 680000000000008, 880000000000006] My goal is to iterate through this list using the SmartSheets API to gathe ...

Determine the number of stored values in a specific key by utilizing stringify within localstorage

Is there a way to determine the number of unique values stored under one key in local storage? For instance: Here is the content of my local storage: [{"id":"item-1","icon":"google.com"},{"id":"item-2","icon":"youtube.com"}] In this case, I would like ...

Creating a dynamic select functionality in Drupal forms

Being more focused on backend development, I am facing a challenge that may be simple for jQuery experts. In Drupal, I have two arrays - one containing names of views and the other having displays for each view. To populate these arrays, here is the code s ...

Struggling to understand why my React Component is failing to render properly

Could there be an issue with how I imported react or am I simply overlooking something small? Any feedback would be greatly appreciated. As a beginner in programming, I may be missing a simple solution that I'm not experienced enough to identify. Than ...

Is it possible to load the response from the $.post function, which contains GIF content, into a JavaScript Image object

How can I preload an image that the server only returns on a POST request? I want to load the image before displaying it. How can I store the result in a JavaScript object? $.post('image.php', {params: complexParamsObject}, function(result) { ...

Identify changes in attributes on elements that are updated automatically

On my webpage, I want to have two select boxes that are connected so their values always match. Here's an example: Imagine a page with two selects: <select class="myselector"> <option value='1'>1 <br> < ...

What is the best way to hide the menu bar on a particular window using electron?

In my application, there is a menu that opens the document properties window when clicked. However, I am facing an issue where the application menu gets inherited by the document properties window itself, allowing you to open another document properties wi ...

Attempting to develop a worldwide npm package. Upon running my script, I encounter the message "The designated path cannot be found."

I have been working on converting my npm module into a global command. You can find the code at this link. However, when I try to run $ seed, an error stating "The system cannot find the path specified" is displayed, indicating that it recognizes it as a ...

techniques for utilizing dynamic variables with the limitTo filter in AngularJS

<div class="container"> <div class="row" ng-repeat="cmts in courCmt.argument" ng-init="getUserInfo(cmts)"> <div class="col-sm-1 col-xs-2"> <div class="thumbnail"> &l ...

Invoke a functional component when a button is clicked in a React application

I have a functional component that includes a button. My goal is to trigger another functional component when this button is clicked. Upon clicking the Submit button, the Preview button appears. When the user clicks on the preview button, it should call t ...

What is the process for activating namespacing on a VueX module that has been imported?

I am currently utilizing a helper file to import VueX modules: const requireModule = require.context('.', false, /\.store\.js$/) const modules = {} requireModule.keys().forEach(filename => { const moduleName = filename ...

Struggling to convert a JSON file into a TableView within a JavaScript application developed with Appcelerator

Trying to display a JSON file in a table using JavaScript and Appcelerator is proving to be quite a challenge. The output appears as an empty table when compiled to an example page. As someone relatively new to JavaScript and JSON, I'm seeking guidanc ...

How can I make an HTML button the default option within a form?

Currently, I am working on an asp.net page which contains a mix of asp.net buttons and HTML input[type=button] elements. These HTML buttons are specifically used to initiate AJAX calls. My dilemma arises when the user hits ENTER - instead of defaulting to ...

The Facebook Like Button appears on Firefox but not on Internet Explorer due to Javascript errors

Hello everyone, I could really use some help with an issue I am facing. My Facebook like button works perfectly fine in Firefox, but when it comes to Internet Explorer, I keep encountering Javascript errors and the button doesn't show up at all: If y ...

I encountered a frustrating issue with saving user input data using localStorage

One of my goals is to store the current inputs even if the user refreshes or closes the browser. The issue I'm facing is that when I select Yes in the radio button, then refresh the page or close the browser and reopen it, the No button is checked wh ...