I am trying to open and close an accordion through a link. I am using jQuery.
You can see the fiddle here – https://jsfiddle.net/squidraj/x1epjfv7/11/
The accordion works well if I just click the panel.
Steps to reproduce the issue –
1. Click the "Read more title 1" link - it will open the "Title 1" box
2. Click the "Title 1" box to close the panel - The toggle works well.
3. Now redo step 1 - Works fine
4. Redo step 2 - The panel doesn't close, which is the issue. It works when I click the panel second time.
$("a.button").on("click", function(e) {
e.preventDefault();
$(".accordion-wrapper div:nth-child(1) article").attr('style', 'max-height:inherit;');
$(".accordion-wrapper input[id=1]").attr('checked', true);
});
//Closing the accordion
$(".accordion-wrapper label").on("click", function(e){
const next = $(this).next()[0];
if (next.style.maxHeight) {
next.style.maxHeight = "";
}
});
div input {
display: none;
}
.accordion-wrapper{
margin: 2rem 0;
div{
margin: 1rem 0;
}
}
.accordion-wrapper article{
background: rgba(255, 255, 255, 0.25);
overflow: hidden;
max-height: 0px;
position: relative;
transition: max-height 0.3s ease-in-out;
border: 1px solid #eee;
padding: 0 15px;
}
.accordion-wrapper label {
position: relative;
display: block;
cursor: pointer;
color: #777;
font-size: 1.1em;
background: #eeeeee;
margin: 0;
padding: 10px 15px;
border: 1px solid #eee;
border-bottom: 1px solid transparent;
}
.accordion-wrapper input:checked ~ article{
max-height: inherit;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<a href="1" class="button">Read more title 1</a>
<div class="accordion-wrapper">
<div>
<input id="1" name="test" type="checkbox">
<label for="1">Title 1</label>
<article>
<p>Content 1</p>
</article>
</div>
<div>
<input id="2" name="test" type="checkbox">
<label for="2">Title 2</label>
<article>
<p>Content 2</p>
</article>
</div>
</div>
It seems the state of the hidden checkbox is still unchecked(false), and hence, the panel doesn’t close on step 4.
Any help is highly appreciated. Thanks in advance.
>Solution :
I have managed to fix the issue by using .prop()
instead of .attr()
.
Here is a detailed explanation why it didnt worked with .attr()
.attr()
-
.attr()
stands for attribute and it is used to get or set the value of an attribute of an HTML element. -
It operates on the attributes as they are defined in the HTML markup.
-
It works with attributes like src, href, title, alt, class, etc.
-
When used to set an attribute’s value, it modifies the HTML markup directly.
-
It works with both standard HTML attributes and custom attributes.
Example:$("img").attr("src", "newimage.jpg");
.prop():
.prop()
stands for property and it is used to get or set the value of properties of HTML elements.- It operates on the properties of the DOM element, not directly on the HTML markup.
- It works with properties like checked, disabled, selected, readOnly, etc.
- When used to set a property’s value, it manipulates the underlying DOM property, not the HTML markup.
- It typically works with boolean properties or properties that represent the state of an element.
- Example:
$("input[type='checkbox']").prop("checked", true);
$("a.button").on("click", function(e) {
e.preventDefault();
$(".accordion-wrapper div input[id=1]~article").attr('style', 'max-height:inherit;');
$(`.accordion-wrapper input[id=${$(this).data('id')}]`).prop('checked', true);
});
//Closing the accordion
$(".accordion-wrapper label").on("click", function(e){
const next = $(this).next()[0];
if (next.style.maxHeight) {
next.style.maxHeight = "";
}
});
div input {
display: none;
}
.accordion-wrapper{
margin: 2rem 0;
div{
margin: 1rem 0;
}
}
.accordion-wrapper article{
background: rgba(255, 255, 255, 0.25);
overflow: hidden;
max-height: 0px;
position: relative;
transition: max-height 0.3s ease-in-out;
border: 1px solid #eee;
padding: 0 15px;
}
.accordion-wrapper label {
position: relative;
display: block;
cursor: pointer;
color: #777;
font-size: 1.1em;
background: #eeeeee;
margin: 0;
padding: 10px 15px;
border: 1px solid #eee;
border-bottom: 1px solid transparent;
}
.accordion-wrapper input:checked ~ article{
max-height: inherit;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<a href="1" data-id="1" class="button">Read more title 1</a>
<div class="accordion-wrapper">
<div>
<input id="1" name="test" type="checkbox">
<label for="1">Title 1</label>
<article>
<p>Content 1</p>
</article>
</div>
<div>
<input id="2" name="test" type="checkbox">
<label for="2">Title 2</label>
<article>
<p>Content 2</p>
</article>
</div>
</div>