I am trying to hide and show a tr row which sits beneath its parent tr, I can get the console.log to display the message on click but the hidden tr want toggle open.
.hiddenTR {
display: none;
}
.ShowHide {
cursor: pointer;
}
$(function () {
$(document).on('click', "#tblActionsByAudit", function (event) {
console.log("hello");
// find where the click originated from
var trigger = event.target;
// if it has a class of "ShowHide"
// THEN toggle the next row
if (trigger.className === 'ShowHide') {
// toggle away
$(trigger).closest('tr').next('.hiddenTR').toggle();
}
});
});
<tbody>
@foreach (var record in Model.ActionsByAudit)
{
<tr class="alignCenter ShowHide">
<td>
@record.Property
</td>
<td data-datatype="date">
@record.AuditDate.ToString("yyyy-MM-dd")
</td>
<td>
@record.Module
</td>
<td>
@if (record.ActionsCompleted == record.ActionsGenerated)
{
<span>@record.ActionsCompleted / @record.ActionsGenerated</span>
}
else
{
<span style="color:red">@record.ActionsCompleted / @record.ActionsGenerated</span>
}
</td>
<td>
@record.ActionsCompletedPercentage
</td>
</tr>
<tr class="alignCenter hiddenTR">
<td colspan="5">Hidden</td>
</tr>
}
</tbody>
Its definitly a jquery issue, but cant work it out
Well, letâs start with an somewhat unrelated, but notable point:
if youâre putting this event on the TABLEâŚ
if (trigger.className === 'ShowHide') {
Will never be true. trigger
points to the table.
And even if youâve classed the table as âShowHideâ,
$(trigger).closest('tr').next('.hiddenTR').toggle();
closest only spirals UP the DOM, not DOWN. It will never find the TR youâre hunting for.
Itâs impossible to bind an event to a table that can identify what row has been clicked on; you should be binding your event to the rows instead.
(As an aside, if you do bind the event to the row, .closest('tr')
is redundant, because trigger
is already the row.)
Right ok, Umm but I cant use an id on the tr as the id will duplicate and then I will have multiple the same idâs.
And yes I see with the closest issue, would you be able to help me with this m_hutley
So I slightly changed it to this below, and to test put the id event on the tr
$(document).on('click', "#tableRowShowHide", function (event) {
console.log("funny");
// find where the click originated from
var trigger = event.target;
// toggle the next showhide row
if (trigger.className === 'ShowHide') {
// toggle
$(trigger).next('.hiddenTR').toggle();
}
});
<tr class="alignCenter ShowHide" id="tableRowShowHide">
<td>
@record.Property
</td>
<td data-datatype="date">
@record.AuditDate.ToString("yyyy-MM-dd")
</td>
<td>
@record.Module
</td>
<td>
@if (record.ActionsCompleted == record.ActionsGenerated)
{
<span>@record.ActionsCompleted / @record.ActionsGenerated</span>
}
else
{
<span style="color:red">@record.ActionsCompleted / @record.ActionsGenerated</span>
}
</td>
<td>
@record.ActionsCompletedPercentage
</td>
</tr>
<tr class="alignCenter hiddenTR">
<td colspan="5">Hidden</td>
</tr>
Correct, you cant use an ID on the row. But you can use a class selector for your bind instead of an ID.
In fact, when you do use it, you will eliminate the need for the if check entirely.
$(document).on("click",".ShowHide", function....
Sorry but I donât think so.
The target property can be the element that registered for the event or a descendant of it.
source: https://api.jquery.com/event.target/
It also works in my testing without jQuery either.
@Paul_Wilkins: Fair, but wouldnt you think the extremely higher chance is that the event.target in that case would be a td
? or something inside the td
?
Much better to target correctly and use the correct verbage ($(this)
) .
Yes, the event target is highly likely to be that, which is why he attempts to get from there to the nearest tr element.
$(trigger).closest('tr').next('.hiddenTR').toggle();
I suppose. Itâs still sloppy, and the reason that $(this)
exists.
I find that the this
keyword ends up becoming confusing, resulting in too much tracing of the code to figure out in just which context the this
keyword is being used.
But I digress - sorry to have disturbed. I return you back to what was being done before.
Though Paulâs point brings up probably why the code is failing - event.trigger diving so deep that the if statement never returns true, because youâve actually clicked on a td or span that doesnt have the ShowHide class.
Thanks for helping guys, I have put it back to using the table id, and then returning the jquery as was, just not sure what to use now. Its currently like this:
$(document).on('click', "#tblActionsByAudit", function (event) {
console.log("funny");
// find where the click originated from
var trigger = event.target;
// toggle the next showhide row
if (trigger.className === 'ShowHide') {
// toggle
$(trigger).closest('tr').next('.hiddenTR').toggle();
}
});
<tr class="alignCenter ShowHide">
<td>
@record.Property
</td>
<td data-datatype="date">
@record.AuditDate.ToString("yyyy-MM-dd")
</td>
<td>
@record.Module
</td>
<td>
@if (record.ActionsCompleted == record.ActionsGenerated)
{
<span>@record.ActionsCompleted / @record.ActionsGenerated</span>
}
else
{
<span style="color:red">@record.ActionsCompleted / @record.ActionsGenerated</span>
}
</td>
<td>
@record.ActionsCompletedPercentage
</td>
</tr>
<tr class="alignCenter hiddenTR">
<td colspan="5">Hidden</td>
</tr>
Im stuck lol
Try this:
var trigger = event.target;
=>
var trigger = $(event.target).closest('tr');
Cheers m_hutley, still not opening up the hidden tr, am ok to use the table id too as the click function id as below
$(document).on('click', "#tblActionsByAudit", function (event) {
console.log("funny");
var trigger = $(event.target).closest('tr');
if (trigger.className === 'ShowHide') {
$(trigger).closest('tr').next('.hiddenTR').toggle();
}
});
k⌠next step in sorting out this insistence is probably the classname checkâŚ
if (trigger.className === 'ShowHide') {
=>
if (trigger.hasClass('ShowHide')) {
1 Like
for the record, the properly scoped version of this code is boiling the entire block down to:
$(".ShowHide").click(function() { $(this).next(".hiddenTR").toggle(); });
Be careful with that though, because it fails to work with other DOM elements that are added to the page.
#1: He doesnt indicate heâs dynamically creating elements.
#2: Heâs already got the block wrapped in a onload
#3 itâs still the correct code.
Jeezus Paul, I do something to you today?
Thanks guys,
I am following the discussion, and very happy it works.
Might be pushing it but is it possible to slide the hidden tr instead of show, if not no worries, very happy, thank you both