I'm wondering if someone has a creative solution to my problem. I have a repeater that is populated from my database and it is as follows:
<asp:Repeater ID="ResultsTableRepeater" runat="server" OnPreRender="ResultsTableRepeater_PreRender">
<HeaderTemplate>
<table class="td-table-bordered" style="font-size: small; width: 90%">
<tr>
<th>Change #</th>
<th>Change Title</th>
<th>Change Description</th>
<th>Clarity Id</th>
<th>Package Description</th>
<th>Package Name</th>
<th>Package Status</th>
<th>Assigned To</th>
<th>New Package</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<asp:Literal runat="server" Text='<%# Eval("ChangeId") %>' ID="IdTag" Visible="false"></asp:Label>
<tr id="tableRow" class="" data-changeId='<%# Eval("ChangeId") %>' runat="server" style='<%#(Eval("AssignedTo").ToString() == "7" || Eval("AssignedTo").ToString() == "8")? "": "font-weight:bold; background-color:cornsilk" %>'>
<td><%# Eval("ChangeId") %></td>
<td><%# Eval("ChangeTitle") %></td>
<td><%# Eval("ChangeDescription") %></td>
<td><%# Eval("ClarityId") %></td>
<td><%# (Eval("PackageId").ToString() == string.Empty) ? ""
: "<a href=http://dev.rlaninfrastructure.tdbank.ca/RCIViewForm?ChangeId=" + Eval("ChangeId") + "&PackageId=" + Eval("PackageId") + " runat='server' id='RCILink'>" %>
<asp:Label ID="ExistingPackageLabel" runat="server" Text='<%# (Eval("PackageId").ToString() == string.Empty) ? "No packages" : Eval("PackageDescription").ToString() %>'>
</asp:Label><%# (Eval("PackageId").ToString() == string.Empty) ? "" : "</a>" %>
</td>
<td><%# Eval("PackageName") %></td>
<td>
<asp:Label ID="LabRequestedLabel" runat="server" Text='<%# (Eval("PackageStatus").ToString() == "1") ? "Requested"
: (Eval("PackageStatus").ToString() == "2") ? "Built"
: (Eval("PackageStatus").ToString() == "3") ? "NFT"
: (Eval("PackageStatus").ToString() == "4") ? "Pilot"
: (Eval("PackageStatus").ToString() == "5") ? "Production"
: (Eval("PackageStatus").ToString() == "6") ? "Completed"
: (Eval("PackageStatus").ToString() == "7") ? "Cancelled"
: (Eval("PackageStatus").ToString() == "8") ? "Pending"
: "" %>'></asp:Label>
</td>
<td><%# (Eval("EmployeeName").ToString() == string.Empty) ? "" : Eval("EmployeeName")%></td>
<td><%# "<a href=http://dev.rlaninfrastructure.tdbank.ca/RCIViewForm?ChangeId=" + Eval("ChangeId") + " runat='server' id='RCILink'>"%>
<asp:Label ID="NewPackageLabel" runat="server" Text="Create New">
</asp:Label><%#"</a>" %></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
and it produces a table that looks like this
What I've circled are rows with repeating Change Id's that I'd like to default to collapsed but can be clicked to be expanded (as well as clicked again to be collapsed again).
I've begun to implement Jon P's solution below, and I'm almost done! Just the Jquery onclick event.
Below is my codebehind PreRender method.
protected void ResultsTableRepeater_PreRender(object sender, EventArgs e) {
int previousId = 0;
int currentId = 0;
int nextId = 0;
for (int item = 0; item < ResultsTableRepeater.Items.Count; item++) {
Literal idTag = (Literal)ResultsTableRepeater.Items[item].FindControl("IdTag");
Literal classTag = (Literal)ResultsTableRepeater.Items[item].FindControl("ClassTag");
HtmlTableRow tableRow = (HtmlTableRow)ResultsTableRepeater.Items[item].FindControl("tableRow");
if (item != ResultsTableRepeater.Items.Count - 1)
int.TryParse(((Literal)ResultsTableRepeater.Items[item + 1].FindControl("IdTag")).Text.ToString(), out nextId);
if (int.TryParse(idTag.Text, out currentId)) {
if (currentId == previousId) {
tableRow.Attributes["class"] = "hidden";
}
else if (currentId != previousId && currentId == nextId) {
tableRow.Attributes["class"] = "toggler";
}
}
else
nextId = 0;
int.TryParse(idTag.Text, out previousId);
}
}
Update again: The only thing I have left to fix is the jquery, which expands and collapses the hidden/opened rows on the toggler lines. Below is the jquery and css as per Jon P's help.
$(".toggler").click(function(){
var idClicked = $(this).data("changeid");
//Toggle hidden on the sibling rows with the same data id
$(this).nextAll("[data-changeId='" + idClicked +"']").toggleClass("hidden");
//Toggle opened status on clicked row
$(this).toggleClass("opened");
});
.hidden{display:none;}
.toggler td:first-child::after{content:" +";}
.toggler.opened td:first-child::after{content:" -";}
Can someone help me out in this final stretch? I feel like I'm close.
Don't have time for a complete answer as there is a fair bit involved server side so I'll try and give you a broad picture.
You need to look at adding a class to your table row, maybe add asp:literal
to your tr
to hold the class. Also add an asp:literal
for your id, this will give you a control you can get the value from. Perhaps use that literal for a data attribute on the table row.
Then use an OnPreRender
event on your Repeater. Here iterate the items of the repeater. Compare the id you have stored in the literal I mentioned above with the id in the previous and next items. If the id is the same as the previous, add a css class you can use to hide it. If the id is differnt to the previous but the same as the next, add a css class to indicate that the row is used to hide and collapse.
Add some CSS to to hide the rows using the class added above.
You want to end up with HTML that resembles the following. I've also added the expand and collapse with jquery
$(document).ready(function() {
$(".toggler").click(function() {
var idClicked = $(this).data("changeid");
//Toggle hidden on the sibling rows with the same data id
$(this).nextAll("[data-changeId='" + idClicked + "']").toggleClass("hidden");
//Toggle opened status on clicked row
$(this).toggleClass("opened");
});
});
.hidden {
display: none;
}
.toggler td:first-child::after {
content: " +";
}
.toggler.opened td:first-child::after {
content: " -";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table class="td-table-bordered" style="font-size: small; width:90%">
<tr>
<th>Change #</th>
<th>Change Title</th>
<th>Change Description</th>
<th>Clarity Id</th>
<th>Package Description</th>
<th>Package Name</th>
<th>Package Status</th>
<th>Assigned To</th>
<th>New Package</th>
</tr>
<tr data-changeId="1">
<td>1</td>
<td>Change Title</td>
<td>Change Description</td>
<td>Clarity Id</td>
<td>Package Description</td>
<td>Package Name</td>
<td>Package Status</td>
<td>Assigned To</td>
<td>New Package</td>
</tr>
<tr class="toggler" data-changeId="2">
<td>2</td>
<td>Change Title</td>
<td>Change Description</td>
<td>Clarity Id</td>
<td>Package Description</td>
<td>Package Name</td>
<td>Package Status</td>
<td>Assigned To</td>
<td>New Package</td>
</tr>
<tr class="hidden" data-changeId="2">
<td>2</td>
<td>Change Title</td>
<td>Change Description</td>
<td>Clarity Id</td>
<td>Package Description</td>
<td>Package Name</td>
<td>Package Status</td>
<td>Assigned To</td>
<td>New Package</td>
</tr>
<tr class="hidden" data-changeId="2">
<td>2</td>
<td>Change Title</td>
<td>Change Description</td>
<td>Clarity Id</td>
<td>Package Description</td>
<td>Package Name</td>
<td>Package Status</td>
<td>Assigned To</td>
<td>New Package</td>
</tr>
<tr data-changeId="3">
<td>3</td>
<td>Change Title</td>
<td>Change Description</td>
<td>Clarity Id</td>
<td>Package Description</td>
<td>Package Name</td>
<td>Package Status</td>
<td>Assigned To</td>
<td>New Package</td>
</tr>
<tr class="toggler" data-changeId="4">
<td>4</td>
<td>Change Title</td>
<td>Change Description</td>
<td>Clarity Id</td>
<td>Package Description</td>
<td>Package Name</td>
<td>Package Status</td>
<td>Assigned To</td>
<td>New Package</td>
</tr>
<tr class="hidden" data-changeId="4">
<td>4</td>
<td>Change Title</td>
<td>Change Description</td>
<td>Clarity Id</td>
<td>Package Description</td>
<td>Package Name</td>
<td>Package Status</td>
<td>Assigned To</td>
<td>New Package</td>
</tr>
</table>
NOTE this could all be done client side, but you would have a brief moment when the table is fully expanded while javascript works out what to hide. That can be a jarring experience for your users.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With