Search code examples
javascriptjquerybootstrap-4

innerhtml only changes on second click


I have a group of panels that I would like to expand individually when clicked upon, but also if the user clicks on Expand + the text should change to Collapse and all panels should expand. Currently, this only works on the second click. I have also tried using "toggle". Expected functionality: Click on Expand + the the text changes to Collapse - and all panels regardless if they are currently being shown should collapse Click on Collapse - and all panels regardless if they are currently being shown should display.

function travelAccordion() {

  var x = document.getElementById("travelClick");
  if (x.innerHTML === "Expand All +") {
    x.innerHTML = "Collapse All -";
    $('#travel-accordion .collapse').collapse('show');
  } else {
    x.innerHTML = "Expand All +";
    $('#travel-accordion .collapse').collapse('hide');
  }
}
.panel-title:hover,
#travelClick {
  cursor: pointer;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<p class="text-right" id="travelClick" onclick="travelAccordion()"> Expand All +</p>
<div class="panel-group" id="travel-accordion">
  <div class="panel panel-default">
    <div class="panel-heading">
      <a aria-expanded="false" class="collapsed" data-parent="#travel-accordion" data-toggle="collapse" href="#collapse1">
        <h4 class="panel-title">Group 1</h4>
      </a>
    </div>
    <div class="panel-collapse collapse" id="collapse1" style="">
      <div class="panel-body">
        Group 1 Text
      </div>
    </div>
    <div class="panel-heading">
      <a aria-expanded="false" class="collapsed" data-parent="#travel-accordion" data-toggle="collapse" href="#collapse2">
        <h4 class="panel-title">Group 2</h4>
      </a>
    </div>
    <div class="panel-collapse collapse" id="collapse2" style="">
      <div class="panel-body">
        Group 2 Text
      </div>
    </div>
  </div>
</div>


Solution

  • I am going to post a formal answer, building off DBS's comment. A whitespace in the html content of your "#travelClick" element is causing the issue. Using an HTML content selector can be unreliable, and instead you should use either a class or data attribute to keep track of the state of the accordion.

    Here is an example:

    function travelAccordion() {
      var x = $("#travelClick");
      var isExpanded = x.data("expanded"); // Get the current state
    
      if (isExpanded) {
        x.html("Expand All +");
        $('#travel-accordion .collapse').collapse('hide');
      } else {
        x.html("Collapse All -");
        $('#travel-accordion .collapse').collapse('show');
      }
    
      x.data("expanded", !isExpanded); // Toggle the state
    }
    
    // Initial setup
    $(document).ready(function() {
      $("#travelClick").data("expanded", false); // Set initial state
    });
    .panel-title:hover,
    #travelClick {
      cursor: pointer;
    }
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
    <p class="text-right" id="travelClick" onclick="travelAccordion()"> Expand All +</p>
    <div class="panel-group" id="travel-accordion">
      <div class="panel panel-default">
        <div class="panel-heading">
          <a aria-expanded="false" class="collapsed" data-parent="#travel-accordion" data-toggle="collapse" href="#collapse1">
            <h4 class="panel-title">Group 1</h4>
          </a>
        </div>
        <div class="panel-collapse collapse" id="collapse1" style="">
          <div class="panel-body">
            Group 1 Text
          </div>
        </div>
        <div class="panel-heading">
          <a aria-expanded="false" class="collapsed" data-parent="#travel-accordion" data-toggle="collapse" href="#collapse2">
            <h4 class="panel-title">Group 2</h4>
          </a>
        </div>
        <div class="panel-collapse collapse" id="collapse2" style="">
          <div class="panel-body">
            Group 2 Text
          </div>
        </div>
      </div>
    </div>