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?

Isaac Gregson
  • 1,999
  • 1
  • 21
  • 31
  • If those are the only classes that will be applied to `.body`, then you can use `$('.body').removeClass().addClass(bgClass);` – j08691 Mar 17 '14 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). – Isaac Gregson Mar 17 '14 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 – Arun P Johny Mar 17 '14 at 17:46

2 Answers2

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.

Serlite
  • 12,130
  • 5
  • 38
  • 49
  • 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)? – Isaac Gregson Mar 17 '14 at 18:06
  • Shouldn't be! If no class matches the string passed to removeClass(), it will just do nothing. – Serlite Mar 17 '14 at 20:22
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

Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
  • 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 href`s or `button` tags with `data-` elements are better in this case? – Isaac Gregson Mar 17 '14 at 17:51
  • 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! – Isaac Gregson Mar 17 '14 at 18:03