3

Simple jquery click toggle function here, though due to my limited knowledge and experience I'm in need of some direction.

I have a set of buttons with a shared boxedBgSwitch class that each have have a uniquie data-id. I'd like to assign the data-id as a class to the body of my document on click, and only one class should be assigned at a time. The below code works for assigning the classes, but it doesn't remove the previously added classes before adding the new one. What is the recommended way to do this?

jQuery

  $('.boxedBgSwitch').on('click', function(e){
    e.preventDefault();
    var bgClass = $(this).data("id");
    $('body').toggleClass(bgClass);
  });

HTML

  <button data-id="bg-blue" class="boxedBgSwitch color-box"></button>
  <button data-id="bg-yellow" class="boxedBgSwitch color-box"></button>
  <button data-id="bg-red" class="boxedBgSwitch color-box"></button>
  <button data-id="bg-orange" class="boxedBgSwitch color-box"></button>
  <button data-id="bg-green" class="boxedBgSwitch color-box"></button>

Obviously, I'm new to jQuery... seems there should be an addOrRemoveClass method for this very purpose. Perhaps there's an equivalent?

3
  • If those are the only classes that will be applied to .body, then you can use $('.body').removeClass().addClass(bgClass); Commented Mar 17, 2014 at 17:41
  • unfortunately there are others :( But it's good to know that calling an empty .removeClass() will clear the classes (I assume this is what's happening here, please correct if wrong). Commented Mar 17, 2014 at 17:45
  • @IsaacGregson yes... so it is best to remove the class name starting with bg- - assuming there are no other class starting like that Commented Mar 17, 2014 at 17:46

2 Answers 2

2

Hmmm, a very basic solution I can think for this is to store the last applied class in a variable, then remove that before applying the new class. Something along this line:

var lastBg = "";

$('.boxedBgSwitch').on('click', function (e) {
    e.preventDefault();
    var bgClass = $(this).data("id");
    $('body').removeClass(lastBg).addClass(bgClass);
    lastBg = bgClass;
});

Can't say this is the best solution, but it seems to work reliably, and won't break even if you start changing up class names. Here's a JSFiddle to demonstrate it in action. Hope this helps! Let me know if you have any questions.

Sign up to request clarification or add additional context in comments.

2 Comments

This did the trick very nicely, and I quite like the basic and clean nature of it. Didn't realize it was possible to set a blank variable like that and simply remove it before adding the new class. I take it there are no problems removing something that's not there in the first place (an empty string)?
Shouldn't be! If no class matches the string passed to removeClass(), it will just do nothing.
1

There are multiple problems

  • Assuming you are trying to change the class of an element with class body, not the class of the body element itself
  • ul should have li as the children, button cannot be direct child of ul element

Ty

$('.boxedBgSwitch').on('click', function (e) {
    e.preventDefault();
    var bgClass = $(this).data("id");
    $('.body').attr('class', function (i, clazz) {
        return (clazz || '').replace(/bg-.*?(\s|$)/, '') + ' ' + bgClass;
    });
});

Demo: Fiddle

2 Comments

Thanks for your incredibly fast and helpful answer, @Arun. Didn't realize I was calling the class body... should have been simply body and I previously had this formatted as a list, wasn't sure if I'd be sticking with the button elements of going back to li tags, but I've edited each out of the question appropriately. Is there a best practice here for whether a hrefs or button tags with data- elements are better in this case?
Because your answer works and you helped me spot some errors in the HTML, I'm giving this an up-vote. But I try to stay away from regular expressions unless I absolutely need to use them, so I much prefer the clean nature of @Serlite's answer. Many thanks, though!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.