It's possible to use repeater inside the another repeater? How?
my problem is, the back-end can't see the repeater inside the repeater.
FRONT:
<div id="blogright">
<ul class="accordion">
<asp:Repeater ID="parentRep" runat="server">
<ItemTemplate>
<li class="2010">
<%# Eval("DYear") %><span><%# Eval("PCount") %></span>
<ul class="sub-menu">
<asp:Repeater ID="childRep" runat="server">
<ItemTemplate>
<li><em><%# Eval("DDay") %></em><%# Eval("DMonth") %><span><%# Eval("ICount") %></span></li>
</ItemTemplate>
</asp:Repeater>
</ul>
</li>
</ItemTemplate>
</asp:Repeater>
</ul>
</div>
BACK:
//This is for parentRep
daString = "SELECT datepart(YEAR,BLG_DATE) as DYear,COUNT(BLG_DATE) as PCount FROM [BLG] INNER JOIN [ACC] ON [BLG].ACC_ID=[ACC].ACC_ID WHERE [BLG].ACC_ID='"+userID+"' GROUP BY BLG_DATE";
SqlDataAdapter da2 = new SqlDataAdapter(daString, conn);
DataTable dt2 = new DataTable();
da2.Fill(dt2);
parentRep.DataSource = dt2;
parentRep.DataBind();
//This is for childRep
dt.Clear();
daString = "SELECT DATEPART(DAY,BLG_DATE) as DDay,datename(month,BLG_DATE) as DMonth,DATEPART(YEAR,BLG_DATE) as DYear FROM [BLG] INNER JOIN [ACC] ON [BLG].ACC_ID=[ACC].ACC_ID WHERE [BLG].ACC_ID='"+userID+"' and BLG_DATE like '%"+urlId+"%'";
SqlDataAdapter da3 = new SqlDataAdapter(daString, conn);
DataTable dt3 = new DataTable();
da2.Fill(dt3);
//can't see the childRep here.
Sorry for my English.
You can get a reference to the child Repeater and bind data to it in the ItemDataBound event this way:
protected void parentRep_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (args.Item.ItemType == ListItemType.Item || args.Item.ItemType == ListItemType.AlternatingItem)
{
Repeater childRepeater = (Repeater)e.Item.FindControl("childRep");
childRepeater.ItemDataBound += new RepeaterItemEventHandler(childRepeater_ItemDataBound);
childRepeater.ItemCommand += new RepeaterCommandEventHandler(childRepeater_ItemCommand);
childRepeater.DataSource = dt3; //dt3 is the DataTable from your code sample
childRepeater.DataBind();
}
}
Additionally, there are some very thorough answers in this thread: Repeater in Repeater
Related
I have a GridView which gets the data from a SQL Server database.
The GridView binds when the user select the date from an CalendarExtender, because the data is different one day to another, also the rows quantity.
E. G., in Saturdays the GridView is filled with 18 rows. In Tuesdays, with 58.
Concern:
What I need to do is to split the GridView in 2 parts (2 GridViews). E. G., In tuesdays, 29 rows each GridView, in saturdays, 9 rows each.
I have tried:
To bring the daily data into a GridView, called "GVTotal":
if (Weekday.Value == "Saturday")
{
GVTotal.DataSourceID = SaturdayData.ID;
GVTotal.DataBind();
}
To count the rows from GVTotal, and divide by 2.
int everything = GVTotal.Rows.Count;
int half = everything / 2;
What I want to do now, is to "Copy" the rows from 0 to half to GVPart1, and from half to everything to GVPart2, in the exactly same order than in GVTotal.
I have read that maybe using a DataTable will made this possible.
I am not pretty sure how to do that. Could someone help me please?
You could have a Repeater with two items, one for each GridView. In the example below, the Repeater is rendered as a table with a single row. Each GridView is in a cell of that row, with an empty cell between them.
<asp:Repeater ID="repeater1" runat="server" OnItemDataBound="repeater1_ItemDataBound">
<HeaderTemplate>
<table cellspacing="0" cellpadding="0">
<tr>
</HeaderTemplate>
<ItemTemplate>
<td>
<asp:GridView ID="gvHalf" runat="server" >
...
</asp:GridView>
</td>
</ItemTemplate>
<SeparatorTemplate>
<td style="width: 32px;" />
</SeparatorTemplate>
<FooterTemplate>
</tr>
</table>
</FooterTemplate>
</asp:Repeater>
In order to get the two data sources, you declare two DataTables in your class:
private DataTable dtTopHalf;
private DataTable dtBottomHalf;
In Page_Load, the two DataTables are populated by splitting the full DataTable in two parts, and the data source of the Repeater is set to two boolean values:
void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
using (SqlConnection conn = new SqlConnection("Data Source=(local); Integrated Security = True; Initial Catalog=TestMP"))
using (SqlCommand cmd = new SqlCommand("SELECT * FROM Clients ORDER BY ClientID ASC", conn))
{
cmd.CommandType = CommandType.Text;
SqlDataAdapter dataAdapter = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
dataAdapter.Fill(dt);
int halfCount = dt.Rows.Count / 2;
dtTopHalf = dt.AsEnumerable().Select(x => x).Take(halfCount).CopyToDataTable();
dtBottomHalf = dt.AsEnumerable().Select(x => x).Skip(halfCount).CopyToDataTable();
}
// Each value in the Repeater indicates if it is the top half or not
repeater1.DataSource = new List<bool>() { true, false };
repeater1.DataBind();
}
}
The specific data source can then be set for each GridView in the ItemDataBound event handler of the Repeater:
protected void repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
bool isTopHalf = (bool)e.Item.DataItem;
GridView gvHalf = e.Item.FindControl("gvHalf") as GridView;
gvHalf.DataSource = isTopHalf ? dtTopHalf : dtBottomHalf;
gvHalf.DataBind();
}
}
Note 1: The Repeater allows to share the same markup for both GridViews. If you prefer, you can declare two separate GridViews in the markup and apply the specific data source to each one in Page_Load.
Note 2: You need a reference to System.Data.DataSetExtensions in your project to use some of the LINQ methods mentioned above.
Thanks to ConnorsFan for the assistance. His answer is the right way to do what I wanted.
As I need to select the date before the data comes in, I wrote Connor's code into my date Textbox OnTextChanged event, into the if (Weekday.Value == "<day of the week>") statement.
This is the solution:
ASPX:
Updated: Only with one GridView, as reccomended:
<asp:Repeater ID="repeater1" runat="server" OnItemDataBound="repeater1_ItemDataBound">
<HeaderTemplate>
<table cellspacing="200px" cellpadding="0">
<tr style="vertical-align: top;">
</HeaderTemplate>
<ItemTemplate>
<td>
<asp:GridView ID="gvHalf" runat="server" BackColor="White" AutoGenerateColumns="False" HeaderStyle-CssClass="tituloshandoff" RowStyle-CssClass="contenidohandoffbatch">
<Columns>
<asp:BoundField HeaderText="IDBATCH" DataField="IDBatch" SortExpression="IDBatch" HeaderStyle-CssClass="TituloInvisible" ItemStyle-CssClass="TituloInvisible" />
<asp:BoundField HeaderText="BATCH" DataField="Nombre" SortExpression="Nombre" />
<asp:BoundField HeaderText="DEALER" DataField="DealerCodigo" SortExpression="DealerCodigo" />
<asp:BoundField HeaderText="CT TIME" DataField="CTStart" SortExpression="CTStart" />
<asp:BoundField HeaderText="STATUS" DataField="Estado" SortExpression="Estado" />
<asp:TemplateField HeaderText="CONTROL">
<ItemTemplate>
<asp:Button ID="Button1" CssClass="botongrid" runat="server" Text="Select" Width="100px" /></ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</td>
</ItemTemplate>
<SeparatorTemplate>
<td style="width: 100px;" />
</SeparatorTemplate>
<FooterTemplate>
</tr>
</table>
</FooterTemplate>
</asp:Repeater>
C#:
I will show only one day in example:
string LaConexion = #"<My Connection String>";
private DataTable dtTopHalf;
private DataTable dtBottomHalf;
protected void TextDate_TextChanged(object sender, EventArgs e)
{
if (diasemana.Value == "Monday")
{
using (SqlConnection conexion = new SqlConnection(LaConexion))
using (SqlCommand comando = new SqlCommand("SELECT [1Monday].IDBatch, Batch.Nombre, Dealer.DealerCodigo, Batch.CTStart, BatchDatos.Estado FROM [1Monday] INNER JOIN Batch ON [1Monday].IDBatch = Batch.IDBatch INNER JOIN Dealer ON Batch.IDDealer = Dealer.IDDealer LEFT OUTER JOIN BatchDatos ON [1Monday].ID = BatchDatos.ID ORDER BY Batch.CTStart", conexion))
{
comando.CommandType = CommandType.Text;
SqlDataAdapter dataAdapter = new SqlDataAdapter(comando);
DataTable dt = new DataTable();
dataAdapter.Fill(dt);
int halfCount = dt.Rows.Count / 2;
dtTopHalf = dt.AsEnumerable().Select(x => x).Take(halfCount).CopyToDataTable();
dtBottomHalf = dt.AsEnumerable().Select(x => x).Skip(halfCount).CopyToDataTable();
}
// Each value in the Repeater indicates if it is the top half or not
repeater1.DataSource = new List<bool>() { true, false };
repeater1.DataBind();
}
}
A Picture:
I have 2 dropdownlist on my web form and the second one is synchronised with the first one based upon what value has been chosen.
Everything works well between the 2 of them and am able to use the values from them to carry out my function.
However the first dropdownlist seems to have an effect on my repeater and paginations. Basically it keeps incrementing the pageddatesource and clears the repeater of any data ?
The SelectedIndexChanged is only meant to update the update.panel1 where the second dropdownlist is but then am not sure how it further increments the page numbers and removes data from repeater?
Here is the front end with the dropdownlists.
<section id="section-search">
<div class="fleft">
Start Date:
<asp:TextBox runat="server" ID="txtStartDate" CssClass="txt txt-sml"></asp:TextBox>
<ajaxToolkit:CalendarExtender ID="calStartDate" runat="server" PopupPosition="Right" Animated="true" TargetControlID="txtStartDate" />
End Date:
<asp:TextBox runat="server" ID="txtEndDate" CssClass="txt txt-sml"></asp:TextBox>
<ajaxToolkit:CalendarExtender runat="server" ID="calEndDate" PopupPosition="Right" Animated="true" TargetControlID="txtEndDate"></ajaxToolkit:CalendarExtender>
<hr />
Product Class:
<asp:DropDownList ID="drpProductClass" runat="server" Width="230px" OnSelectedIndexChanged="drpProductClass_SelectedIndexChanged" AutoPostBack="true" />
<hr />
<asp:UpdatePanel ID="updatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
Product:
<asp:DropDownList ID="drpProduct" runat="server" Width="230px" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
<div class="fright">
<asp:Button runat="server" ID="btnFilter" Text="Search" CssClass="submit" OnClick="btnFilter_Click"/>
</div>
</section>
<section id="section-title">
<h1>Order Search</h1><h2></h2>
</section>
<section class="info-strip tr">
<asp:Literal ID="litResults" runat="server"></asp:Literal>
</section>
<section class="track-table">
<asp:Literal runat="server" ID="litMessage" Visible="false" Text="<div class='wysiwyg'><p>You currently have no orders...</p></div>"></asp:Literal>
<asp:PlaceHolder runat="server" ID="phOrders">
<%--<table>
<thead>
</thead>
<tbody>--%>
<asp:Repeater ID="rprOrders" runat="server" OnItemCommand="rprOrders_ItemCommand" >
Here is my Code behind
protected void SetupControl()
{
if (this.StopProcessing)
{
// Do not process
}
else
{
if (CMSContext.ViewMode == ViewModeEnum.LiveSite)
{
if(!Page.IsPostBack)
{
PopulateProductClass();
PopulateProduct();
PopulateOrders();
}
}
}
}
protected void drpProductClass_SelectedIndexChanged(object sender, EventArgs e)
{
CustomTableItemProvider ctip = new CustomTableItemProvider();
UserInfo user = CooneenHelper.GetUserImpersonisationUser();
QueryDataParameters qdp = new QueryDataParameters();
qdp.Add("#UserID", user.UserID);
DataSet ds = gc.ExecuteQuery("CN_GetEmpIDByUID", qdp, QueryTypeEnum.StoredProcedure, true);
int emplID = Convert.ToInt32(ds.Tables[0].Rows[0]["UserEmployeeID"].ToString());
if (drpProductClass.SelectedValue.ToString() != "0")
{
QueryDataParameters qdp2 = new QueryDataParameters();
qdp2.Add("#WR_ClassID", Convert.ToInt32(drpProductClass.SelectedValue.ToString()));
qdp2.Add("#UserEmployeeID", emplID);
DataSet ds2 = gc.ExecuteQuery("CN_OrdersGetProductByClassID", qdp2, QueryTypeEnum.StoredProcedure, true);
drpProduct.ClearSelection();
drpProduct.DataSource = ds2.Tables[1];
drpProduct.DataTextField = "ProductName";
drpProduct.DataValueField = "SKUNumber";
drpProduct.DataBind();
drpProduct.Items.Insert(0, new ListItem("-- Select Product --", "0"));
updatePanel1.Update();
}
else
{
drpProduct.ClearSelection();
PopulateProduct();
}
}
private void PopulateOrders()
{
CustomerInfo ki = CustomerInfoProvider.GetCustomerInfoByUserID(CooneenHelper.GetUserImpersonisationID());
int nKustomerID = ki.CustomerID;
DataTable dts = new DataTable();
dts.Columns.Add("OrderDate", typeof(string));
dts.Columns.Add("OrderNumber", typeof(string));
dts.Columns.Add("OrderItemSKUName", typeof(string));
dts.Columns.Add("OrderItemSKUID", typeof(string));
dts.Columns.Add("OrderItemStatus", typeof(string));
dts.Columns.Add("OrderItemUnitCount", typeof(string));
QueryDataParameters qdp = new QueryDataParameters();
qdp.Add("#CustomerID", nKustomerID);
DataSet ds = gc.ExecuteQuery("CN_OrderList", qdp, QueryTypeEnum.StoredProcedure, true);
foreach (DataRow dr in ds.Tables[0].Rows)
{
DataRow drNew = dts.NewRow();
drNew["OrderDate"] = ValidationHelper.GetDateTime(dr["OrderDate"], DateTime.Now).ToShortDateString();
drNew["OrderNumber"] = dr["OrderNumber"].ToString();
drNew["OrderItemSKUName"] = dr["OrderItemSKUName"].ToString();
drNew["OrderItemSKUID"] = dr["OrderItemSKUID"].ToString();
drNew["OrderItemStatus"] = dr["OrderItemStatus"].ToString();
drNew["OrderItemUnitCount"] = dr["OrderItemUnitCount"].ToString();
dts.Rows.Add(drNew);
}
PagedDataSource pds = new PagedDataSource();
pds.DataSource = dts.DefaultView;
//DataView view = dts.DefaultView;
//allow paging, set page size, and current page
pds.AllowPaging = true;
pds.PageSize = PerPage;
pds.CurrentPageIndex = CurrentPage;
//show # of current page in label
if (pds.PageCount > 1) litResults.Text += " - Showing page " + (CurrentPage + 1).ToString() + " of " + pds.PageCount.ToString();
//disable prev/next buttons on the first/last pages
btnPrev.Enabled = !pds.IsFirstPage;
btnNext.Enabled = !pds.IsLastPage;
rprOrders.Visible = true;
rprOrders.DataSource = pds;
rprOrders.DataBind();
}
We had a similar problem and could never figure out the root cause of it, we chalked it up to a bug in WebForms. But we were able to get around the problem by setting ClientIDMode="AutoID" for the control or page, we ended up setting our entire site that way cause we found problems that it happened to solve. Let me know if this works for you too. Wish I could be of greater help.
I am working on a project in asp.net. I have used two nested repeaters to show status and comments on that status. The nested repeater is bound to a data source which has two tables. Now when I #Eval the value of column of second table it is showing a not contain property name error.
<ItemTemplate>
<div style="height:285px;">
<img src='ProfilePic/<%#Eval("ProfilePic")%>' width="100" height="100" alt="" />
<asp:LinkButton ID="lnkfrndname" OnClick="lnkfrndname_Click" CommandName="frndname" CommandArgument='<%#Eval("UserName") %>' runat="server"> <u><%#Eval("Firstname")%> <%#Eval("LastName")%></u></asp:LinkButton>
<br />
<%#Eval("StatusText")%>
<br />
<asp:HiddenField ID="hfstatusid" Value='<%# Eval("StatusId") %>' runat="<asp:Repeater ID="replike" runat="server">
< <asp:Literal ID="ltlstatuscomm" Text='<%#Eval("CommentText") %>' runat="server"></asp:Literal>
</ItemTemplate>
</ </ItemTemplate>
</asp:Repeater>
.cs
protected void rephomecontent_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if ((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType == ListItemType.AlternatingItem))
{
HiddenField hf = e.Item.FindControl("hfstatusid") as HiddenField;
if (hf != null)
{
Repeater rep = e.Item.FindControl("replike") as Repeater;
if (rep != null)
{
int statusid = int.Parse(hf.Value.ToString());
DataSet ds = new StatusLikeInfoAction().ViewStatusLike(statusid);
rep.DataSource = ds;
rep.DataBind();
}
}
}
}
It wound be good if you bind the repeater with Datatable instead of DataSet containing multiple table.
First Analyze whether you want to bind
ds.Tables[0]
Or
ds.Tables[1]
then bind the repeater as follows
rep.DataSource = ds.Tables[0];
Or
rep.DataSource = ds.Tables[1];
as per your choices
I have this code:
$(document).ready(function () {
$('#Priroda').hide();
$('#priroda_').click(function () {
$('#Znamenitosti').hide();
$('#Priroda').show();
});
$('#znamenitosti_').click(function () {
$('#Priroda').hide();
$('#Znamenitosti').show();
});
});
</script>
<div class="meni">
<nav>
<ul>
<li class="active">Info</li>
<li>Znamenitosti</li>
<li>Priroda</li>
<li>Noken Zivot</li>
</ul>
</nav>
</div>
where I have few categories in the menu. When i click on specific category, i want to show the (div) tag for that specific category within the same .aspx page, and the other (div) tags for the other categories should be hidden.
This is the (div) tag for the category "Priroda":
<div class="Priroda" id="Priroda">
<asp:DataList ID="DataList1" runat="server" RepeatColumns="7" CellPadding="3">
<ItemTemplate>
<div class="boxButton">
<ul class="Gallery">
<li><a id="A1" href='<%# Eval("ime","~/Sliki/Ohrid/Priroda/{0}") %>' title='<%# "Од "+ Eval("userid")+ ", на " + Eval("datum")+ ", " + Eval("opis")%>' rel="FaceBox[gallery1]" runat="server" >
<asp:Image ID="Image1" ImageUrl='<%# Bind("ime", "~/Sliki/Ohrid/Priroda/{0}") %>' runat="server" Width="140" Height="140" AlternateText='<%# Bind("imeslika") %>' />
</a></li></ul></div>
</ItemTemplate>
</asp:DataList>
</div>
For binding the DataList i used this code in .cs file:
protected void BindDataList1()
{
String strConnString = System.Configuration.ConfigurationManager
.ConnectionStrings["makbazaConnectionString"].ConnectionString;
SqlConnection con = new SqlConnection(strConnString);
con.Open();
//Query to get ImagesName and Description from database
SqlCommand command = new SqlCommand("SELECT ime, imeslika, kategorija, datum, opis, slikapateka, userid FROM Ohrid WHERE kategorija='Priroda'", con);
SqlDataAdapter da = new SqlDataAdapter(command);
DataTable dt = new DataTable();
da.Fill(dt);
dlImages.DataSource = dt;
dlImages.DataBind();
con.Close();
}
Now i don't know how to call BindDataList1(); to show me data when i click on that category. I have different BindDataLists for each category. Can you tell me how to call specific BindDataList for the category that is selected from the menu? For example when i click on link Priroda show me the (div) tag Priroda and BindDalaList1();, when i click on link Znamenitosti show me the (div) tag Znamenitosti and BindDalaList2();
I think a simple way to do this would be to run your databind functions for all categories at once, for example in the PreRender event of "DataList1", so all of the data is on the page, and each bit is just hidden or shown through your jQuery.
Alternatively, could you use instead of tags, and have an OnClick property set to call your DataBind1 method.
<asp:Repeater ID="rp1" runat="server">
<ItemTemplate>
<ul>
<li>
<%#Module(Convert.ToInt32(Eval("id")),Eval("university").ToString()) %>
<asp:Repeater ID="rp2" runat="server">
<ItemTemplate>
<ol>
<li id="sublist" runat="server">
<%#Eval("college") %>
</li>
</ol>
</ItemTemplate>
</asp:Repeater>
</li>
</ul>
</ItemTemplate>
</asp:Repeater>
C# CODE
public string Module(int id,string university)
{
con = new SqlConnection(ConStr);
con.Open();
cmd = new SqlCommand("SELECT college FROM tbluniversity where id=" + id, con);
da = new SqlDataAdapter(cmd);
con.Close();
ds = new DataSet();
da.Fill(ds);
//Here I want to find the inner repeator of current row then bind this dataset to that.
how to find Repeator
return university;
}
you have to add a ItemCreated event and you can use e.Item.FindControl method to find your inner repeater using its id