JQuery toggle in table: click to affect element in row below

Situation →

Live code here

I know how to use the toggle function, but the situation is slightly tricky when we click on an element of one row, the toggle effect is needed one row below.

How can we handle such toggle functions?
That sky blue needs to be toggled.

Click Element: Row 1
Toggle Effect: Row 2

How you do it is to add an event handler to each shaded row

const shaded = document.querySelectorAll("tr.shaded");
shaded.forEach(function (row) {
    row.addEventListener("click", shadedClickHandler);
});

So that you can get the row that was clicked:

function shadedClickHandler(evt) {
    const row = evt.target;
    ...
}

and then use nextElementSibling to affect the row below it.

row.nextElementSibling.classList.toggle("hide");

With some CSS to hide things

.hide {
    display: none;
}

That’s how you do it with vanilla JavaScript.

I’m sure that someone else will come along to show how it’s easier to do with jQuery.

1 Like

Actually sir shaded is for styling. In fact shaded and non shaded all rows needs even handler, and row below that ill be showed or hidden.

I think in that case this should be:

The even row in tbody → tr is to be flipped.

What must happen when someone clicks on one of the “AWeber customer” rows?
:

  • Should nothing happen?
  • Should the “AWeber customer” row be hidden?
  • Should the row above be hidden?
  • Or, should the row below be hidden?

Sir, Initially all these light blue parts will be hidden →

I have put the class hidden in flip container when that particular heading here is clicked the flip, which is light blue color, row below will be visible (toggling effect).

sounds like you’re reinventing the accordion.

jQuery shorthands most of the code Paul has mentioned above.

$("tr.shaded").click((e) => {
   $(this).next().toggle();
});
1 Like

But I think we need some CSS class toggling as this solution alone is not working:

somehow we have to remove and delete .hidden class row just below it.

I tried this version, but the result was not that fruitful →

$(document).ready(function() {
   $("tr").click((e) => {
	$(this).next("tr").toggle();
  });
});

I think the event is not yet getting fired. or maybe I should remove this class:

.hidden {
	display: none;
}

I was also giving this a try →

$(document).ready(function() {
  $("tr").click((e) => {
		// $(this).next("tr").toggle();
		$(this).toggleClass('hidden').next('tr').slideToggle(100);
	});
});

that’s NOT the code I gave you. :stuck_out_tongue:

That will cause your blue rows to hide the next header row.

My apologies, I forgot the retargetting rules with jquery and arrow functions. It retargets $(this) to being the container.

$("tr.shaded").click(function (e) {
   $(this).next().toggle();
});

non shaded rows alsoneeds to be taken care sir.

In what way?

1 Like

shaded is just CSS polishing giving alternate color rows, but both these needs to have even triggering so that flip container can appear disappear:

tbody odd tr

needs to be taken care of

whole code here →

<body>
		<table>
			<thead>
				<tr class="header">
					<th></th>
					<th>First</th>
					<th>Second</th>
					<th>Third</th>
				</tr>
			</thead>
			<tbody>
				<tr class="shaded">
					<td><h3><a href="#">Heading Here</a></h3></td>
					<td>Column variable text</td>
					<td>Column variable text</td>
					<td>Column variable text</td>
				</tr>
				<tr class="flip hidden">
					<td colspan="4">AWeber customer EastVille Comedy Club had a problem. Through email, they wanted to draw people away from Netflix, YouTube, and the movies and into their Brooklyn club to see their top-notch list of comedians. </td>
				</tr>
				<tr>
					<td><h3><a href="#">Heading Here</a></h3></td>
					<td>Column variable text</td>
					<td>Column variable text</td>
					<td>Column variable text</td>
				</tr>
				<tr class="flip hidden">
					<td colspan="4">AWeber customer EastVille Comedy Club had a problem. Through email, they wanted to draw people away from Netflix, YouTube, and the movies and into their Brooklyn club to see their top-notch list of comedians. </td>
				</tr>
				<tr class="shaded">
					<td><h3><a href="#">Heading Here</a></h3></td>
					<td>Column variable text</td>
					<td>Column variable text</td>
					<td>Column variable text</td>
				</tr>
				<tr class="flip hidden">
					<td colspan="4">AWeber customer EastVille Comedy Club had a problem. Through email, they wanted to draw people away from Netflix, YouTube, and the movies and into their Brooklyn club to see their top-notch list of comedians. </td>
				</tr>
				<tr>
					<td><h3><a href="#">Heading Here</a></h3></td>
					<td>Column variable text</td>
					<td>Column variable text</td>
					<td>Column variable text</td>
				</tr>
				<tr class="flip hidden">
					<td colspan="4">AWeber customer EastVille Comedy Club had a problem. Through email, they wanted to draw people away from Netflix, YouTube, and the movies and into their Brooklyn club to see their top-notch list of comedians. </td>
				</tr>
			</tbody>
		</table>

tbody tr:nth-child(odd)

So both the rows need to have a common class, dont they?

1 Like

Yes, I have put a common class: dude.

$(document).ready(function() {
      $("tr.dude").click(function (e) {
		   $(this).next().toggle();
			});
		});

It works.

1 Like

If we change the HTML :slight_smile:
From →

<tr class="dude ">
	<td><h3><a href="#">Heading Here</a></h3></td>
	<td>Column variable text</td>
	<td>Column variable text</td>
	<td>Column variable text</td>
</tr>
<tr class="flip hidden">
	<td colspan="4">AWeber customer EastVille Comedy Club had a problem. Through email, they wanted to draw people away from Netflix, YouTube, and the movies and into their Brooklyn club to see their top-notch list of comedians. </td>
</tr>

TO →

<tr >
	<td><h3 class="dude"><a href="#">Heading Here</a></h3></td>
	<td>Column variable text</td>
	<td>Column variable text</td>
	<td>Column variable text</td>
</tr>
<tr class="flip hidden">
	<td colspan="4">AWeber customer EastVille Comedy Club had a problem. Through email, they wanted to draw people away from Netflix, YouTube, and the movies and into their Brooklyn club to see their top-notch list of comedians. </td>
</tr>

JQuery to:

$(".dude").click(function (e) {
$(this).next(".flip").toggle();

But that doesn’t work actually.

correct, because the thing you’ve given the class ‘dude’ to no longer has a sibling with the class ‘flip’. In fact, it has no siblings.

You’d do better to strip the <a> tag out, use CSS to style the H3 like a link.

To retarget your javascript, you’ll need a new function - .parent(). Parent returns a reference to the element that contains the current element. See if you can figure out how to use it in this situation.
Hint: $(this) is pointing at your H3. So that’s your starting location.

1 Like

Hi, Please click the last row it works →


$(document).ready(function() {
  $(".dude").click(function (e) {
   $(this).parent().parent("tr").next(".flip").toggle();
	});
});

Can we make this more full proof →

$(this).parent().parent("tr").next(".flip").toggle();

write this in such a way that unless the tr is found →

.parent().parent().parent()..parent()................parent().parent("tr").

The above should keep repeating, and once it is found then the parent() should stop.

I suppose there may be times when that many chained together is necessary, but to me that screams there must be a better way. In fact, I’d wager that would be very much less fool-proof not more.

Why would there ever not be a <tr> found. IMHO, if you have invalid HTML you should fix that, not write hacky JavaScript to compensate.

Sir, here in this example it is of no sense, but I want to accomplish this for the sake of learning.
There might be situation where HTML may be coming from users in case I ended up developing a plugin in future so please guide me, if possible.

JQuery is a old and established library there must be certain method.

this worked like a charm → https://api.jquery.com/closest/

$(document).ready(function() {
   $(".dude").click(function (e) {
      $(this).closest("tr").next(".flip").toggle();
	});
});

#1

also when dude class is directly in tr: