Reputation: 41
I have 4 "More Info" dropdown buttons that show more information when clicking on them. I want each one to open/close on it's own without the others opening/closing.
I have created some jquery code that works but the only way I can see to make it work for each button is to repeat it for each ID. I'm sure there is a much dryer way to complete it.
$(document).ready(function() {
var moreBtnWrapperEl = $('.more-benefits-btn-wrapper');
$(moreBtnWrapperEl).click(function() {
var extraInfoText = $('#extra1-text').text();
var i = $("i", this);
$('.showFurther').slideToggle();
if (extraInfoText === "More info" ? $(this).find('#extra1-text').text('Show less') : $(this).find('#extra1-text').text('More info'));
i.toggleClass('fa-chevron-up');
$(this).append(i);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="showFurther" style="display: none;">
<p class="extra-text">Lorem ipsum dolor, sit amet consectetur adipisicing elit. Repellendus, officia fugit sapiente omnis aperiam eius rerum veniam, voluptas veritatis delectus, voluptatum dolore molestias aliquid optio ipsam modi debitis corporis. Molestiae!</p>
</div>
<div class="more-benefits-btn-wrapper">
<span id="extra1-text">More info</span>
<span class="btn-icon">
<i class="fal fa-chevron-down"> </i>
</span>
</div>
Upvotes: 1
Views: 41
Reputation: 111
If you wrap the show button and the benefits btn with an element, it would be aa matter of navigating to the parent and then finding the only show further element available.
<div>
<div class="showFurther" style="display: none;">
<p class="extra-text">Lorem ipsum dolor, sit amet consectetur adipisicing elit. Repellendus, officia fugit sapiente omnis aperiam eius rerum veniam, voluptas veritatis delectus, voluptatum dolore molestias aliquid optio ipsam modi debitis corporis. Molestiae!</p>
</div>
<div class="more-benefits-btn-wrapper">
<span id="extra1-text">More info</span>
<span class="btn-icon">
<i class="fal fa-chevron-down"> </i>
</span>
</div>
</div>
var moreBtnWrapperEl = $('.more-benefits-btn-wrapper');
$(moreBtnWrapperEl).click(function() {
var extraInfoText = $('#extra1-text').text();
var i = $("i", this);
$(this).parent().find('.showFurther').slideToggle();
if (extraInfoText === "More info" ? $(this).find('#extra1-text').text('Show less') : $(this).find('#extra1-text').text('More info'));
i.toggleClass('fa-chevron-up');
$(this).append(i);
});
Upvotes: 0
Reputation: 967
You can use a toggleClass to show or hide the extra content in your container. You can even change the text for the More info
or Show less
span by using the content
CSS property. Like so:
$(document).ready(function(){
$('.more-benefits-btn-wrapper').click(function(){
$(this).toggleClass('more');
})
});
.more-benefits-btn-wrapper {
display: block;
width: 200px;
padding-bottom: 10px;
}
.more-info-span::after {
content: 'More info...';
display: inline-block;
color: #00f;
padding-left: 5px;
}
.more-benefits-btn-wrapper.more .more-info-span::after {
content: 'Show less';
}
.content-span {
display: none;
}
.more-benefits-btn-wrapper.more .content-span {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="more-benefits-btn-wrapper">
<span class="more-info-span">Content title 1</span>
<span class="btn-icon">
<i class="fal fa-chevron-down"> </i>
</span>
<span class="content-span">Lorem ipsum dolor sit amet</span>
</div>
<div class="more-benefits-btn-wrapper">
<span class="more-info-span">Content title 2</span>
<span class="btn-icon">
<i class="fal fa-chevron-down"> </i>
</span>
<span class="content-span">Lorem ipsum dolor sit amet</span>
</div>
<div class="more-benefits-btn-wrapper">
<span class="more-info-span">Content title 3</span>
<span class="btn-icon">
<i class="fal fa-chevron-down"> </i>
</span>
<span class="content-span">Lorem ipsum dolor sit amet</span>
</div>
Upvotes: 1
Reputation: 337560
To solve this problem, and keep your code 'DRY' (which stands for Don't Repeat Yourself), you can use DOM traversal.
jQuery offers lots of methods to find related elements. In your case you can get the reference to the clicked .more-benefits-btn-wrapper
element using the this
keyword in the click event handler, then use find()
and prev()
to get the related elements. Try this:
$(document).ready(function() {
$('.more-benefits-btn-wrapper').click(function() {
var $wrapper = $(this);
$wrapper.prev('.showFurther').slideToggle();
$wrapper.find('.extra-text').text(function(i, t) {
return t == 'More info' ? 'Show less' : 'More info';
});
$wrapper.find('i').toggleClass('fa-chevron-up');
});
});
.showFurther {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="showFurther">
<p class="extra-text">Lorem ipsum dolor, sit amet consectetur adipisicing elit. Repellendus, officia fugit sapiente omnis aperiam eius rerum veniam, voluptas veritatis delectus, voluptatum dolore molestias aliquid optio ipsam modi debitis corporis. Molestiae!</p>
</div>
<div class="more-benefits-btn-wrapper">
<span class="extra-text">More info</span>
<span class="btn-icon">
<i class="fal fa-chevron-down"> </i>
</span>
</div>
<div class="showFurther">
<p class="extra-text">Lorem ipsum dolor, sit amet consectetur adipisicing elit. Repellendus, officia fugit sapiente omnis aperiam eius rerum veniam, voluptas veritatis delectus, voluptatum dolore molestias aliquid optio ipsam modi debitis corporis. Molestiae!</p>
</div>
<div class="more-benefits-btn-wrapper">
<span class="extra-text">More info</span>
<span class="btn-icon">
<i class="fal fa-chevron-down"> </i>
</span>
</div>
<div class="showFurther">
<p class="extra-text">Lorem ipsum dolor, sit amet consectetur adipisicing elit. Repellendus, officia fugit sapiente omnis aperiam eius rerum veniam, voluptas veritatis delectus, voluptatum dolore molestias aliquid optio ipsam modi debitis corporis. Molestiae!</p>
</div>
<div class="more-benefits-btn-wrapper">
<span class="extra-text">More info</span>
<span class="btn-icon">
<i class="fal fa-chevron-down"> </i>
</span>
</div>
Upvotes: 1