I have this table which contains Events, and on a click on its icon ( an arrow ) I create new rows (called child event ) which are then add under the current row. I want, on a click on the same icon to hide its child event, but only his. Right now, f I click on a new event ( a different row) , it will toggle every hidden row, even if they are not relevent to the current row …
simply I’m trying to force get some kind of UntilNext but I cant get that function to work, and with the simple loop I’m doing atm it skips the oneEvent but triggers EVERY child row and not the one I want.
$('.JSONArrow').on("click", function () {
var image = $(this);
var Row = image.closest("tr");
Row.toggleClass("Opened");
if (Row.hasClass("Opened")) {
image.attr("src", "/Images/downArrow.png")
if (!(Row.hasClass("alreadyOpen"))) {
var id = image.attr("id");
$.get("/Home/Child/" + id, function (data) {
Row.after(data);
Row.addClass("alreadyOpen");
});
}
} else {
image.attr("src", "/Images/rightArrow.png");
}
var tr = Row.nextAll('tr');
for (i = 0; i < tr.length; i++) {
var eventClass = $(tr[i]).attr('class');
if (eventClass == 'ChildEvent')
$(tr[i]).slideToggle()
else {
if (eventClass == 'oneEvent')
return;
}
}
});
must be something simple to make nextUntil to work only on child row but I havent manage it so far, according to jquery doc it should be simple like :
var tr = Row.nextUntil('tr',$(".oneEvent"));
for (i = 0; i < tr.length; i++) {
var eventClass = $(tr[i]).attr('class');
if (eventClass == 'ChildEvent'){
$(tr[i]).slideToggle()
}
}
but I cant make it work. Anyone could point out how to do it, or use another jquery function I dont know about that would select all(‘tr”) that are linked(childEvent) to my Row variable and not the others.
I’m not sure poeple will undestand more with the hthml if you dont know asp or mvc4, but here goes : EDIT ::
<div class="TableHolder">
<table id="mainTable">
<thead>
<tr class="header">
<th class="iconColumn">Child</th>
<th>Date </th>
.... other <th>
</th>
</tr>
</thead>
@Html.EditorFor(x => x.logs)
</table>
and thats the table row per say :
string dynamicClass = "";
if (Model.Parent == null )
{
dynamicClass = "oneEvent";
}
else
{
dynamicClass = "ChildEvent";
}
}
<tr class="@dynamicClass">
<td class="iconColumn">
@if (Model.Parent == null )
{
<img class="JSONArrow" id="@Model.EventID" src="~/Images/rightArrow.png"/>
}
</td>
<td>@Model.TimeUTC.ToString("dddd, dd MMMM yyyy")<br />@Model.TimeUTC.ToString("HH:mm:ss") </td>
.... other column
</tr>
I’ll try to simplify what I ment :
you have rows.(Event) when you click on a row(Event), new dynamic rows appears under it (called ChildEvent).
if you click a second time on a row(event), you hide the rows if they exists under him, but only if they are ChildEvent class.
my current code hides ALL the ChildEvent on the table, I want to hide only those under the (event) clicked.
if the user clicks back on a row(event), it will show the (ChildEvent) if they exists, but only the (childEvent) relevant to the row(event) clicked, and not the ChildEvent of the whole table.
childEvent can only be added under its relevant Event.
re-edit :
row.nextUntil(".oneEvent", ".ChildEvent").slidetoggle();
this is what i want, textually : toggle the tr who are under the one I clicked, if they have the ChildEvent class. test until you reach a tr who have the class “oneEvent”.
I just cant undestand what parameters go where.
rererereedit :
<table>
<tr class=oneEvent></tr>
<tr class=oneEvent></tr>
<tr class=oneEvent></tr>
<tr class=oneEvent></tr>
<tr class=oneEvent></tr>
<tr class=oneEvent></tr>
</table>
ON CLICK :
<table>
<tr class="oneEvent, Opened, alreadyOpened"></tr>
<tr class=ChildEvent display = true></tr>
<tr class=ChildEvent display = true></tr>
<tr class=ChildEvent display = true></tr>
<tr class=ChildEvent display = true></tr>
<tr class=ChildEvent display = true></tr>
<tr class=oneEvent></tr>
<tr class=oneEvent></tr>
<tr class=oneEvent></tr>
<tr class=oneEvent></tr>
<tr class=oneEvent></tr>
</table>
click on the same oneEvent
<table>
<tr class="oneEvent, alreadyOpened"></tr>
<tr class=ChildEvent display = false></tr>
<tr class=ChildEvent display = false></tr>
<tr class=ChildEvent display = false></tr>
<tr class=ChildEvent display = false></tr>
<tr class=ChildEvent display = false></tr>
<tr class=oneEvent></tr>
<tr class=oneEvent></tr>
<tr class=oneEvent></tr>
<tr class=oneEvent></tr>
<tr class=oneEvent></tr>
</table>
click on a new oneEvent :
<table>
<tr class="oneEvent, alreadyOpened"></tr>
<tr class=ChildEvent display = false></tr>
<tr class=ChildEvent display = false></tr>
<tr class=ChildEvent display = false></tr>
<tr class=ChildEvent display = false></tr>
<tr class=ChildEvent display = false></tr>
<tr class=oneEvent></tr>
<tr class=oneEvent></tr>
<tr class="oneEvent, Opened, alreadyOpened"></tr>
<tr class=ChildEvent display = true></tr>
<tr class=ChildEvent display = true></tr>
<tr class=ChildEvent display = true></tr>
<tr class=oneEvent></tr>
<tr class=oneEvent></tr>
</table>
click on another new oneEvent
<table>
<tr class="oneEvent, alreadyOpened"></tr>
<tr class=ChildEvent display = false></tr>
<tr class=ChildEvent display = false></tr>
<tr class=ChildEvent display = false></tr>
<tr class=ChildEvent display = false></tr>
<tr class=ChildEvent display = false></tr>
<tr class=oneEvent></tr>
<tr class="oneEvent, Opened, alreadyOpened"></tr>
<tr class=ChildEvent display = true></tr>
<tr class=ChildEvent display = true></tr>
<tr class="oneEvent, Opened, alreadyOpened"></tr>
<tr class=ChildEvent display = true></tr>
<tr class=ChildEvent display = true></tr>
<tr class=ChildEvent display = true></tr>
<tr class=oneEvent></tr>
<tr class=oneEvent></tr>
click back on an earlier one Event :
<table>
<tr class="oneEvent, alreadyOpened"></tr>
<tr class=ChildEvent display = false></tr>
<tr class=ChildEvent display = false></tr>
<tr class=ChildEvent display = false></tr>
<tr class=ChildEvent display = false></tr>
<tr class=ChildEvent display = false></tr>
<tr class=oneEvent></tr>
<tr class="oneEvent, Opened, alreadyOpened"></tr>
<tr class=ChildEvent display = true></tr>
<tr class=ChildEvent display = true></tr>
<tr class="oneEvent, alreadyOpened"></tr>
<tr class=ChildEvent display = false></tr>
<tr class=ChildEvent display = false></tr>
<tr class=ChildEvent display = false></tr>
<tr class=oneEvent></tr>
<tr class=oneEvent></tr>
click on the 1st OneEvent :
<table>
<tr class="oneEvent, Opened, alreadyOpened"></tr>
<tr class=ChildEvent display = true></tr>
<tr class=ChildEvent display = true></tr>
<tr class=ChildEvent display = true></tr>
<tr class=ChildEvent display = true></tr>
<tr class=ChildEvent display = true></tr>
<tr class=oneEvent></tr>
<tr class="oneEvent, Opened, alreadyOpened"></tr>
<tr class=ChildEvent display = true></tr>
<tr class=ChildEvent display = true></tr>
<tr class="oneEvent, alreadyOpened"></tr>
<tr class=ChildEvent display = false></tr>
<tr class=ChildEvent display = false></tr>
<tr class=ChildEvent display = false></tr>
<tr class=oneEvent></tr>
<tr class=oneEvent></tr>
Yeah. We have enough HTML to see what you’re asking for now! Here’s what I would suggest:
You also have to fix your HTML. You separate class names with a space, not with a comma when you put multiple class names in your HTML. See here for a working demo:
http://jsfiddle.net/jfriend00/ZkvgN/
Since you seem to be having performance problems, here’s a special purpose version of nextUntil that is 3x faster as measured in this jsperf: http://jsperf.com/nextuntilfast
You would use it by replacing this:
with this:
OK, here’s my third guess at what you want to hide all
.ChildEventobjects in the current row. Since the HTML you included has no.ChildEventobjects in it, this is again a guess:Since you haven’t included your HTML, it’s hard to know exactly how to solve this problem.
After reading your question about 20 times (since you aren’t around to answer the clarifying questions), here’s my best guess at what you’re asking. If what you want to do with the last block of code in your function is to slideUp any rows that are after where the click was up to and not including a row with
.oneEvent, then you can do that with this code:The
.oneEventindicates where to stop matching sibling elements. The.ChildEventis a filter that removes items from the result that don’t match that selector. This will give you all following rows up to (but not including) the row that is.oneEventthat are also.ChildEventand it will then slide them up. If they are already closed, it will leave them closed. If you really want a toggle, then you can use.slideToggle()like your original code did, but I was guessing that what you’re really after is collapsing of other rows.This would be a revised version of your code:
This was my original guess at what you needed help with…
The typical way that a click action is applied to the same region that the click occurred and not all regions in the document is with the following algorithm:
You use
.closest()to find the proper parent container. You use.find()to find objects matching a selector that are in this container.If you want to apply something to all items in the container, then you select a higher container selector (like perhaps the whole table). If you want to apply something to just this region, then you pick a container selector for the
.closest()call that goes up only to your immediate region. The.find()then identifies the targets in whatever region you have selected. In this way, you can target only child objects of whatever scope you want.For example, to apply an action to all items that match a selector in the same row as the click occurs, you would do this:
For more specific code, please add your HTML to your question. As you have it know, you’re asking us to try to figure out what your HTML must be by looking at your code. That’s not easy and sometimes not possible and certainly never leads to the best possible solution.