Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using jQuery to remove & add classes to buttons, the new class added won't work with it's click function

I have 2 buttons, click one will swap classes for both buttons.
The classes are selected and unselected.

My CodePen:
http://codepen.io/leongaban/pen/iLBvs

enter image description here

For example: click the Login button will remove it's unselected class and give it its selected class and give the Register button its unselected class.

Now the problem is that the register_unselected class doesn't work. The unselected classes are the ones that have click actions in my jQuery.

I should be able to keep clicking the gray button and turning it blue. However after clicking the first gray button (login) the new gray button register doesn't work.

Using Chrome's inspector I can clearly see that my register_unselected class has been added, yet the click function doesn't work.

enter image description here

Any ideas? How would you approach this?

// Login Tab (default : first)
$(".login_unselected").click(function(){

  console.log('clicked login');

  // Show Login Tab as selected
  $(this)
    .removeClass('login_unselected')
    .addClass('login_selected');

  // Show Register Tab as unselected
  $(this).parent().find('#tab_register')
    .removeClass('register_selected')
    .addClass('register_unselected');

});

// Register Tab
$(".register_unselected").click(function(){

  console.log('clicked register');

  // Show Login Tab as selected
  $(this)
    .removeClass('register_unselected')
    .addClass('register_selected');

  // Show Register Tab as unselected
  $(this).parent().find('#tab_login')
    .removeClass('login_selected')  
    .addClass('login_unselected');

});
like image 619
Leon Gaban Avatar asked Jun 13 '13 22:06

Leon Gaban


Video Answer


2 Answers

When you call $(".register_unselected").click() jQuery actually searches the DOM for any elements matching .register_unselected and then listens for click events on them. Since your element won't exist until after this method is called, this will have no effect.

Instead, use $("body").on("click", ".register_unselected", function(){});

You could also replace body with another selector that will always contain the element changing classes.

EDIT: Here's a forked CodePen: http://codepen.io/anon/pen/DqFuL

like image 160
mash Avatar answered Sep 16 '22 15:09

mash


Nobody has given the more obvious and elegant solution.

Lets clean up the CSS a little:

//instead of .login_unselected, .registerunselected  
.target {
      color: #ccc;
      background: #666;
      cursor: pointer;
}

//instead of .x_selected, .y_selected
.selected {
      color: #fff;
      background: #3399cc;
      text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);
}

So the HTML is now

<ul>
    <li id="tab_login" class="target">Login</li>
    <li id="tab_register" class="target">Register</li>
</ul>

The jQuery is:

$("ul").on("click", ".target", function(){

      // Remove selected class from any that have it
      $(".target").removeClass('selected');
      // Add class to the one you're clicking on
      $(this).addClass('selected');

});

Instead of calling the class .target you can call it .unselected. From the context of your question it's likely that you don't need two separate classes, classes are made to be applied to many elements and if you need to reference them individually you have the ids already.

Also remember, you can apply many classes to an element and then override styles from one class by specifying different property values on the last class. Whichever class is applied last will override the settings of any classes already applied to it, unless values for the properties you wish to override have not been specified in the overriding class.

like image 21
Dom Avatar answered Sep 16 '22 15:09

Dom