Hatface
Hatface

Reputation: 11

Class toggle removes other classes

Good morning SO,

I am trying to toggle between 3 classes to assign colors to text boxes. The toggleClass method works for 2 classes but not for 3 so I wrote a function based off of a response I found on SO to how to toggle between 3 classes. After I hit the ready button to toggle classes the first time, instead of toggling the classes it removes all existing classes and adds the class in the array instead appending one of the 3 classes in the array to the end. This since the text boxes are targeted by class, this prevents me from being able to click the button to move on to the next class. How could I change my code to stop it from removing the initial set of classes?

JQuery

    $(document).ready(function () {
    
        $('#btn1').click(function() {
            $('.tb1').each(function () {
                var classes = ['red', 'green', 'blue'];
                this.className = classes[($.inArray(this.className, classes) + 1) % classes.length];
            });
        });
    }); 
.tbleft{
    font-size: 63px;
    width: 28%;
    color:white;
    margin-top:.5%
}
.tbcenter{
    font-size: 63px;
    width: 20%;
    color:white;
    margin-top:.5%
}
.green{
    background-color: green;
}
.red{
    background-color: red;
}
.blue{
    background-color:dodgerblue;
}
<form class="leftform" action="/write" method="post">
       <input class="tb1 tbleft red" id="tb1-1" type="text" name="loads"/>
       <input class="tb1 tbcenter red" id="tb1-2" type="text" name="door"/>
       <input class="tb1 tbcenter red" id="tb1-3" type="text" name="quad"/>
       <input class="btn" id="btn1" type="button" value="Ready"/>
       </form> 

jsfiddle

Any assistance would be appreciated.

Upvotes: 1

Views: 89

Answers (5)

Andrew Bazylskyi
Andrew Bazylskyi

Reputation: 56

You can use data attributes. Just add another color to data-colors attribute.

var colorsStr = $('#btn1').data('colors');
var colorsArr = colorsStr.split(',').reverse();
var index = colorsArr.length - 1;

$('#btn1').click(function() {

  if (index < 0) index = colorsArr.length - 1;
  
  $.each($('.tb1'), function(key, val) {
    $(val).css('background-color', colorsArr[index]);
  })

  index -= 1;
});
.tbleft{
    font-size: 63px;
    width: 28%;
    color:white;
    margin-top:.5%
}
.tbcenter{
    font-size: 63px;
    width: 20%;
    color:white;
    margin-top:.5%
}
.red{
    background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form class="leftform" action="/write" method="post">
  <input class="tb1 tbleft red" id="tb1-1" type="text" name="loads"/>
  <input class="tb1 tbcenter red" id="tb1-2" type="text" name="door"/>
  <input class="tb1 tbcenter red" id="tb1-3" type="text" name="quad"/>
  <input class="btn" id="btn1" type="button" value="Ready" data-colors="green, blue, red"/>
</form>

Upvotes: 0

adiga
adiga

Reputation: 35222

Create 2 variables called previousClass and newClass:

$(document).ready(function () {

    var previousClass = "red", newClass = "red";
    var classes = ['red', 'green', 'blue'];

    $('#btn1').click(function () {
        previousClass = newClass;
        newClass = classes[($.inArray(previousClass, classes) + 1) % classes.length];

        $('.tb1').each(function () {
            $(this).removeClass(previousClass).addClass(newClass);
        });
    });
});

here's a fiddle: https://jsfiddle.net/Lrjsheot/1/

Upvotes: 0

Terry
Terry

Reputation: 66103

The reason you are stripping all the classes off the elements is because those that are not in the array will also be stripped out.

Since red is also guaranteed to be in your classes list, we can:

  1. Return the color class by filtering through the classList
  2. Get new color based on the returned color class
  3. Use classList.remove() to remove old class
  4. Use classList. add() to add new class

Of course, this means that the browser needs to support the modern DOMTokenList API.

$(document).ready(function() {

  var classes = ['red', 'green', 'blue'];

  $('#btn1').click(function() {
    $('.tb1').each(function() {
      // Retrieve color classes from classList by checking if it is in classes array
      var colorClass = [].filter.call(this.classList, function(cls) {
        return classes.indexOf(cls) > -1;
      })[0];
      
      // Get new color
      var newColorClass = classes[($.inArray(colorClass, classes) + 1) % classes.length];
      
      // Remove old class, add new class
      this.classList.remove(colorClass);
      this.classList.add(newColorClass);
    });
  });
});
.tbleft {
  font-size: 63px;
  width: 28%;
  color: white;
  margin-top: .5%
}

.tbcenter {
  font-size: 63px;
  width: 20%;
  color: white;
  margin-top: .5%
}

.green {
  background-color: green;
}

.red {
  background-color: red;
}

.blue {
  background-color: dodgerblue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form class="leftform" action="/write" method="post">
  <input class="tb1 tbleft red" id="tb1-1" type="text" name="loads" />
  <input class="tb1 tbcenter red" id="tb1-2" type="text" name="door" />
  <input class="tb1 tbcenter red" id="tb1-3" type="text" name="quad" />
  <input class="btn" id="btn1" type="button" value="Ready" />
</form>

Upvotes: 0

Milan Chheda
Milan Chheda

Reputation: 8249

You can try the below code. I have done some significant changes to rotate the colors:

$(document).ready(function() {
  var classes = ['red', 'green', 'blue'];
  $('#btn1').click(function() {
    $('.tb1').each(function() {
      var current = $(this);
      $(classes).each(function(k, v) {
        if (current.hasClass(v)) {
          var keyNum = k + 1
          if (classes.length == (k + 1)) {
            keyNum = 0
          }
          current.removeClass(v).addClass(classes[keyNum]);
          return false;
        }
      });
    });
  });
});
.tbleft {
  font-size: 63px;
  width: 28%;
  color: white;
  margin-top: .5%
}

.tbcenter {
  font-size: 63px;
  width: 20%;
  color: white;
  margin-top: .5%
}

.green {
  background-color: green;
}

.red {
  background-color: red;
}

.blue {
  background-color: dodgerblue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form class="leftform" action="/write" method="post">
  <input class="tb1 tbleft red" id="tb1-1" type="text" name="loads" />
  <input class="tb1 tbcenter red" id="tb1-2" type="text" name="door" />
  <input class="tb1 tbcenter red" id="tb1-3" type="text" name="quad" />
  <input class="btn" id="btn1" type="button" value="Ready" />
</form>

Upvotes: 2

Konrad
Konrad

Reputation: 1

Instead of using this.className, try with $(this).addClass() and $(this).removeClass().

this.className overwrites all classes you have for that element. Instead, you want to remove only the colour class, and add a new one.

Upvotes: -1

Related Questions