Best way to reuse JavaScript for common html elements

JacksWastedLife

I have an HTML form that takes in values from a dropdown list. When an option is selected the HTML badge is updated to display the status of Good or Bad.

Each badge element span class is the same, but the ID is different as I need to capture the result.

Is there a way that I can use a single JavaScript function against all span classes but only update the span class for where the dropdown box is?

Or do I need to define every element ID within the JavaScript function.

The <span class="badge badge-soft-success" is on every badge.

const changeBadgeColour = document.getElementById('project-tier-entry-level');

changeBadgeColour.addEventListener('change', function() {
  var p_status = document.getElementById("project-tier-entry-level");
  p_status_value = p_status.options[p_status.selectedIndex].value;


  const statusBadge = document.getElementById('project-tier-entry-level-status');
  if (p_status_value === "Yes") {

    document.getElementById('project-tier-entry-level-status').className = 'badge badge-soft-success'
    document.getElementById('project-tier-entry-level-status').textContent = 'Good!'

  } else {
    document.getElementById('project-tier-entry-level-status').className = 'badge badge-soft-danger'
    document.getElementById('project-tier-entry-level-status').textContent = 'Bad!'
  }

  console.log()

});
<div class="col-sm-6">
  <label class="form-label" for="project-tier-entry-level-label">Does the project land in our Tiered entry levels?</label>
  <span class="badge badge-soft-success" id="project-tier-entry-level-status"></span>
  <select class="form-control" name="choices-single-no-sorting" id="project-tier-entry-level">
    <option value="" disabled selected hidden>Please Choose...</option>
    <option>Yes</option>
    <option>No</option>
  </select>
</div>

mplungjan

You can delegate

document.getElementById('container').addEventListener('change', function(e) {
  const tgt = e.target;
  if (tgt.tagName === "SELECT" && tgt.id.startsWith("project-tier")) { // in case there are other things that can change in that container
    const yes = tgt.value === "Yes"
    const statusBadge = tgt.previousElementSibling; // or tgt.closest('div').querySelector('span.badge');
    statusBadge.classList.toggle("badge-soft-success", yes)
    statusBadge.classList.toggle("badge-soft-danger", !yes)
    statusBadge.textContent = yes ? 'Good!' : 'Bad!';
  }
});
<div id="container">
  <div class="col-sm-6">
    <label class="form-label" for="project-tier-entry-level-label">Does the project land in our Tiered entry levels?</label>
    <span class="badge badge-soft-success" id="project-tier-entry-level-status"></span>
    <select class="form-control" name="choices-single-no-sorting" id="project-tier-entry-level">
      <option value="" disabled selected hidden>Please Choose...</option>
      <option>Yes</option>
      <option>No</option>
    </select>
  </div>

  <div class="col-sm-6">
    <label class="form-label" for="project-tier-entry-level-label">Does the project land in our Tiered normal levels?</label>
    <span class="badge badge-soft-success" id="project-tier-normal-level-status"></span>
    <select class="form-control" name="choices-single-no-sorting" id="project-tier-normal-level">
      <option value="" disabled selected hidden>Please Choose...</option>
      <option>Yes</option>
      <option>No</option>
    </select>
  </div>
</div>

Three options with a result of the selections:

document.getElementById('container').addEventListener('change', function(e) {
  const tgt = e.target;
  if (tgt.tagName === "SELECT" && tgt.id.startsWith("project-tier")) { // in case there are other things that can change in that container
    const badge = tgt.value
    const statusBadge = tgt.previousElementSibling; // or tgt.closest('div').querySelector('span.badge');
    statusBadge.classList.toggle("badge-soft-success", badge==="Yes")
    statusBadge.classList.toggle("badge-soft-danger",  badge==="No")
    statusBadge.classList.toggle("badge-soft-unknown",  badge==="Unknown")
    const text = {"Yes":"Good!","No":"Bad!","Unknown":"Unknown!"}[badge] || "What?"
    statusBadge.textContent = text;
    
    const res =  [...document.querySelectorAll("#container select[id^=project-tier]")]
      .reduce((acc, sel) => {
        if (acc[sel.value] != undefined) acc[sel.value]++;
        else acc["Not set"]++;
        return acc
      },{"Yes":0,"No":0,"Unknown":0,"Not set":0})
    document.getElementById("result").value = Object.entries(res).map(([key,val]) => `${key}: ${val}`).join('\n')
  }
});
<form id="tierForm">
<div id="container">
  <div class="col-sm-6">
    <label class="form-label" for="project-tier-entry-level-label">Does the project land in our Tiered entry levels?</label>
    <span class="badge badge-soft-success" id="project-tier-entry-level-status"></span>
    <select class="form-control" name="choices-single-no-sorting" id="project-tier-entry-level">
      <option value="" disabled selected hidden>Please Choose...</option>
      <option>Yes</option>
      <option>No</option>
      <option>Unknown</option>
    </select>
  </div>

  <div class="col-sm-6">
    <label class="form-label" for="project-tier-entry-level-label">Does the project land in our Tiered normal levels?</label>
    <span class="badge badge-soft-success" id="project-tier-normal-level-status"></span>
    <select class="form-control" name="choices-single-no-sorting" id="project-tier-normal-level">
      <option value="" disabled selected hidden>Please Choose...</option>
      <option>Yes</option>
      <option>No</option>
      <option>Unknown</option>
      <option></option>
    </select>
  </div>
</div>
<div>
<textarea readonly id="result"></textarea>
</div>
</form>

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Best way to reuse a Runnable

Best way to create nested HTML elements with jQuery

What is the best way to find common elements from 2 sets?

Vue - best way to reuse methods

Java: Best way to remove Javascript from HTML

Best way to assign a javascript object to html element

Best way in JavaScript to "intersect" two arrays of JSON objects by common property?

What is the best way to retrieve specific elements from an HTML page in VBA?

Best way to render a web of interconnecting elements in HTML5?

Best way for maping html elements from material ui and rendering by map

What is the best way to reuse a for-loop?

Apache POI - is caching workbook best way to reuse?

What is the best way to reuse styles in ionic?

best way to iterate over elements of web page in JavaScript/jQuery

what is the best way to delete elements at execution time of a foreach in javascript?

Best way to check if an existing array is having all distinct elements or not in JavaScript?

Best way to search list of elements from javascript array

Best way to put array elements in custom order in Javascript

What is the best way to categorize/group and sort a list of elements using javascript?

Javascript - Best way to create array with unique elements from another array

Is there a good way to attach JavaScript objects to HTML elements?

Is there a better way of attaching javascript to multiple HTML elements?

Is there an alternative way to retrieve html elements in javascript

Different Directives with Common HTML / JavaScript Parts - Best Practices

Best way to refactor common code

Best way to create readable Javascript in Java for adding to html page

Best way to change several HTML-table cells via javascript

Best way to change background color with JavaScript HTML DOM

Best way to hide duplicate elements