How to get count of nested repeater items - c#

I've a repeater on my page. And it's containing a nested repeater on it's item.
It's structure is as below
<asp:Repeater ID="rptOuterRepeater" runat="server" >
<ItemTemplate>
<tr >
<td>
// Need some code logic here for counting
</td>
</tr>
<tr>
<td>
<asp:Repeater ID="rptInnerRepeater" unat="server">
<ItemTemplate>
<tr >
<td>
</td>
</tr>
</ItemTemplate>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
I need to count rptInnerRepeater 's item count in place of comments. Is this possible using Inline Code.

Since, you are binding your Repeater to a Datasource, Why cannot you manipulate your datasource to contain the Count of the SubItems Collection to which your inner repeater is bound?
You can do it this way:
<asp:Repeater ID="rptOuterRepeater" runat="server">
<ItemTemplate>
<table>
<tr>
<td>
<%# Eval("Count") %>
</td>
</tr>
<tr>
<td>
<asp:Repeater ID="rptInnerRepeater" runat="server"
DataSource='<%# Eval("Items") %>'>
<ItemTemplate>
<tr>
<td>
<%# Eval("Id") %>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</td>
</tr>
</table>
</ItemTemplate>
</asp:Repeater>
and your DataSource is :
var datasource = testList.Select(s =>
new
{
Count = s.Items.Count,
Items = s.Items,
Id = s.Id
}).ToList();
rptOuterRepeater.DataSource = datasource;
rptOuterRepeater.DataBind();
so why not modify your datasource collection to contain an extra field called Count?
on the client side, you will have to use very ugly javascript/jQuery code, which will be superbly specific to your need.

Best I could come with in terms of short coding, using a literal and a ItemDataBound event handler. Not really what I would call "inline", but I hope this will help anyway.
<script runat="server">
void innerRpItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.DataItem != null)
{
var lit = (Literal) ((Control) sender).Parent.FindControl("count");
lit.Text = string.IsNullOrWhiteSpace(lit.Text) ? "1" : (int.Parse(lit.Text) + 1).ToString();
}
}
</script>
<asp:Repeater ID="rptOuterRepeater" runat="server" >
<ItemTemplate>
<tr >
<td>
// Need some code logic here for counting
<asp:Literal runat="server" ID="count"/>
</td>
</tr>
<tr>
<td>
<asp:Repeater ID="rptInnerRepeater" runat="server" OnItemDataBound="innerRpItemDataBound" >
<ItemTemplate>
<tr >
<td>
</td>
</tr>
</ItemTemplate>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
---------------- previous non working solution
You may try to replace this line
// Need some code logic here for counting
with this one
<%#((Repeater)Container.FindControl("rptInnerRepeater")).Items.Count%>
Not tested, and not really sure it would work, but worth a try I would say :-)
Hope this will help

Related

How to hide table rows in a DataList if column data returns null from SQL Server

I need to hide table rows in a DataList if column data returns null from SQL Server (for each individual column). I have it working successfully but this method will be very tedious as I have about 100 rows in my table. Surely there is a simpler way.
Here is my C# code:
protected void DataList1_ItemDataBound1(object sender, DataListItemEventArgs e)
{
if ((String.IsNullOrEmpty(((Label)e.Item.FindControl("lblAccountStatus")).Text)))
{
HtmlTableRow row = (HtmlTableRow)e.Item.FindControl("rowAccountStatus");
row.Visible = false;
}
if ((String.IsNullOrEmpty(((Label)e.Item.FindControl("lblAccountName")).Text)))
{
HtmlTableRow row = (HtmlTableRow)e.Item.FindControl("rowAccountName");
row.Visible = false;
}
}
Here is my webform markup:
<asp:DataList ID="DataListAccount" runat="server" OnItemDataBound="DataList1_ItemDataBound1">
<ItemTemplate>
<tr>
<td style="width: 171px">Account Status:</td>
<td style="width: 220px">
<asp:Label ID="lblAccountStatus" runat="server" Text='<%# Eval("ACCOUNT_STATUS") %>'></asp:Label>
</td>
</tr>
<tr id="rowAccountName">
<td style="width: 171px">Account Status:</td>
<td style="width: 220px">
<asp:Label ID="lblAccountName" runat="server" Text='<%# Eval("ACCOUNT_NAME") %>'></asp:Label>
</td>
</tr>
</ItemTemplate>
</asp:DataList>
You can wrap the ItemTemplate contents with a PlaceHolder and use a Ternary Operator to set the visibility.
<asp:PlaceHolder ID="PlaceHolder1" runat="server" Visible='<%# !string.IsNullOrEmpty(Eval("ACCOUNT_STATUS").ToString()) ? true : false %>'>
<tr>
<td style="width: 171px">Account Status:</td>
<td style="width: 220px">
<asp:Label ID="lblAccountStatus" runat="server" Text='<%# Eval("ACCOUNT_STATUS") %>'></asp:Label>
</td>
</tr>
</asp:PlaceHolder>
But I would recommend you make sure you filter the source data of empty items. Something like
SELECT * FROM accounts WHERE account_status IS NOT NULL
just modify this code by adding multiple conditions
string value = Convert.ToString( row["MyColumn"]);
if (string.IsNullOrEmpty(value))

In Paged Listview CheckBox_CheckedChanged event not working

The Problem is when I check the checkbox it works great, but when I check the checkbox on next page. previous page check boxes gets unchecked.
Checked box Checked/Unchecked event fires CheckedChanged event. But when I check the checkbox in listview next page of listview it uncheck's the checkboxes of listview previous Page.
ListView.aspx Code
<table class=" example1 table table-bordered table-striped">
<thead>
<tr>
<th>Sr no.</th>
<th>Parent Category</th>
<th>Title</th>
<th>Description</th>
<th>Image</th>
<th>Show on Homepage</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<asp:ListView ID="ListCourse" runat="server" OnItemCommand="ListCourse_ItemCommand" DataKeyNames="CID">
<LayoutTemplate>
<tr id="ItemPlaceholder" runat="server">
</tr>
</LayoutTemplate>
<ItemTemplate>
<tr class="gradeA">
<td>
<asp:Label ID="lblSrno" runat="server" Text='<%# Container.DataItemIndex+1 %>'></asp:Label>
</td>
<td>
<asp:Label ID="lbl" runat="server" Text='<%# GetCourse(Convert.ToInt32( Eval("CatID"))) %>'></asp:Label>
</td>
<td>
<asp:Label ID="Lbltitle" runat="server" Text='<%# Eval("Title") %>'></asp:Label>
<asp:Label ID="lablc" runat="server" Visible="false" Text='<%# Eval("CID") %>'></asp:Label>
</td>
<td>
<asp:Label ID="lblDescrption" runat="server" Text='<%# (Eval("Description").ToString().Length <=200)?Eval("Description").ToString(): Eval("Description").ToString().Substring(0, 200) + "..."%>'></b></asp:Label>
</td>
<td>
<img class="img_show " src="/Gallery/<%# Eval("Image")%>">
</td>
<td>
<asp:CheckBox ID="CheckCourse" runat="server" Style="margin-left: 50px;" OnCheckedChanged="CheckCourse_CheckedChanged" AutoPostBack="true" />
</td>
<td>
<asp:LinkButton ID="LinkEdit" runat="server" PostBackUrl='<%# "Add_New_Course.aspx?ID="+ Eval("CID")%>'>Edit</asp:LinkButton>
</td>
<td>
<asp:LinkButton ID="LinkDelete" runat="server" CommandName="DeleteCourse" CommandArgument='<%# Eval("CID") %>' OnClientClick='return confirm("Do you want to delete record ??")'> Delete</asp:LinkButton>
</td>
</tr>
</ItemTemplate>
</asp:ListView>
</tbody>
</table>
Code Behind CheckedChanged
protected void CheckCourse_CheckedChanged(object sender, EventArgs e)
{
CheckBox checkhome = (CheckBox)sender;
ListViewItem item = (ListViewItem)checkhome.NamingContainer;
ListViewDataItem dataItem = (ListViewDataItem)item;
string code = ListCourse.DataKeys[dataItem.DisplayIndex].Value.ToString();
int CID = Convert.ToInt32(code);
Course_Master objnew = DB.Course_Master.Single(p => p.CID == CID);
bool IsHome = CheckOnHome(CID);
if (IsHome == true)
{
if (checkhome.Checked == false)
{
objnew.ShowOnHomePage = false;
}
}
else
{
if (checkhome.Checked == true)
{
objnew.ShowOnHomePage = true;
}
}
DB.SaveChanges();
}
It doesn't fire because when the postback fires the server doesn't know the previous state of the checkbox, so it doesn't know if it's changed or not.
Try to set the default value to false and it should work
<asp:CheckBox ID="CheckCourse" runat="server" Checked="false" Style="margin-left: 50px;" OnCheckedChanged="CheckCourse_CheckedChanged" AutoPostBack="true" />
You need to save ids somewhere of checked item from the list. As when you move to the page 2 of ListView it lost its previous state.
Store data in viewstate and load it from there. To read and to bind it, you would need to handle PagePropertiesChanging and ItemDataBound event handlers of ListView.
Here is a good explaination regarding Maintaining the state of checkboxes in ListView
Please give +1 if it helped. Cheers!
Thank you Guys for the help. I solved it using some simple procedure's by removing the check-boxes from the ListView and adding text instead of it regarding whether the checkbox is checked or not(Yes/No). As I thought it will the easiest way to solve my problem.

How to access aspx control in code behind?

NET. i am trying to access the div tag in code behind which is inside the SeparatorTemplate
Here is my aspx code
<div>
<asp:DataList ID="DataList1" runat="server">
<ItemStyle ForeColor="#4A3C8C" BackColor="#E7E7FF"></ItemStyle>
<HeaderTemplate>
<table width="900px">
<tr>
<td width="300px">
<b>Name</b>
</td>
<td width="300px">
<b>Account No</b>
</td>
<td width="300px">
<b>Company</b>
</td>
</tr>
</table>
</HeaderTemplate>
<ItemTemplate>
<table width="900px">
<tr>
<td align="left" width="300px">
<%# DataBinder.Eval(Container.DataItem, "Name")%>
</td>
<td align="left" width="300px">
<%# DataBinder.Eval(Container.DataItem, "AccountNo")%>
</td>
<td align="left" width="300px">
<%# DataBinder.Eval(Container.DataItem, "Company")%>
</td>
</tr>
</table>
</ItemTemplate>
<HeaderStyle Font-Bold="True" ForeColor="#F7F7F7" BackColor="#4A3C8C"></HeaderStyle>
<SeparatorTemplate>
<div id="divSeprator" runat="server">//This div tag i want to access in the code behind
<br />
</div>
</SeparatorTemplate>
</asp:DataList>
</div>
I have tried accessing the this.Controls and DataList1.Controls but both of those doesn't contain this div i know it is in the SepratorTemplate but i don't know how to access control from that template because there is nothing to find the controls.
protected void DataList1_ItemDataBound(object sender, DataListItemEventArgs e)
{
// Find the div control as htmlgenericcontrol type, if found apply style
System.Web.UI.HtmlControls.HtmlGenericControl div = (System.Web.UI.HtmlControls.HtmlGenericControl)e.Item.FindControl("DivContent");
if(div != null)
div.Style.Add("border-color", "Red");
}
You will need to find it from the datalist row as below.
HtmlGenericControl div = (HtmlGenericControl)yourDataList.Items[0].FindControl("dvSeparator");
You can pass the index of the data list item (row) in .Items[] for which you want to find the div for processing.
If you want to process div from all the datalist items then you can do it in the item data bound event of the datalist as #Upvote MarkAnswer has suggested in his answer.
HtmlGenericControl divSeprator = (HtmlGenericControl)DataList1.Items[0].FindControl("divSeprator");
Where 0 is your item index.
Or just bind a DataList1_ItemDataBoud event and use:
if(e.Item.ItemType == ListItemType.Separator)
HtmlGenericControl divSeprator = (HtmlGenericControl)e.Item.FindControl("divSeprator");
you need to make tag runat="sever" and give it id
<div id="div" runat="server">
Then you can access it by using
HtmlGenericControl div = HtmlGenericControl("div")

Repeater Control binding categories to details

I'm new to repeater controls and pretty unfamiliar with them. Can someone help get me on the right track. Im using c# asp.net. I need my repeater to populate a sidebar with category names. On category name click, a main content div will populate category item details.
Thank you
All i have so far is populating the table with a hardcoded pk
<div class="chartdisplay">
<div id="repeater">
<asp:Repeater ID="Repeater" runat="server">
<HeaderTemplate>
<table width="100%" style= "background-color:#cccccc; font-size: 16px">
<tr style="background-color:#00bfbf"> <th> Item #</th> <th> Item Description </th> <th>Pre Price</th> <th>Size</th> </tr>
</HeaderTemplate>
<ItemTemplate>
<tr> <td> <%#Eval("Item #") %></td>
<td> <%#Eval("Item Description") %></td>
<td> <%#Eval("Pre Price") %></td>
<td> <%#Eval("Size") %></td> </tr>
</ItemTemplate>
<AlternatingItemTemplate>
<tr style="background-color:#eeeeee">
<td> <%#Eval("Item #") %></td>
<td> <%#Eval("Item Description") %></td>
<td> <%#Eval("Pre Price") %></td>
<td> <%#Eval("Size") %></td
</tr>
</AlternatingItemTemplate>
<FooterTemplate> </Table> </FooterTemplate>
</asp:Repeater>
</div>
</div>
and side bar
<div class="productCategoriesLabel">
<asp:Repeater ID="rptrCategories" OnItemCommand="detailsCat" runat="server">
<ItemTemplate>
<tr><td><%#Eval("PromoGroup") %></td></tr>
</ItemTemplate>
</asp:Repeater>
</div>
This is how u can bind another Repeater on click.
<div class="productCategoriesLabel">
<asp:Repeater ID="rptrCategories" runat="server"
onitemcommand="rptrCategories_ItemCommand">
<ItemTemplate>
<tr>
<td>
<asp:LinkButton ID="lbtnGroup" CommandName="cmd" runat="server" Text='<%#Eval("PromoGroup") %>'></asp:LinkButton>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</div>
protected void rptrCategories_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "cmd")
{
string Group = ((LinkButton)rptrCategories.Items[e.Item.ItemIndex].FindControl("lbtnGroup")).Text;
// DataTable dt = GroupDeatils(Group);
detRepeter.DataSource = dt;
detRepeter.DataBind();
}
}

whole row selectable in a Repeater

I have the following: repeater with a couple rows. each row starts with linkbutton with which can i navigate to another page. what I now want to do is that I can click the whole row with the same clicking functionality of the linkbutton.
Here is my Repeater:
<table>
<tr>
<td>
<asp:Repeater ID="rptTasks" runat="server" onitemcommand="rptTasks_ItemCommand"
onitemdatabound="rptTasks_ItemDataBound" onitemcreated="rptTasks_ItemCreated">
<HeaderTemplate>
<table>
<tr>
<td colspan="8"></td>
<td colspan="2"> </td>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr style="cursor: pointer" onclick="Select(this);">
<td>
<asp:LinkButton ID="SelectRow" runat="server" CommandName="SelectRow" Text="Test" />
<asp:HyperLink ID="LnkTaskID1" runat="server" CommandName="SelectRow" Text='<%# Eval("TaskID") %>' Font-Underline="True" /></td>
<td><asp:Label ID="StatusLabel1" runat="server" Text='<%# LocalizeStatusBinding(Eval("Status", "{0}")) %>' /></td>
</tr>
</ItemTemplate>
<AlternatingItemTemplate>
<tr style="cursor: pointer" onclick="Select(this);">
<td>
<asp:LinkButton ID="SelectRow" runat="server" CommandName="SelectRow" Text="Test" />
<asp:HyperLink ID="LnkTaskID1" runat="server" CommandName="SelectRow" Text='<%# Eval("TaskID") %>' Font-Underline="True" /></td>
<td><asp:Label ID="StatusLabel1" runat="server" Text='<%# LocalizeStatusBinding(Eval("Status", "{0}")) %>' /></td>
</tr>
</table>
</AlternatingItemTemplate>
<FooterTemplate>
<tr>
<td colspan="5" align="left">
<asp:Label ID="lblCurrentPage"
runat="server"></asp:Label>
</td>
<td colspan="5" align="right">
<asp:HyperLink ID="lnkPrev" runat="server" Text="<< Prev"></asp:HyperLink>
<asp:HyperLink ID="lnkNext" runat="server" Text="Next>>"></asp:HyperLink>
</td>
</tr>
</table>
</FooterTemplate>
</asp:Repeater>
</td>
</tr>
</table>
I have also used javascript to get the selected row:
<script type="text/javascript" >
function Select(obj)
{
obj.className = 'selected';
var tbl = document.getElementById("table1")
var firstRow = tbl.getElementsByTagName("TR")[0];
var oldRow = tbl.rows[firstRow.getElementsByTagName("input")[0].value];
if (oldRow != null)
{
oldRow.className = '';
}
firstRow.getElementsByTagName("input")[0].value = obj.rowIndex;
}
</script>
<script type="text/C#" >
onclick="this.getElementsByTagName('input')[0].clicked=true;
</script>
When i give the second table tag an id="table1" i get jscript error, oldRow unknown
Does someone know a solution for this issue? for clarity: I want clicking on an row and then navigating just like if I click on the first linkbutton of each row.
In advance thanks.
$(function () {
SetNaigationToSearchList();
}
);
function SetNaigationToSearchList() {
$("tr td")
.css("cursor", "pointer")//set the pointer cursor for table row
.click(function () {
$row = $(this).parent();
var ID = $("td", $row).eq(0).text();//Get the 0 th col value of the cliked index...
alert('clicked');
}
});
}

Categories

Resources