JQuery - get array of divs by data attribute and iterate over them

Viewed 55

I have 4 divs, and am building a navbar that determines which one is displayed while hiding the others. The nav buttons are as follows:

<button data-button="personalInfo">Personal Info</button>
<button data-button="vehicleInfo">Vehicle Info</button>
<button data-button="vehicleCondition">Vehicle Condition</button>
<button data-button="ownershipInfo">Ownership Info</button>

The divs are as follows:

<div data-section="personalInfo">Personal Info</div>
<div data-section="vehicleInfo">Vehicle Info</div>
<div data-section="vehicleCondition">Vehicle Condition</div>
<div data-section="ownershipInfo">Ownership Info</div>

When a button is clicked, I want to display the div with the data-section attribute that corresponds to the button's data-button attribute. I have written a function that takes a particular data-section as an argument, with the intention of looping through each div and applying the bootstrap class of d-none to every one except the one whose data-section matches the argument. However, I can't seem to get all the divs by the data-section in a way that allows me to iterate over them. Here is the JQuery:

const personalInfoBtn = $(this).find('[data-button="personalInfo"]')
const vehicleInfoBtn = $(this).find('[data-button="vehicleInfo"]')
const vehicleConditionBtn = $(this).find('[data-button="vehicleCondition"]')
const ownershipInfoBtn = $(this).find('[data-button="ownershipInfo"]')

const switchFormSection = (dataSection) => {
    // All 3 of these methods do not get hold of the divs in a manner that allows me to loop over them and add/remove classes
    // const sections = $widget.attr("data-section");
    // const sections = $("div[data-section]");
    // const sections = $widget.data("section");

    sections.each(function(section){
        if(section === dataSection) {
            section.removeClass('d-none');
        } else {
            section.addClass('d-none');
        }
    })
}

personalInfoBtn.on("click", function(e) {
    switchFormSection("personalInfo");
})

vehicleInfoBtn.on("click", function(e) {
    switchFormSection("vehicleInfo");
})

vehicleConditionBtn.on("click", function(e) {
    switchFormSection("vehicleCondition");
})

ownershipInfoBtn.on("click", function(e) {
    switchFormSection("ownershipInfo");
})

Any help on how to achieve this, or indeed if there is a smarter way of executing this functionality, is appreciated.

1 Answers

Since the data attributes for the buttons and divs exactly match, there's no need to specify each different possibility individually. With a click listener on the buttons, identify the data-button attribute of the clicked element, then you can iterate over all <div>s and hide them, then show the one that matches the data-button:

const divs = $('[data-section]');
$('[data-button]').on('click', (e) => {
  divs.addClass('d-none');
  const name = e.target.dataset.button;
  divs
    .filter(`[data-section=${name}]`)
    .removeClass('d-none');
});
.d-none {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button data-button="personalInfo">Personal Info</button>
<button data-button="vehicleInfo">Vehicle Info</button>
<button data-button="vehicleCondition">Vehicle Condition</button>
<button data-button="ownershipInfo">Ownership Info</button>


<div data-section="personalInfo">Personal Info</div>
<div data-section="vehicleInfo" class="d-none">Vehicle Info</div>
<div data-section="vehicleCondition" class="d-none">Vehicle Condition</div>
<div data-section="ownershipInfo" class="d-none">Ownership Info</div>

Related