Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jquery previous element with several classes

I got this structure of table :

<tr class="dossier">
  <td>...</td>
  <td>...</td>
</tr>
<tr class="detail">
  <td>...</td>
  <td>...</td>
</tr>
<tr class="detail alert">
  <td>...</td>
  <td>...</td>
</tr>
<tr class="dossier">
  <td>...</td>
  <td>...</td>
</tr>
<tr class="detail">
  <td>...</td>
  <td>...</td>
</tr>
<tr class="detail">
  <td>...</td>
  <td>...</td>
</tr>
<tr class="even dossier">
  <td>...</td>
  <td>...</td>
</tr>
<tr class="detail">
  <td>...</td>
  <td>...</td>
</tr>
<tr class="detail alert">
  <td>...</td>
  <td>...</td>
</tr>

When a tr element has alert class, I have to add alert class to the previous element with dossier class.

I try this code :

$("tr.alert").prev("tr.dossier").addClass("alert");

This is working only with <tr class="dossier"> elements. It doesn't work with<tr class="even dossier"> elements.

Has somebody a way to do this ?

like image 642
user3469203 Avatar asked Oct 05 '15 12:10

user3469203


People also ask

How do you select an element with multiple classes?

Use the getElementsByClassName method to get elements by multiple class names, e.g. document. getElementsByClassName('box green') . The method returns an array-like object containing all the elements that have all of the given class names.

How can use two classes in jQuery?

The . class selector can also be used to select multiple classes. Note: Seperate each class with a comma. Note: Do not start a class attribute with a number.

How do you target multiple elements in jQuery?

To select multiple elements of an html page using multiple elements selector, we pass the element names inside parenthesis, in double quotes, separated by commas. For example: $(“div, p, h2”) this will select all the div, p and h2 elements of a page.


2 Answers

You can iterate through tr elements and check if have class alert. Then you can check the previous elements that has class dossier and add class alert to that element:

$("table tr").each(function() {
  if ($(this).hasClass("alert")) {
    $(this).prevAll("tr.dossier").first().addClass("alert");
  }

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <tr class="dossier">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail alert">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="dossier">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="even dossier">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail alert">
    <td>...</td>
    <td>...</td>
  </tr>
</table>
like image 198
Alex Char Avatar answered Nov 02 '22 19:11

Alex Char


The below explanation is in the context of my example code at the end of my answer.

First of all since you have multiple tr.alert's you will need to use .each() as you are wanting to add your class to the closest tr.dossier to each tr.alert but leaving the middle tr.dossier unchanged.

Using $("tr.alert").prev("tr.dossier") will only return the immediately preceding element and only then if that element is a tr with the class dossier. If you want an element that is further back through the DOM you will need to use $("tr.alert").prevAll("tr.dossier").

However simply using $("tr.alert").prevAll("tr.dossier") will return all previous tr's with the class dossier for each tr.alert and then combine them into one collection. In the case of your DOM jQuery will return the first tr.dossier for your first tr.alert and all three for the last one. Those four results will then be reduced to the three actual items available in the DOM.

From there you can use .first() or .last() to select an individual item but it will only select the tr.dossier preceding either your first or last tr.alert and won't be applied to both (as it appears you require). Using .each() will allow you to deal with each tr.alert individually and find it's nearest tr.dossier.

In this example the rows with the class dossier have a green background and those with alert have their font size set to 50px.

$("tr.alert").each(function(index, me) {
  $(me).prevAll("tr.dossier").first().addClass("alert");
});
tr.alert {
  font-size: 50px;
}
tr.dossier {
  background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <tr class="dossier">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail alert">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="dossier">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="even dossier">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail alert">
    <td>...</td>
    <td>...</td>
  </tr>
</table>
like image 26
John C Avatar answered Nov 02 '22 17:11

John C