total in repeater footer, itemdatabound in VB.NET - asp.net

I want to sum the total of the gender at the repeater footer using vb.net by using item data bound, the behind code is wrong cause I don't know how to do it...
FRONT CODE
<asp:Repeater ID="repGender" runat="server">
<HeaderTemplate>
<table cellspacing="0" rules="all" border="1">
<tr>
<th>Gender</th>
<th>Total</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<%# Eval("GENDER")%>
</td>
<td style="text-align: center">
<%# Eval("TOTAL")%></a>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
<tr style="font-weight: bold">
<td>Grand Total</td>
<td style="text-align: center">
<asp:Label runat="server" ID="lblTotal"></asp:Label>
</td>
</tr>
</table>
</FooterTemplate>
</asp:Repeater>
BEHIND CODE
Protected Sub repGender_ItemDataBound(sender As Object, e As RepeaterItemEventArgs) Handles repGender.ItemDataBound
If e.Item.ItemType = ListItemType.Item OrElse e.Item.ItemType = ListItemType.AlternatingItem Then
Total += Convert.ToInt32(DataBinder.Eval(e.Item.DataItem, ""))
Else e.Item.ItemType == ListItemType.Footer
End If
End Sub

Ok, so we need to define a simple total var at the form's "class" level. it only needs to persist during the data bind operation.
So, given your above markup, then we have this code to load the repeater.
Dim MyTotal As Integer
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadData
End If
End Sub
Sub LoadData()
Dim strSQL As String =
"SELECT Gender, count(*) as TOTAL
FROM Employee
GROUP BY Gender"
Dim rstData As New DataTable
Using mycon As New SqlConnection(GetConstr)
Using cmdSQL As New SqlCommand(strSQL, mycon)
mycon.Open()
rstData.Load(cmdSQL.ExecuteReader)
End Using
End Using
MyTotal = 0
repGender.DataSource = rstData
repGender.DataBind()
End Sub
And with your markup we see/get this:
And our data row bind event looks like this:
Protected Sub repGender_ItemDataBound(sender As Object, e As RepeaterItemEventArgs) Handles repGender.ItemDataBound
If e.Item.ItemType = ListItemType.Item Or
e.Item.ItemType = ListItemType.AlternatingItem Then
' We don't have lable or text box with an "id" in repeat
' section, (can't use find control unless you assign "id" to these controls).
' so, lets grab the whole data row used for binding
Dim gData As DataRowView = e.Item.DataItem
MyTotal = MyTotal + gData.Item("TOTAL")
End If
If e.Item.ItemType = ListItemType.Footer Then
' set the total value in footer
Dim lblTotal As Label = e.Item.FindControl("lblTotal")
lblTotal.Text = MyTotal
End If
End Sub

Related

Search button, to search in Repeater

I want to create a search button, so that I can search based on what I want to search in repeater table. I do not know how to it, cause I already try repGender.Rebind(), but still wrong... I do not know how to the behind code, as I know that we need:
Protected Sub BtnSearch_Click(sender As Object, e As EventArgs) Handles BtnSearch.Click
This is the UI, the table is in repeater
FRONT CODE
<label for="name">Jantina</label>
<asp:DropDownList ID="ddlGender" runat="server"></asp:DropDownList>
<asp:Button ID="BtnSearch" runat="server" Text="Search" />
<br/><br/>
<asp:Repeater ID="repGender" runat="server">
<HeaderTemplate>
<table cellspacing="0" rules="all" border="1">
<tr>
<th>Gender</th>
<th>Total</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<%# Eval("GENDER")%>
</td>
<td style="text-align: center">
<%# Eval("TOTAL")%></a>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
<tr style="font-weight: bold">
<td>Grand Total</td>
<td style="text-align: center">
<asp:Label runat="server" ID="lblTotal"></asp:Label>
</td>
</tr>
</table>
</FooterTemplate>
</asp:Repeater>
BEHIND CODE
Partial Class Statistics
Inherits App.Main
Dim MyTotal As Integer
Private Property Label As Object
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
If Not IsPostBack Then
BindData()
ddlGender_Bind()
End If
End Sub
Sub BindData()
Dim dal As New DBWrapper.DAL(strConnectionString, strProviderName)
Dim dt As New DataTable
dal.DB.Parameters.Clear()
dal.DB.AddParameter("#GENDER", ddlGender.Text)
If dal.DB.ExecuteProcedure(dt, "GENDER_BB") Then
repGender.DataSource = dt
repGender.DataBind()
End If
End Sub
Protected Sub repGender_ItemDataBound(sender As Object, e As RepeaterItemEventArgs) Handles repGender.ItemDataBound
If e.Item.ItemType = ListItemType.Item OrElse e.Item.ItemType = ListItemType.AlternatingItem Then
Dim gData As DataRowView = e.Item.DataItem
MyTotal = MyTotal + gData.Item("TOTAL")
End If
If e.Item.ItemType = ListItemType.Footer Then
' set the total value in footer
Dim lblTotal As Label = e.Item.FindControl("lblTotal")
lblTotal.Text = MyTotal
End If
End Sub
Public Sub ddlGender_Bind()
Dim dal As New DBWrapper.DAL(strConnectionString, strProviderName)
Dim dt As New DataTable
If dal.DB.ExecuteProcedure(dt, "GENDER_R") Then
Share.LoadList(ddlGender, "GENDER", "GENDER_ID", dt, Enums.MsgCode.PleaseSelect.ToString, ListOrder.ByValue)
End If
End Sub
Protected Sub BtnSearch_Click(sender As Object, e As EventArgs) Handles BtnSearch.Click
End Sub
End Class
Here I share the answer for people to refer...
Protected Sub BtnSearch_Click(sender As Object, e As EventArgs) Handles BtnSearch.Click
Dim dal As New DBWrapper.DAL(strConnectionString, strProviderName)
Dim dt As New DataTable
dal.DB.Parameters.Clear()
dal.DB.AddParameter("#GENDER", ddlGender.SelectedValue)
If dal.DB.ExecuteProcedure(dt, "GENDER_B") Then
repGender.DataSource = dt
repGender.DataBind()
End If
End Sub
At Stored Procedure GENDER_B
ALTER PROCEDURE [dbo].[GENDER_B]
#GENDER as INT
AS
BEGIN
declare #sql as varchar(max)
set #sql='SELECT b.GENDER, COUNT(b.GENDER) AS TOTAL FROM USERS a
JOIN GENDER b ON b.GENDER_ID = a.GENDER
WHERE IS_DELETED = 0
GROUP BY b.GENDER'
if #GENDER<>''
begin
set #sql = #sql + 'and a.GENDER=''' + #GENDER + ''' '
end
--select #sql
exec(#sql)
END

how to add onclick event to a programmatically created link button in vb.net

I want to display the products which i get them from my DB using dataset in a table dynamically because of the number of products in each store is vary , and when the user click on a product from the table i will display the clicked product details on the screen .
the problem is that i have added a link button programmatically in each cell of the table but the click event handler not working .
Please how can i add a link button , and click event handler dynamically? and how can i get the id of the clicked button inside the event handler method(ShowProductDetails)?
this is my code
products.aspx
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<table style=" width: 700px;" align="center">
<tr style="width:100%;">
<td align="center" width="50%" >Stores </td>
<td align="right" width="50%" >
<asp:DropDownList ID="StoresDDL" runat="server" AutoPostBack="True" Width="120px">
</asp:DropDownList>
</td>
</tr>
<tr>
<td >
<asp:table id="ProductsTBL" runat ="server" style="width: 700px;"
align="center" BorderStyle="Groove" BorderWidth="3px">
</asp:table>
</td>
</tr>
<tr>
<td>
<asp:Panel runat ="server" id="ProductDetails_Panel" visible ="false">
<asp:Label ID="selectedProduct" runat ="server" Visible="false" ></asp:Label>
</asp:Panel>
</td>
</tr>
</table>
</asp:Content>
Products.aspx.vb
Imports System.Data
Partial Class Admin_ViewProducts
Inherits System.Web.UI.Page
Dim con As New Conection
Dim ds_Products As New DataSet
Dim dr_Products As DataRow
Dim ds_Stores As New DataSet
Dim dr_Stores As DataRow
Dim sB As New LinkButton()
Protected Sub StoresDDL__Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles StoresDDL.Init
StoresDDL.Items.Clear()
StoresDDL.Items.Add("Select a store")
StoresDDL.DataValueField = 0
Try
ds_Stores = con.get_data("select storeid , storeName from Store ")
End If
Dim x As Integer = 1
For Each Me.dr_stores In ds_stores.Tables(0).Rows
If (dr_stores.IsNull(0) = False) Then
StoresDDL.Items.Add(dr_stores.Item(1))
StoresDDL.Items(x).Value = dr_stores.Item(0)
x = x + 1
End If
Next
Catch ex As Exception
End Try
End Sub
Protected Sub StoresDDL_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles StoresDDL.SelectedIndexChanged
ds_products = con.get_data("select productid ,productName from Product where storeid=" & StoresDDL.SelectedValue ")
Dim y As Integer = 1
Dim NOClmns As Integer = 3
Dim NOCells As Integer = ds_products.Tables(0).Rows.Count
Dim NORows As Integer = Math.Round(NOCells / 3, MidpointRounding.AwayFromZero)
' Current row count
Dim rowCtr As Integer
' Current cell counter.
Dim cellCnt As Integer
Dim productCount As Integer = 0
While productCount <> ds_products.Tables(0).Rows.Count
For rowCtr = 1 To NORows
Dim tRow As New TableRow()
For cellCount = 1 To 4 'For NOCells = 1 To cellCnt
Dim tCell As New TableCell()
'Dim s As New HyperLink()
sB = New LinkButton()
sB.ID = ds_products.Tables(0).Rows(productCount).Item("productName").ToString
sB.Text = ds_products.Tables(0).Rows(productCount).Item("productName").ToString
AddHandler sB.Click, AddressOf Me.ShowProductDetails
tCell.Controls.Add(sB)
tRow.Cells.Add(tCell)
productCount += 1
Next cellCount 'NOCells
' Add new row to table.
ProductsTBL.Rows.Add(tRow)
Next rowCtr
End While
End Sub
Protected Sub ShowProductDetails(ByVal sender As System.Object, ByVal e As System.EventArgs)
ProductDetails_Panel.Visible = True
selectedProduct.Visible = True
selectedProduct.Text = "test"
End Sub
End Class
In order to make this work, you will want to use the Command Event for the link button and pass a CommandArgument, the product ID.
So:
sb.CommandArgument = ds_products.Tables(0).Rows(productCount).Item("productID")
sb.CommandName = "clicked"
sb.OnCommand="LinkButton_Command"
Then, add an event to the code behind:
Sub LinkButton_Command(sender As Object, e As CommandEventArgs)
If e.CommandName = "clicked" Then
Process Request
End IF
End Sub
But, if it were me, I would bind to a DataGrid or Repeater, rather than create my own table...

how to make a label in a nested repeater visible programmatically

I have two repeaters, one nested in the other. I'm outputting a list of course titles in the parent repeater and the dates of those courses in the child repeater. This part is working fine. But, not all the course titles necessarily have dates available at any given time, so I want to be able to put a message up under each Course title that currently has no dates saying to check back regularly, blah, blah, blah. I've put the label in the footer template of the nested repeater with visibility=false and am trying to set the visibility=true at the appropriate time in the ItemDataBound Sub. Unfortunately, this is not working. I'm not getting any errors, the label just isn't showing up. I'm really hoping someone can help me out with my code or suggest an alternate way to do this. I'm kinda new to asp.net(VB) and am still struggling a bit. I've never tried nesting repeaters before. Here is my code:
.aspx
<asp:Repeater ID="rptTech" runat="server" >
<HeaderTemplate>
<table class="tableCourses">
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<strong><asp:Label runat="server" ID="lblCourseName" Text='<%# Eval("CourseName") %>'></asp:Label></strong>
<br />
<asp:Label runat="server" ID="lblCourseSummary" Text='<%# Eval("Summary") %>'></asp:Label>
<br />
<asp:HyperLink ID="hpCourseMaterial" Visible='<%# CheckCourseMaterial(Eval("CourseMaterial")) %>' NavigateUrl='<%# "/files/Portal_Course_Material/" & Eval("CourseMaterial")%>' Text="Download Course Material" runat="server"></asp:HyperLink>
</td>
</tr>
<tr>
<td>
<asp:Repeater ID="rptTechDates" DataSource='<%#Eval("relCourses") %>' runat="server" >
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<strong><asp:Label runat="server" ID="lblDate" Text='<%# CDate(Eval("dteDate")).ToString("dd/MM/yyyy") %>'></asp:Label></strong><br />
<asp:Label runat="server" ID="dteTime" Text='<%# "Time: " & CDate(Eval("dteTime2")).ToString("HH:mm") & " EST" %>'></asp:Label><br />
<asp:HyperLink ID="Register" NavigateUrl='<%# "/Test.aspx?intMeetingID2=" & Eval("pkWebinarID")%>' Text="Register" runat="server"></asp:HyperLink>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
<tr>
<td>
<asp:Label ID="lblNoCourses" Text="There are no course dates available at this time. Please check back regularly to see any updates." runat="server" Visible="False"></asp:Label>
</td>
</tr>
</table>
</FooterTemplate>
</asp:Repeater>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
And Codebehind:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim curDate As Date = CDate(Now)
'Create the connection
Dim connstring As String
connstring = ConfigurationManager.ConnectionStrings("LPISQLConn").ConnectionString
Using conn As New SqlConnection(connstring)
Dim cmd As New SqlCommand("SELECT foo1, foo2, foo3 FROM tblFoo", conn)
cmd.CommandType = CommandType.Text
Dim ad As New SqlDataAdapter(cmd)
Dim ds As New DataSet()
ad.Fill(ds)
ds.Relations.Add(New DataRelation("relCourses", ds.Tables(0).Columns("fkcrsID"), ds.Tables(1).Columns("webinarID"), False))
rptTech.DataSource = ds.Tables(0)
rptTech.DataBind()
End Using
End Sub
Protected Sub rptTech_ItemDataBound(ByVal sender As Object, ByVal e As RepeaterItemEventArgs)
If e.Item.ItemType = ListItemType.Item OrElse e.Item.ItemType = ListItemType.AlternatingItem Then
Dim drv As DataRowView = TryCast(e.Item.DataItem, DataRowView)
Dim rptTechDates As Repeater = TryCast(e.Item.FindControl("rptTechDates"), Repeater)
rptTechDates.DataSource = drv.CreateChildView("relCourses")
If rptTechDates.Items.Count < 1 And rptTechDates IsNot Nothing Then
If e.Item.ItemType = ListItemType.Footer Then
Dim lblNoCourses As Label = TryCast(e.Item.FindControl("lblNoCourses"), Label)
If lblNoCourses IsNot Nothing Then
lblNoCourses.Visible = True
End If
End If
Else
rptTechDates.DataBind()
End If
End If
End Sub
I would do the following:
Change your ItemDataBoundEvent for the parent repeater to:
Protected Sub rptTech_ItemDataBound(ByVal sender As Object, ByVal e As RepeaterItemEventArgs)
If e.Item.ItemType = ListItemType.Item OrElse e.Item.ItemType = ListItemType.AlternatingItem Then
Dim drv As DataRowView = TryCast(e.Item.DataItem, DataRowView)
Dim rptTechDates As Repeater = TryCast(e.Item.FindControl("rptTechDates"), Repeater)
rptTechDates.DataSource = drv.CreateChildView("relCourses")
rptTechDates.DataBind()
End If
End Sub
Add this to the markup of your child repeater:
OnItemDataBound="rptTechDates_ItemDataBound"
Now add this:
Protected Sub rptTechDates_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs)
If e.Item.ItemType = ListItemType.Footer Then
If DirectCast(DirectCast(e.Item.NamingContainer, Repeater).DataSource, DataTable).Rows.Count = 0 Then
DirectCast(e.Item.FindControl("lblNoCourses"), Label).Visible = True
End If
End If
So, if the number of rows in the child repeater's datasource is 0, then show the label.
EDIT After comment from OP
Protected Sub rptTechDates_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs)
If e.Item.ItemType = ListItemType.Footer Then
If DirectCast(DirectCast(e.Item.NamingContainer, Repeater).DataSource, DataView).Count = 0 Then
DirectCast(e.Item.FindControl("lblNoCourses"), Label).Visible = True
End If
End If
You want to search rptTechDates repeater for the lblNoCourses control. The e.Item.FindControl("lblNoCourses") is searching the rptTech repeater which doesn't exist. See this question to search the control in the rptTechDates footer.
Also, you'll want to call Databind() on the repeater after setting it's DataSource
rptTechDates.DataSource = drv.CreateChildView("relCourses")
rptTechDates.Databind()

Find a repeater that is within another repeater

Ok so my issue is I have three repeaters. Within that repeater I have another repeater and a third one in the second. There is more in between but that's not relevant. Below the HTML is my VB code. My issue is that rptCrashPercentageAvg reutrns Nothing. How can rptCrashStatsDisplay access rptCrashPercentageAvg?
<asp:Repeater ID="rptCrashStatsDisplay" runat="server">
<ItemTemplate>
<asp:Repeater ID="rptCrashPercentage" runat="server">
<ItemTemplate>
<tr class="statsRowA">
<td class="emphasis" style="padding-left: 20px">
<%# DataBinder.Eval(Container.DataItem,"CRASH_TYPE_DESC") %>:
</td>
<td style="padding-left: 5px">
<%--background-color: <%# Iif(DataBinder.Eval(Container.DataItem,"CRASH_TYPE_PERCENT")>DataBinder.Eval(Container.DataItem,"COUNT(*)"), "red", "null") %>"--%>
<%#String.Format("{0:N1}", DataBinder.Eval(Container.DataItem, "CRASH_TYPE_PERCENT"))%>
%
</td>
<asp:Repeater ID="rptCrashPercentageAvg" runat="server">
<ItemTemplate>
<td style="padding-left: 5px">
<%#String.Format("{0:N1}", DataBinder.Eval(Container.DataItem, "AVG_VAL"))%>
%
</td>
</ItemTemplate>
</asp:Repeater>
</tr>
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
Private Sub rptCrashStatsDisplay_ItemDataBound(ByVal sender As System.Object, _
ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles rptCrashStatsDisplay.ItemDataBound
Dim dv As DataRowView = CType(e.Item.DataItem, DataRowView)
If Not IsNothing(dv) Then
Dim rptCrashPercentage As Repeater = CType(e.Item.FindControl("rptCrashPercentage"), Repeater)
Dim view As DataView = dv.CreateChildView("statRel1")
If (view.Count > 0) Then
rptCrashPercentage.DataSource = view
rptCrashPercentage.DataBind()
End If
Dim rptCrashPercentageAvg As Repeater = CType(e.Item.FindControl("rptCrashPercentageAvg"), Repeater)
Dim viewAvg As DataView = dv.CreateChildView("statRel2")
If (viewAvg.Count > 0) Then
rptCrashPercentageAvg.DataSource = viewAvg
rptCrashPercentageAvg.DataBind()
End If
End If
End Sub
I would try making sure you're looking for it in the correct place. It'll look in your repeater's Header for the control and since it won't find it there, it'll be Nothing the first time you try and use it.
If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
Dim rptCrashPercentageAvg As Repeater = CType(e.Item.FindControl("rptCrashPercentageAvg"), Repeater)
'Shouldn't be "nothing" here.
End If
Otherwise you could try a more inefficient method:
Dim rptCrashPercentageAvg As Repeater = CType(e.Item.FindControl("rptCrashPercentageAvg"), Repeater)
If rptCrashPercentageAvg IsNot Nothing Then
Dim viewAvg As DataView = dv.CreateChildView("statRel2")
If (viewAvg.Count > 0) Then
rptCrashPercentageAvg.DataSource = viewAvg
rptCrashPercentageAvg.DataBind()
End If
End If
Edit: Also, since it actually is a repeater, you shouldn't need the CType.

Repeater control. Using a table that spans rows

The following "FindControl" method fails to find the imgAd control. Any idea why? Could it be the Table that contains it? The intent of the table is to line things up in columns across rows.
<asp:Content ID="Content3" ContentPlaceHolderID="phPageContent" runat="Server">
<asp:Repeater ID="repBanner" runat="server">
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:Image ID="imgAd" runat="server" AlternateText="Panda Visa" ImageUrl="Images/AffiliateBanners/125%20by%20125.jpg" />
</td>
<td>
<asp:TextBox ID="txtHtml" runat="server" Columns="80" ReadOnly="True" Rows="7" TextMode="MultiLine"></asp:TextBox>
</td>
<td>
<asp:Button runat="server" Text="Copy HTML to Clipboard" OnClientClick="ClipBoard('txtHtml')" />
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
Protected Sub repBanner_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles repBanner.ItemDataBound
Dim CurrentAd As Ad = CType(e.Item.DataItem, Ad)
Dim RepeaterItem As RepeaterItem = e.Item
Dim imgAd As Image = CType(RepeaterItem.FindControl("imgAd"), Image)
imgAd.ImageUrl = "Images/" & "125 by 125.jpg" '<<<Error occurs here
End Sub
Object reference not set to an instance of an object.
Here's some debug info that I thought may help:
? RepeaterItem.Controls.Count
1
? RepeaterItem.Controls(0).Controls.Count
0
? typename(RepeaterItem.Controls(0))
"LiteralControl"
You need to check e.Item.ItemType to make sure that you're dealing with an item, not a header or footer. Something like this:
Protected Sub repBanner_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles repBanner.ItemDataBound
If (e.Item.ItemType <> ListItemType.Item AndAlso e.Item.ItemType <> ListItemType.AlternatingItem) Then
Return
End If
Dim CurrentAd As Ad = CType(e.Item.DataItem, Ad)
Dim RepeaterItem As RepeaterItem = e.Item
Dim imgAd As Image = CType(RepeaterItem.FindControl("imgAd"), Image)
imgAd.ImageUrl = "Images/" & "125 by 125.jpg" '<<<Error occurs here
End Sub

Resources