Ber B
Ber B

Reputation: 97

Add multiple classes to an element using .attr?

I am currently trying to add multiple classes from a variable created when the user selects checkboxes to an element using $('.element').attr but this doesn't seem to be working so far - this method seems to be only getting the first class in the array, .addClass works only to add the classes and not remove them.

Is there any workaround to this?

The Code used is:

$('.ms-drop').on('change', function(){

        var val = [];

        var selectedItem  = $(this).find('input').attr('value');

        //get the values of each checked checkbox
        $(this).find('li > label > input:checked').each(function(i){
            val[i] = $(this).val();
        });

        var new_class = val.join(' ');

        console.log(new_class);

        $('.editable').attr('class', new_class);

        $('.writeHere').html(new_class);

});

Please see the link below to see it working:

JSBin

Any help will be greatly appreciated!

Upvotes: 1

Views: 2586

Answers (2)

Rhumborl
Rhumborl

Reputation: 16609

I would listen to the input onchange instead and just use toggleClass:

$('.ms-drop input[type="checkbox"]').on('change', function(){
  $('.editable').toggleClass($(this).val());
  $('.editable').html($('.editable').attr('class')); // for debug purposes
});
<!DOCTYPE html>
<html>
<head>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  
  <section class="ms-drop">
    <ul>
      <li>
        <label>
          <input type="checkbox" value="Class1">
        </label>
      </li>
      <li>
        <label>
          <input type="checkbox" value="Class2">
        </label>
      </li>
      <li>
        <label>
          <input type="checkbox" value="Class3">
        </label>
      </li>
      <li>
        <label>
          <input type="checkbox" value="Class4">
        </label>
      </li>
    </ul>
  </section>
  
  
  <div class="editable">
    Class: <span class="writeHere">Hehe</span>
  </div>
  
  
</body>
</html>

EDIT If other code can change the style of .editable as @Roamer-1888 mentions, you can test the checked state of the box and decide to add or remove, rather than just toggle (although anything else changing the classes would make the checkboxes out of sync anyway which is a functional bug in itself):

$('.ms-drop input[type="checkbox"]').on('change', function(){
  if($(this).is(':checked'))
    $('.editable').addClass($(this).val());
  else
    $('.editable').removeClass($(this).val());

  $('.editable').html($('.editable').attr('class')); // for debug purposes
});

Upvotes: 6

iCollect.it Ltd
iCollect.it Ltd

Reputation: 93601

Remove all existing classes via removeAttr(), then add them using addClass():

$('.editable').removeAttr('class');
$('.editable').addClass(new_class);

Which can be chained to just:

$('.editable').removeAttr('class').addClass(new_class);

Your join code appears to work correctly and in theory attr will replace the classes. I actually suspect you have another issue going on.

Actual issue: You are basically removing the class you are using to match the elements with you need to change the way you find them e.g add an id to that field instead:

 <div id="myedit" class="editable">
    Class: <span class="writeHere">Hehe</span>
  </div>

and change the way tyou access it from $('.editable') to:

$('#myedit').addClass...

Thanks for all the votes, but I actually think Rhumborl's approach is cleaner and better for the problem specified. Please upvote his :)

Upvotes: 9

Related Questions