skip to Main Content

I got this script half-working but need help finishing it off. My jQuery skills are weak at best.

I’m basically creating an interactive flow chart using jQuery to add an expand class. But I went in search of a solution that would be more elegant than 1000 individual addClass scripts.

HTML (I removed excessive stuff):

<div class="x">
  <div class="x">Question</div>
  <button for="question-1-yes-action" class="x">Yes</button>
  <button for="question-1-no-action" class="x">No</button>
</div>
<div class="x">
  <div id="question-1-yes-action" class="x">
    <div class="x">Answer Yes</div>
  </div>
  <div id="question-1-no-action" class="x">
    <div class="x">Answer No</div>
  </div>
</div>

jQuery:

$(function() {
    var currentFlow = $("button").attr("for");
    $("button").click(function() {
        $( "div[ id=" + currentFlow + "]").addClass( "expand" );
    });
});

The idea was to identify the container that needed the "expand" class added to it based on the for/ID relationship. At first, I thought it worked! If I click "Yes" the "Answer Yes" will get the "expand" class added to it. However… if I click "No," the "Answer Yes" also gets the "expand" class added to it. So clearly I did something wrong. I just don’t know what it is or if my logic will even succeed.

Any advice would be appreciated.

3

Answers


  1. Your code is nearly there, the issue you have is that you only set currentFlow once, when the page loads. It instead needs to be set when the click event happens, and it needs to read the for from the button which was clicked.

    In addition, it’s not good practice to create non-standard attributes in your HTML. In this case, for. If you want to store custom metadata in your HTML, use a data attribute instead.

    Lastly, if you’re going to select an element by its id, use an id selector, not an attribute selector.

    Here’s a working example with all these amendments incorporated:

    jQuery($ => {
      $('.action-button').on('click', e => {
        e.preventDefault();
        $('.expand').removeClass('expand');
        let currentFlow = $(e.target).data("for");
        $(currentFlow).addClass('expand');
      });
    });
    .answer { display: none; }
    .answer.expand { display: block; }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <div class="question-container">
      <div class="question">Question</div>
      <button type="button" data-for="#question-1-yes-action" class="action-button">Yes</button>
      <button type="button" data-for="#question-1-no-action" class="action-button">No</button>
    </div>
    <div class="answer-container">
      <div id="question-1-yes-action" class="answer">
        <div>Answer Yes</div>
      </div>
      <div id="question-1-no-action" class="answer">
        <div>Answer No</div>
      </div>
    </div>

    Note that I also replaced all your x classes with more meaningful names.

    Login or Signup to reply.
  2. You will have to fetch the for attribute on click of the button. So that the script fetches the attribute of the clicked button.

    In your case, by default the attribute of the first button is retrieved. I have modified the code as shown below:

    $(function() {
        $("button").click(function() {
            var currentFlow = $(this).attr("for");
            $( "div[ id=" + currentFlow + "]").addClass( "expand" );
        });
    });
    
    Login or Signup to reply.
  3. $(function() {
      $('button[for*="-action"]').click(function() {
        var id = $(this).attr('for');
        $('div[id*="-action"]').removeClass('expand');
        $('div[id="' + id + '"]').addClass('expand');
      });
    });
    .expand {
      background-color: red;
      padding-bottom: 50px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="x">
      <div class="x">Question</div>
      <button for="yes-action" class="x">Yes</button>
      <button for="no-action" class="x">No</button>
    </div>
    
    <div class="x">
      <div id="yes-action" class="action">
        <div class="x">Answer Yes</div>
      </div>
      <div id="no-action" class="action">
        <div class="x">Answer No</div>
      </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search