Iteration on CSS class array and Toggle class on click

68
July 23, 2019, at 12:00 PM

I have this code

The problem is I need to toggle class on click. I have classes

.col
.col-1 / .col-2 / col-3 etc.

and I need to apply on click to the right .col-1 / col-2 an expand class, so it would like

.col .col-1 .col-1--expand
.col .col-2 .col-2--expand

Before I had this on hover in CSS and it works, but make it on click is little problematic. I searched whole day Javascript and jQuery cases, but I haven't found any right solution to it. What I learned, I must use forEach function in Javascript, but a solution in jQuery is also what I want. I tried something like this on my project, but I'm still bad at Javascript :(

if (document.querySelector('.slider__col')) {
const expandElement = element.querySelectorAll('.slider__col')
expandElement.forEach(element => {
    element.addEventListener('click', function() {
        element.classList.toggle("");
    })
})
Answer 1

You can use a regular expression to match element classes and toggle the expand class on that element when clicked.

var matched = this.className.match(/col-\d{1,2}/);

This will find any classes in your element's class attribute that contains col- followed by any numbers up to two digits so you can cater for 1-99.

matched.length && (matched = matched.pop())

.match() returns an array of matches so you can determine if any matches were found and pop the first match off of the array.

var expandClass = matched + '--expand';

Because you're matching, for example, col-1 you can use this string and append --expand to make col-1--expand.

$(this).toggleClass(expandClass);

You can use jQuery's toggleClass to add/remove the expandClass depending on the class's presence. See col-3 for demonstration.

$(document).on('click', '.col', function () { 
  var matched = this.className.match(/col-\d{1,2}/); 
  if (matched.length && (matched = matched.pop())) { 
    var expandClass = matched + '--expand'; 
    $(this).toggleClass(expandClass); 
  } 
});
.col { 
  background-color: blue; 
  color: white; 
  padding: .25rem 1rem; 
  margin: .25rem 0; 
} 
 
.col-1--expand, 
.col-2--expand, 
.col-3--expand, 
.col-4--expand, 
.col-5--expand, 
.col-6--expand { 
  background-color: green; 
  padding-top: 1rem; 
  padding-bottom: 1rem; 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> 
 
<div id="grid"> 
  <div class="col col-1">1</div> 
  <div class="col col-2">2</div> 
  <div class="col col-3 col-3--expand">3</div> 
  <div class="col col-4">4</div> 
  <div class="col col-5">5</div> 
  <div class="col col-6">6</div> 
</div>

Answer 2

Welcome to StackOverflow! Since you want a solution in jQuery, let me give you some guidance.

1. The forEach function is in jQuery available as the .each() method. Making your code:

// Select your classes, for each of them run a function
$('.col-1').each(function() { });

2. To make something happen on a click, jQuery has a .click() method available, it will call a function on click. Making your code:

$('.col-1').each(function() {
    // Click method:
    $(this).click(function() { } );
});
// Or just do:
$('.col-1').click(function() { });

jQuery does not need a loop and can bind the click method to all classes by itself. There are cases where it still might be useful, but let's keep it basic for now and get your code working!

3. Adding the new CSS class. In jQuery there are many methods you can use for it. In this case you are probably looking for the .toggleClass() method. Other useful ones might me .addClass() and .removeClass(). Making your code:

$('.col-1').click(function() {
    $(this).toggleClass("col-1--expand");
});
// Or just add it:
$('.col-1').click(function() {
    $(this).addClass("col-1--expand");
});

Done, repeat for other classes where you want to do some magic. Next time try spending a day on the jQuery API Documentation. All the methods are there, with great examples included! Best of luck with it.

READ ALSO
Laravel 5, Ngnix web server www-data permissions issue

Laravel 5, Ngnix web server www-data permissions issue

I'm running a Laravel 54 app in the Ngnix server

74
Controlling dependencies in Symfony tests

Controlling dependencies in Symfony tests

I have a number of edge to edge tests for my Symfony 42 application

97
Automating the addition of columns based on changes made to another table in MySQL

Automating the addition of columns based on changes made to another table in MySQL

I want to automate the addition of columns into a MySQL table based on changes made to an existing table

65