Abstracting the adding of click events to elements selected by class using jQuery

Posted by baroquedub on Stack Overflow See other posts from Stack Overflow or by baroquedub
Published on 2010-05-21T14:20:12Z Indexed on 2010/05/21 14:30 UTC
Read the original article Hit count: 191

I'm slowly getting up to speed with jQuery and am starting to want to abstract my code. I'm running into problems trying to define click events at page load.

In the code below, I'm trying to run through each div with the 'block' class and add events to some of its child elements by selecting them by class:

<script language="javascript" type="text/javascript">
$(document).ready(function (){

$('HTML').addClass('JS'); // if JS enabled, hide answers

 $(".block").each(function() { 
  problem = $(this).children('.problem');
  button = $(this).children('.showButton');

  problem.data('currentState', 'off');

  button.click(function() {
   if ((problem.data('currentState')) == 'off'){
    button.children('.btn').html('Hide');
    problem.data('currentState', 'on');
    problem.fadeIn('slow');
   } else if ((problem.data('currentState')) == 'on'){
    button.children('.btn').html('Solve');
    problem.data('currentState', 'off');
    problem.fadeOut('fast');
   }
   return false;

  });
 });
});
</script>

<style media="all" type="text/css">
.JS div.problem{display:none;}
</style>


<div class="block">
    <div class="showButton">
        <a href="#" title="Show solution" class="btn">Solve</a>
    </div>

    <div class="problem">
      <p>Answer 1</p>
    </div>
</div>

<div class="block">
    <div class="showButton">
        <a href="#" title="Show solution" class="btn">Solve</a>
    </div>

    <div class="problem">
      <p>Answer 2</p>
    </div>
</div>

Unfortunately using this, only the last of the divs' button actually works. The event is not 'localised' (if that's the right word for it?) i.e. the event is only applied to the last $(".block") in the each method.

So I have to laboriously add ids for each element and define my click events one by one. Surely there's a better way! Can anyone tell me what I'm doing wrong? And how I can get rid of the need for those IDs (I want this to work on dynamically generated pages where I might not know how many 'blocks' there are...)

<script language="javascript" type="text/javascript">
$(document).ready(function (){

$('HTML').addClass('JS'); // if JS enabled, hide answers

 // Preferred version DOESN'T' WORK  
 // So have to add ids to each element and laboriously set-up each one in turn...

 $('#problem1').data('currentState', 'off');

 $('#showButton1').click(function() {
  if (($('#problem1').data('currentState')) == 'off'){
   $('#showButton1 > a').html('Hide');
   $('#problem1').data('currentState', 'on');
     $('#problem1').fadeIn('slow');
  } else if (($('#problem1').data('currentState')) == 'on'){
   $('#showButton1 > a').html('Solve');
   $('#problem1').data('currentState', 'off');
     $('#problem1').fadeOut('fast');
  }
  return false;

 });


 $('#problem2').data('currentState', 'off');

 $('#showButton2').click(function() {
  if (($('#problem2').data('currentState')) == 'off'){
   $('#showButton2 > a').html('Hide');
   $('#problem2').data('currentState', 'on');
     $('#problem2').fadeIn('slow');
  } else if (($('#problem2').data('currentState')) == 'on'){
   $('#showButton2 > a').html('Solve');
   $('#problem2').data('currentState', 'off');
     $('#problem2').fadeOut('fast');
  }
  return false;

 });

});
</script>

<style media="all" type="text/css">
.JS div.problem{display:none;}
</style>



<div class="block">
    <div class="showButton" id="showButton1">
        <a href="#" title="Show solution" class="btn">Solve</a>
    </div>

    <div class="problem" id="problem1">
      <p>Answer 1</p>
    </div>
</div>

<div class="block">
    <div class="showButton" id="showButton2">
        <a href="#" title="Show solution" class="btn">Solve</a>
    </div>

    <div class="problem" id="problem2">
      <p>Answer 2</p>
    </div>
</div>

© Stack Overflow or respective owner

Related posts about jQuery

Related posts about JavaScript