Open and close accordion on click a link using jQuery

Advertisements

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>

Leave a ReplyCancel reply