Ganidu Ranasinghe
Ganidu Ranasinghe

Reputation: 225

Switching between three classes with different names

I have a header and three different classes defines three different sizes. On click of the different buttons I need to apply the size class to the header and remove the existing heading size class.

JS Fiddle

<div class="row">
  <div class="col-sm-12">
    <div class="layout-attachments">
      <ul class="list-inline layout-components">
        <li class="list-inline-item"><a id="smallHeader">S</a></li>
        <li class="list-inline-item"><a id="mediumHeader">M</a></li>
        <li class="list-inline-item"><a id="largeHeader">L</a></li>

      </ul>
      <h1 class="img-responsive img-thumbnail w-75-p">Change the class of this element</h1>
</div>

jQuery:

this.$('.list-inline-item').click(function() {

    if ($('.layout-attachments h1').hasClass('w-50-p')) {
        $('.layout-attachments h1').removeClass('w-50-p').addClass('w-75-p ');
    } else if ($('.layout-attachments h1').hasClass('w-75-p ')) {
        $('.layout-attachments h1').removeClass('w-75-p ').addClass('w-100-p');
    } else if ($('.layout-attachments h1').hasClass('w-100-p')) {
        $('.layout-attachments h1').removeClass('w-100-p').addClass('w-50-p');
    }
});
});

Upvotes: 0

Views: 99

Answers (5)

Varun
Varun

Reputation: 241

Maintain the class which alters the font size in the list item as a data attribute and add the new class to the target on click event!

Here is the working solution..

var $item = $('.list-inline-item'),
  $target = $('.img-responsive.img-thumbnail');

$item.on('click', function() {
  var size = $(this).find('a').data('size');
  
  $target
    .removeClass('w-50-p w-75-p w-100-p') // remove size classes
    .addClass(size);
});
.w-50-p {
  font-size: 1em;
}

.w-75-p {
  font-size: 1.5em;
}

.w-100-p {
  font-size: 2em;
}

.list-inline-item a {
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
  <div class="col-sm-12">
    <div class="layout-attachments">
      <ul class="list-inline layout-components">
        <li class="list-inline-item"><a data-size="w-50-p">S</a></li>
        <li class="list-inline-item"><a data-size="w-75-p">M</a></li>
        <li class="list-inline-item"><a data-size="w-100-p">L</a></li>

      </ul>
      <h1 class="img-responsive img-thumbnail w-75-p">Change the class of this element</h1>
    </div>

Upvotes: 1

dabishan
dabishan

Reputation: 691

You can do this:

    <div class="row">
        <div class="col-sm-12">
            <div class="layout-attachments">
            <ul class="list-inline layout-components">
                <li class="list-inline-item"><a id="smallHeader" data-new-class="w-50-p">S</a></li>
                <li class="list-inline-item"><a id="mediumHeader" class="active" data-new-class="w-75-p">M</a></li>
                <li class="list-inline-item"><a id="largeHeader" data-new-class="w-100-p">L</a></li>

            </ul>
            <h1 class="img-responsive img-thumbnail w-75-p">Change the class of this element</h1>
        </div>
    </div>

there is an class="active" and data-new-class="w-75-p" that track what is currently clicked and what class to apply when click. You can find a better name for the data attribute.

For javascript:

$('.list-inline-item a').click(function() {

  var $activeSize = $('.list-inline-item a.active');
  // removes active from current
  $activeSize.removeClass('active');

  var $heading = $('.layout-attachments h1')

  //removes the class and add class you want
  $heading.removeClass($activeSize.data('newClass'));
  $heading.addClass($(this).data('newClass'));

  //add active to the clicked one
  $(this).addClass("active")
});

JS Fiddle

Upvotes: 1

KHansen
KHansen

Reputation: 930

You had some errors in your jQuery:

$('.list-inline-item').on('click', function() {
  if ($('.layout-attachments h1').hasClass('w-50-p')) {
    $('.layout-attachments h1').removeClass('w-50-p').addClass('w-75-p');
  } else if ($('.layout-attachments h1').hasClass('w-75-p')) {
    $('.layout-attachments h1').removeClass('w-75-p ').addClass('w-100-p');
  } else if ($('.layout-attachments h1').hasClass('w-100-p')) {
    $('.layout-attachments h1').removeClass('w-100-p').addClass('w-50-p');
  }
});

But either way the code doesn't make much sense as it is, because it doesn't matter what li item you click.

Edit:

html:

<div class="row">
    <div class="col-sm-12">
        <div class="layout-attachments">
        <ul class="list-inline layout-components">
            <li class="list-inline-item" data-size="w-50-p"><a id="smallHeader">S</a></li>
            <li class="list-inline-item" data-size="w-75-p"><a id="mediumHeader">M</a></li>
            <li class="list-inline-item" data-size="w-100-p"><a id="largeHeader">L</a></li>
        </ul>
        <h1 id="w-75-p" class="img-responsive img-thumbnail">Change the class of this element</h1>
    </div>
</div>

jQuery:

$('.list-inline-item').on('click', function() {
  var newSize = $(this).attr("data-size");
  $(".layout-attachments h1").removeAttr("id").attr("id", newSize)
});

css:

#w-50-p {font-size: 18px;}
#w-75-p {font-size: 26px;}
#w-100-p {font-size: 34px;}

The easiest was is to use an id on the target element and set a data attribute which refers to the correct id.

Upvotes: 1

Alen.Toma
Alen.Toma

Reputation: 4870

This is very easy. Here i made an example.

Make sure to read the comment and also have a look at attribute Size

var sizes= ["w-75-p", "w-100-p", "w-50-p" ] 
$('.list-inline-item').click(function() {
  sizes.forEach((item)=> $('.layout-attachments h1').removeClass(item) ); // reset the size.
  
  // now Add the right Size
  $('.layout-attachments h1').addClass($(this).attr("size"))

});
.w-50-p {
    font-size: 18px;
}

.w-75-p {
    font-size: 26px;
}

.w-100-p {
    font-size: 34px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
        <div class="col-sm-12">
            <div class="layout-attachments">
            <ul class="list-inline layout-components">
                <li class="list-inline-item" size="w-50-p"><a id="smallHeader">S</a></li>
                <li class="list-inline-item" size="w-75-p"><a id="mediumHeader">M</a></li>
                <li class="list-inline-item" size="w-100-p"><a id="largeHeader">L</a></li>
               
            </ul>
            <h1 class="img-responsive img-thumbnail w-75-p">Change the class of this element</h1>
        </div>
    </div>

Upvotes: 3

JoshG
JoshG

Reputation: 6735

There are a couple of issues with your code. For starters, you have a syntax error in your jQuery block. You also don't need spaces after your class names in the removeClass calls. But the biggest issue is you need to be able to determine if the user has clicked "small", "medium", or "large" in order to apply the correct class. Otherwise, if you make the other corrections I mentioned, as it is right now you will basically just be toggling through the three classes.

Here's how I might approach the problem, with click handlers for each of the list elements (small, medium, large):

this.$('.list-inline-item').click(function(e) {

  if (e.target.id === "smallHeader") {
    // handle small case
    $(".layout-attachments h1").removeClass("w-75-p w-100-p").addClass("w-50-p");
  } else if (e.target.id === "mediumHeader") {
    // handle medium case
    $(".layout-attachments h1").removeClass("w-50-p w-100-p").addClass("w-75-p");
  } else if (e.target.id === "largeHeader") {
    // handle large case
    $(".layout-attachments h1").removeClass("w-50-p w-75-p").addClass("w-100-p");
  } else {
    // unhandled case
  }
});
.w-50-p {
  font-size: 18px;
}

.w-75-p {
  font-size: 26px;
}

.w-100-p {
  font-size: 34px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.1/jquery.min.js"></script>
<div class="row">
  <div class="col-sm-12">
    <div class="layout-attachments">
      <ul class="list-inline layout-components">
        <li class="list-inline-item"><a id="smallHeader">S</a></li>
        <li class="list-inline-item"><a id="mediumHeader">M</a></li>
        <li class="list-inline-item"><a id="largeHeader">L</a></li>

      </ul>
      <h1 class="img-responsive img-thumbnail w-75-p">Change the class of this element</h1>
    </div>
  </div>

Another thing you could do, instead of calling removeClass with the other classes you don't want attached to the element, is add a function to jQuery that will remove all classes according to some substring. For example, with this function, you could remove all classes starting with "w-":

$.fn.removeClassStartingWith = function (filter) {
    $(this).removeClass(function (index, className) {
        return (className.match(new RegExp("\\S*" + filter + "\\S*", 'g')) || []).join(' ')
    });
    return this;
};

You could invoke it then like this:

$(".layout-attachments h1").removeClassStartingWith("w-").addClass("w-50-p");

This is not absolutely necessary but might be useful.

Upvotes: 1

Related Questions