Home > other >  How to set up a change event with a nested toggle event?
How to set up a change event with a nested toggle event?

Time:09-10

In the snippet below, I have a select menu. When 'Create Agency' is selected, then the red square should display.

Doing something like this in jQuery would be...

const agencyId = document.querySelector("#agencyId");
const addAgencyForm = document.querySelector("#addAgencyForm");

$('#agencyId').on('change', () => {
  $('#addAgencyForm').toggle(this);
});

...but I need to do this with Vanilla JavaScript.

Converting the .on() method with a nested toggle... this is as far as I can get:

const agencyId = document.querySelector("#agencyId");
const addAgencyForm = document.querySelector("#addAgencyForm");

agencyId.addEventListener("change", (event) => {
  if (event.target && event.target.id == "agencyId") {
    addAgencyForm.classList.toggle("d-block");
  }
});

How do I properly convert this .on() w/ nested .toggle() method to vanilla JS?

const agencyId = document.querySelector("#agencyId");
const addAgencyForm = document.querySelector("#addAgencyForm");

agencyId.addEventListener("change", (event) => {
  if (event.target && event.target.id == "agencyId") {
    addAgencyForm.classList.toggle("d-block");
  }
});
.box {
  height: 100px;
  width: 100px;
  background-color: red;
}

.d-none {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<div >
<form>
    <div >
    <div >
      <div >
        <label for="agencyId" >Agency</label>
        <select  id="agencyId" data-placeholder="Optionally, assign new contact to an agency..." name="agency.id">
          <option value="">Select</option>
          <option value="0">Create Agency</option>
          <option value="1">Department of Corrections</option>
          <option value="2">Defense Advocates Office</option>
        </select>
      </div>
    </div>
  </div>  
</form>
</div>
<hr>
<div  id="addAgencyForm"></div>

CodePudding user response:

If I understand correctly you have it nearly correct, but you have the wrong class passed as argument to the classlist.toggle() method.

const agencyId = document.querySelector("#agencyId");
const addAgencyForm = document.querySelector("#addAgencyForm");

agencyId.addEventListener("change", (event) => {
  if (event.target && event.target.id == "agencyId") {
    addAgencyForm.classList.toggle("d-none");
  }
});
.box {
  height: 100px;
  width: 100px;
  background-color: red;
}

.d-none {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<div >
<form>
    <div >
    <div >
      <div >
        <label for="agencyId" >Agency</label>
        <select  id="agencyId" data-placeholder="Optionally, assign new contact to an agency..." name="agency.id">
          <option value="">Select</option>
          <option value="0">Create Agency</option>
          <option value="1">Department of Corrections</option>
          <option value="2">Defense Advocates Office</option>
        </select>
      </div>
    </div>
  </div>  
</form>
</div>
<hr>
<div  id="addAgencyForm"></div>

CodePudding user response:

I guess you don't need extra styles to hide and show, because this is the purpose of toggle function, so I suggest you only keep the main style which is "box"

const agencyId = document.querySelector("#agencyId");
const addAgencyForm = document.querySelector("#addAgencyForm");

agencyId.addEventListener("change", (event) => {
  if (event.target && event.target.id == "agencyId") {
    addAgencyForm.classList.toggle("box");
  }
});
.box {
  height: 100px;
  width: 100px;
  background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<div >
<form>
    <div >
    <div >
      <div >
        <label for="agencyId" >Agency</label>
        <select  id="agencyId" data-placeholder="Optionally, assign new contact to an agency..." name="agency.id">
          <option value="">Select</option>
          <option value="0">Create Agency</option>
          <option value="1">Department of Corrections</option>
          <option value="2">Defense Advocates Office</option>
        </select>
      </div>
    </div>
  </div>  
</form>
</div>
<hr>
<div id="addAgencyForm"></div>

CodePudding user response:

A quick way to achieve your goal here is to base your test that toggles the red square on a new data-* that we add to the option with the Create Agency text.

Let's say we have added data-reveal-red-square="1" to the Create Agency option: <option value="0" data-reveal-red-square="1">Create Agency</option>.

Now when the select#agencyId dropdown changes we can base our test on the new data-reveal-red-square that we have added and if it exists on the currently selected option then we can reveal the red square or otherwise we hide it.

const agencyDropdown = document.getElementById('agencyId'),
  redSquare = document.getElementById('red-square');

/**
 * listen for changes on the dropdown. 
 * If a change happens and the selcted option becomes "Create Agency" which has "data-reveal-red-square" then we reveal the "red square"
 * Otherwise, we hide it once again.
 */
agencyDropdown.addEventListener('change', e => {
  const currentlySelectedOption = agencyDropdown.options[agencyDropdown.selectedIndex];
  redSquare.classList[currentlySelectedOption.dataset.revealRedSquare ? 'remove' : 'add']('hidden');
});
/** just for demo purpose */

#red-square {
  height: 150px;
  width: 150px;
  margin: auto;
  background-color: #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<div >
  <form>
    <div >
      <div >
        <div >
          <label for="agencyId" >Agency</label>
          <select  id="agencyId" data-placeholder="Optionally, assign new contact to an agency..." name="agency.id">
            <option value="">Select</option>
            <!-- notice the "data" attribute we added to that option -->
            <option value="0" data-reveal-red-square="1">Create Agency</option>
            <option value="1">Department of Corrections</option>
            <option value="2">Defense Advocates Office</option>
          </select>
        </div>
        <!-- the "red square, initially hidden using Boostsrap 3 "hidden" class" -->
        <div  id="red-square"></div>
      </div>
    </div>
  </form>
</div>

Note that the above example is one way to achieve your goal that only aims to get you started and definitely not the only way around. There must be other possible solutions that might be based on IDs, classes or other possibilities.

  • Related