How to Update Specific update panel and prevent other to be refreshed? - asp.net

i am trying to add time attendance at dashboard but i have other
update panels with filter tools such as month and year when tick event
of the timer occured the dropdown options collapsed and i can't choose
one of them. i need to update only TimerUpdatePanel not other update
panels the code :
<asp:UpdatePanel ID="TimerUpdatePanel" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="true">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
</Triggers>
<ContentTemplate>
<div class="row">
<div class="offset-2 col-md-4">
<div id="timer" class="bg-primary timer-div">
<div>
<h2 id="Timer_Time" runat="server">00:00:00</h2>
<h2 id="Timer_Day" runat="server">-------</h2>
<h2 id="Timer_Date" runat="server">00-00-0000</h2>
</div>
</div>
</div>
<asp:Timer ID="Timer1" runat="server" Interval="1000" OnTick="Timer1_Tick" />
</div>
<div class="hr-line-dashed"></div>
<div class="row">
<div class="col-md-4 offset-5" style="padding-top: 12px; letter-spacing: 2px;">
<span id="PunchMsg" runat="server"></span>
<br />
<span id="TimerOption" runat="server"></span>
</div>
<div class="col-md-3">
<h2 id="stopWatch" runat="server"><span></span><span id="Hours"
runat="server">00:00:00
<asp:Button ID="PunchIN" Text="Punch In" runat="server" Visible="true" CssClass="btn btn-primary"
OnClick="PunchIN_Click"></asp:Button>
<asp:Button ID="PunchOut" Text="Punch Out" runat="server" Visible="false" CssClass="btn btn-warning"
OnClick="PunchOut_Click"></asp:Button>
</asp:UpdatePanel>
Protected Sub Timer1_Tick(sender As Object, e As EventArgs)
Dim CurrentDay = DateTime.Now.ToString("dddd")
Dim CurrentDate = DateTime.Now.ToString("dd-MM-yyyy")
Dim CurrentTime = DateTime.Now.ToString("H:mm tt")
Timer_Day.InnerText = CurrentDay
Timer_Date.InnerText = CurrentDate
Timer_Time.InnerText = CurrentTime
If PunchIN.Visible = False AndAlso PunchOut.Visible = True Then
If Session("TimerStatement") <> "" Then
Dim h = Val(Hours.InnerText)
Dim m = Val(Minutes.InnerText)
Dim s = Val(Seconds.InnerText)
s += 1
If s = 60 Then
s = 0
m = m + 1
End If
If m = 60 Then
m = 0
h = h + 1
End If
Hours.InnerText = h.ToString("00")
Minutes.InnerText = m.ToString("00")
Seconds.InnerText = s.ToString("00")
Else
TimerOption.InnerText = "Please select one of the below options first"
End If
End If
TimerUpdatePanel.Update()
End Sub
[this image show filter tools that be collpsed every 1 second][1]
[1]: https://i.stack.imgur.com/QYBCW.jpg

Well, some panel that updates with a timer? It should not bother other bits and parts on the page.
but, DO keep in mind the following:
While a update panel does prevent a page re-fresh, it DOES DO A post-back, or better said what we call a PARTICAL post back.
that means on each timer click, the web page LOAD event WILL fire each time. So, just like clicking any button on the form, you do get a post-back, and page load event will trigger each time.
What this means?
Well, if you load up say a drop down list, or other controls say like some grid view?
You BETTER make sure that the page load event ONLY loads up that grid, or drop down ON THE REAL first page load - since page load always will trigger over and over.
So, say we drop in this div to the page - (your example - stripped down).
<asp:UpdatePanel ID="TimerUpdatePanel" runat="server"
UpdateMode="Conditional" ChildrenAsTriggers="true" >
<ContentTemplate>
<asp:Timer ID="Timer1" runat="server" Interval="1000" OnTick="Timer1_Tick"
Enabled="false" />
<div style="width:20%;padding:15px;border:solid">
<h2 id="Timer_Time" runat="server">00:00:00</h2>
<h2 id="Timer_Day" runat="server">-------</h2>
<h2 id="Timer_Date" runat="server">00-00-0000</h2>
<hr />
<span id="PunchMsg" runat="server"></span>
<span id="TimerOption" runat="server" > </span>
<h2 id="stopWatch" runat="server" >
<span id="Hours" runat="server" >00:00:00</span>
</h2>
<asp:Button ID="PunchIN" Text="Punch In" runat="server" Visible="true"
style="float:left"
CssClass="btn btn-primary" OnClick="PunchIN_Click" >
</asp:Button>
<asp:Button ID="PunchOut" Text="Punch Out" runat="server" Visible="false"
style="float:right"
CssClass="btn btn-warning" OnClick="PunchOut_Click">
</asp:Button>
<br />
<br />
</div>
</ContentTemplate>
</asp:UpdatePanel>
And for code behind? Well, just like a date? We don't have to +1 to month etc.. ALL we need is the staring time when you punch in. From that we can get the elapsted time. We don't even need a timer here, and we could say update every 5 seconds, 10 seconds - it just don't matter.
So, our code can look like this now:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
End Sub
Protected Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Call Update
End Sub
Sub Update()
Dim dtNow As DateTime = DateTime.Now
Timer_Day.InnerText = dtNow.ToString("dddd")
Timer_Date.InnerText = dtNow.ToString("dd-MM-yyyy")
Timer_Time.InnerText = dtNow.ToString("H:mm tt")
' now show elapsed time
Dim dtPunchIn As DateTime = Session("PunchIn")
Dim MyTimeSpan As TimeSpan = (dtNow - dtPunchIn)
Hours.InnerText = MyTimeSpan.ToString("hh\:mm\:ss")
End Sub
Protected Sub PunchIN_Click(sender As Object, e As EventArgs) Handles PunchIN.Click
Session("PunchIn") = DateTime.Now
Timer1.Enabled = True
PunchIN.Visible = False
PunchOut.Visible = True
End Sub
Protected Sub PunchOut_Click(sender As Object, e As EventArgs) Handles PunchOut.Click
Timer1.Enabled = False
Call Update()
PunchOut.Visible = False
PunchIN.Visible = True
Session("PunchIn") = Nothing
End Sub
And now we see this:
Hit punch in, and we now have this:
Ok, so at this point, assuming our page load event does not mess things up?
Then your other controls - such as drop down etc. should not matter - not one bit.
(but, if you re-load combo box on each page load - then you have big issue).
So, lets drop in two more "div" and while they do NOT need to be up-date panels,
we can and will mmake them as such (in a bit!!!).
The 2nd panel will be some filter options, and the 3rd panel will be a grid that 2nd panel can filter.
So, we drop in this filter panel. (float left next to punch in panel)
<div style="width:20%;padding:15px;border:solid 1px;float:left;margin-left:20px">
<h3>Panel 2</h3>
<h4>Filters</h4>
<div style="float:left">
<asp:Label ID="Label1" runat="server" Text="Select City"></asp:Label>
<br />
<asp:DropDownList ID="cboCity" runat="server" Width="160px"
DataValueField="City"
DataTextField="City" >
</asp:DropDownList>
</div>
<div style="float:left;margin-left:20px">
<asp:Label ID="Label2" runat="server" Text="Select Province"></asp:Label>
<br />
<asp:DropDownList ID="cboProvince" runat="server" Width="160px"
DataValueField="Province"
DataTextField="Province" >
</asp:DropDownList>
</div>
<div style="clear:both"></div>
<br />
<div style="float:left">
<asp:Label ID="Label3" runat="server" Text="Must Have Description"></asp:Label>
<br />
<asp:CheckBox ID="chkDescripiton" runat="server" />
</div>
<div style="float:left;margin-left:20px">
<asp:Label ID="Label4" runat="server" Text="Show only Active Hotels"></asp:Label>
<br />
<asp:CheckBox ID="chkActiveOnly" runat="server" />
</div>
<div style="clear:both"></div>
<br />
<div style="float:left;">
<asp:Button ID="cmdSearch" runat="server" Text="Search" CssClass="btn"/>
</div>
<div style="float:right;">
<asp:Button ID="cmdClear" runat="server" Text="Clear Fitler" CssClass="btn"/>
</div>
</div>
And then our grid view: (panel 3)
<div style="width:40%;padding:15px;border:solid 1px;float:left;margin-left:20px">
<h3>Panel 3</h3>
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="False" DataKeyNames="ID" CssClass="table" Width="60%">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="Province" HeaderText="Province" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:BoundField DataField="Active" HeaderText="Active" />
</Columns>
</asp:GridView>
</div>
Code to load?
This:
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()
' load combo box for filters
Dim cmdSQL As New _
SqlCommand("SELECT City FROM tblHotels WHERE City is not null GROUP by City")
cboCity.DataSource = MyrstP(cmdSQL)
cboCity.DataBind()
cboCity.Items.Insert(0, New ListItem("All", "All"))
cmdSQL.CommandText =
"SELECT Province FROM tblHotels WHERE Province is not null GROUP by Province"
cboProvince.DataSource = MyrstP(cmdSQL)
cboProvince.DataBind()
cboProvince.Items.Insert(0, New ListItem("All", "All"))
' load grid data
cmdSQL.CommandText = "SELECT * FROM tblHotelsA ORDER BY HotelName"
GridView1.DataSource = MyrstP(cmdSQL)
GridView1.DataBind()
End Sub
NOTE SUPER care, we test/check IsPostBack = false - else our loading code will trigger each time. ALL YOUR web pages need this IsPostBack test on page load - even if no update panel. (your page will not work correctly if you don't add the above stub).
So, now we have this:
So, really, the combo boxes etc. in that 2nd panel (which is not yet a panel) does not really matter.
but, I could have any post-back from panel 2, say update panel 3. I don't really need to do this, but I could.
So, if I wrap a update panel around 2 and 3 above?
Then for 2nd panel (filter), I need to trigger update of panel 3
So, I add this to panel 2
<Triggers>
<asp:PostBackTrigger ControlID="cmdSearch" />
</Triggers>
but, all in all? use of combo boxes etc on your page? Should not matter.
But then again, every other day - we see posts here in that on page load event, they are re-loading drop downs, grids etc., and THEY REALLY only need to run and load on FIRST page load. As noted, failure to include the If NOt IsPostback code block will break most pages - even without a update panel.
But, do keep in mind, that page load WILL trigger on any post-back from a update panel - including button clicks, and the timer event. While the post-back is not a full page re-fresh, it does trigger page load each time.

Related

Populate a ASP.NET UserControl Dynamically

Is there anyway for a ASP.NET page with say a gridview on it to load a user control into a Modal popup. I would like to use the User Controls onload function but that is triggered when the parent page is loaded, not when you click on for example a link called 'edit' in the GridView.
I don't want to redirect to another ASP.NET page, I would like to popup the edit page which will contain many controls like Dropdowns and Listboxes that in themselves with contain hundreds of records.
I have tried using Ajax and JSON but the population of the dropdowns and listboxes is very slow.
Any help would be appreciated!
I have tried using Ajax and JSON but the population of the dropdowns and listboxes is very slow.
I do this all the time.
So, say a simple gv of hotels.
and our popup control is the user control that is a "form like" layout to edit the one row.
Note the "difficult" issue is if the user does edit, then we need to trigger a refresh of the grid. But, even that is quite easy.
So, say our gv - rather simple.
We drop in a plain jane button (for edit).
So, we have this markup (a gridview)
<div id="MyGridArea" runat="server" clientidmode="static">
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID"
CssClass="table table-hover" Width="60em" AllowPaging="True" GridLines="None"
ShowHeaderWhenEmpty="true" EnableViewState="false">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" SortExpression="LastName" />
<asp:BoundField DataField="City" HeaderText="City" SortExpression="City" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" SortExpression="HotelName" />
<asp:BoundField DataField="Description" HeaderText="Description" SortExpression="Description" />
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="cmdEdit" runat="server" Text="Edit" CssClass="btn"
OnClick="cmdEdit_Click" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<PagerStyle CssClass="GridPager" />
</asp:GridView>
<asp:Button ID="cmdAdd" runat="server" Text="+Add" CssClass="btn myshadow" />
</div>
<br />
<uc1:MyEditHotelC ID="EHotel" runat="server"
MyEditArea="MyEditArea"
MyGridArea="MyGridArea"
MyTable="tblHotelsA"
MyTitle="Edit Hotel Information" />
Note our plain jane edit button.
And, right below the gv is our user control.
Note how I have some custom (public properties) of the UC.
In above, the "div" for "grid" is setup, and also I define the div for editing.
Ok, so code to load is this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadGrid()
End If
End Sub
Sub LoadGrid()
GridView1.DataSource = Myrst("SELECT * FROM [VtblHotelsA] ORDER BY HotelName")
GridView1.DataBind()
End Sub
And we now see/get this:
Ok, so now when we hit edit button?
We will get the current row, and THEN pop up our user control.
So, the code behind edit button is this:
Protected Sub cmdEdit_Click(sender As Object, e As EventArgs)
Dim btn As Button = sender
Dim gRow As GridViewRow = btn.NamingContainer
Dim intPK As Integer = GridView1.DataKeys(gRow.RowIndex).Item("ID")
Call EditOne(intPK)
End Sub
Sub EditOne(intPK As Integer)
Me.EHotel.MyPk = intPK
Me.EHotel.LoadData()
Me.EHotel.MyFocusCancel()
ScriptManager.RegisterClientScriptBlock(UpdatePanel1, UpdatePanel1.GetType,
"popedit", "popedit()", True)
End Sub
and now we see this:
I also have a pubic event for the UC. (since if the user edits, we need to re-load (re-display) the gv on this current page.
So, how does the UC pop up that dialog?
The UC uses jQuery.UI. (it does not matter what/which library you use to pop a dialog, but you should pick one and "run" with it.
So, the markup for the UC ALSO includes the jQuery pop dialog.
The markup for the UC is just a "div" and the jquery dialog code.
It looks like this:
<div id="EditRecord" runat="server" style="float:left;display:normal" clientidmode="Static" >
<br/>
<style>
.iForm label {display:inline-block;width:90px}
.iForm span {display:inline-block;font-weight:700
}
.iForm input {border-radius:8px;border-width:1px;margin-bottom:10px}
.iForm select {border-radius:8px;border-width:1px;margin-bottom:10px;margin-bottom:10px;height:24px;margin-left:-3px}
.iForm textarea {border-radius:8px;border-width:1px;margin-bottom:10px}
.iForm input[type=checkbox] {margin-right:8px}
</style>
<div style="float:left" class="iForm">
<label>HotelName</label>
<asp:TextBox ID="txtHotel" runat="server" f="HotelName" width="280">
</asp:TextBox> <br />
<label>First Name</label>
<asp:TextBox ID="tFN" runat="server" f="FirstName" Width="140"></asp:TextBox> <br />
<label>Last Name</label>
<asp:TextBox ID="tLN" runat="server" f="LastName" Width="140"></asp:TextBox> <br />
<label>City</label>
<asp:DropDownList ID="cboCity" runat="server" Width="140px"
DataTextField="City"
DataValueField="id"
f="City_ID" >
</asp:DropDownList>
<br />
<label>Province</label><asp:TextBox ID="tProvince" runat="server" f="Province" Width="75"></asp:TextBox>
(etc. etc. etc.). It just the layout in a div for editing the hotel.
And the pop dialog code is this:
<div id="mydelpop" style="display:none">
<h4>Really delete this Hotel?</h4>
</div>
<script>
function popedit() {
MyPWidth = "62em"
MyWidth = $(window).width()
if (MyWidth < 840) {
MyPWidth = (MyWidth - 25) + 'px'
}
var myDialog = $("#EditRecord");
myDialog.dialog({
title: "Edit Hotel",
width: MyPWidth,
modal: true,
appendTo: "form",
dialogClass : "dialogWithDropShadow",
close: myclose
});
}
function myclose() {
var myDialog = $("#EditRecord");
myDialog.dialog('close')
// myDialog.find("form").remove();
// destory the instance, but only
// if exists (if we dont' clean up then button
// clicks don't work on 2nd use of dialog)
if (myDialog.hasClass('ui-dialog-content')) {
myDialog.dialog('destroy');
}
}
</script>
So, the edit code, the JavaScript parts are part of the UC.
I only have to "set" the values for the UC, and of course "pop" the dialog by injecting the script. At that point, everything else is the UC.
You can see/try a working example of the above code here:
http://www.kallal.ca/WebSite11/WebForm2

Set focus on selected checkbox list item

I am trying to achieve a search function for a checkbox list that i have. Upon typing in the search text, it will set focus on the item in the checkbox list (preferably not through JavaScript).
Below is what i have for the design source.
<asp:Panel runat="server" DefaultButton="Button1">
<br />
<asp:TextBox ID="txtSearchCountry" runat="server" class="form-control" placeholder="Search for a country"/>
<asp:Button ID="Button1" runat="server" Style="display: none" OnClick="Button1_Click1" />
<br />
<div style="OVERFLOW-Y:scroll; WIDTH:100%; HEIGHT:115px">
<asp:CheckBoxList ID="chkCountry" runat="server" RepeatLayout="Table" Height="35px" class="form-control"></asp:CheckBoxList>
</div>
Followed by my vb code.
Protected Sub Button1_Click1(sender As Object, e As EventArgs)
Dim i As Integer
For i = 0 To chkCountry.Items.Count - 1
If InStr(chkCountry.Items(i).Value.Trim(), txtSearchCountry.Text.Trim()) = True Then
End If
Next
End Sub
With the code, i am able to find and match the search text. However, how am i able to set the focus to the item in the checkbox list?

ASP.Net add item to listbox without posting

I am trying to add items to a listbox. I have a textbox and a button and when the user enters something into the textbox and hits add, I want to insert a new item the listbox without the page refreshing.
Here is what I have so far:
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<div class="col-xs-6 text-center">
<asp:Label ID="empid" runat="server" Text="Employee ID" CssClass="label-default label "></asp:Label>
<asp:TextBox ID="txtEmployeeID" runat="server" CssClass="form-control"></asp:TextBox>
<div class="col-xs-6">
<asp:Button ID="btnAddEmp" runat="server" Text="Add Emp" CssClass="btn btn-primary top-buffer" Width="100%" />
</div>
<div class="col-xs-6">
<asp:Button ID="btnRemoveEmp" runat="server" Text="Remove Emp" CssClass="btn btn-danger top-buffer" Width="100%" />
</div>
<asp:ListBox ID="listEmps" runat="server"
CssClass="top-buffer add-height"
Width="100%"
ValidationGroup="req"></asp:ListBox>
</div>
</ContentTemplate>
</asp:UpdatePanel>
and here is my button click event
Protected Sub btnAddEmp_Click(sender As Object, e As EventArgs) Handles btnAddEmp.Click
If Not IsPostBack() Then
If listEmps.Items.Count = 0 Then
listEmps.Items.Add(txtEmployeeID.Text)
Else
'check list to see if employee already exists
For i = listEmps.Items.Count - 1 To 0 Step -1
If RTrim(txtEmployeeID.Text) = RTrim(listEmps.Items(i).ToString) Then
'employee already exists within list
Response.Write("<script>alert('Employee ID " & txtEmployeeID.Text.Trim & " has already been added. ')</script>")
txtEmployeeID.Text = ""
Exit Sub
End If
Next
'add to list
listEmps.Items.Add(txtEmployeeID.Text)
End If
End If
End Sub
How can I properly add items to a listbox without refreshing the page?
Remove your If Not IsPostBack() Then check in your button click event. The IsPostBack() is typically only used for the Page_Load event. Since your button is contained in an UpdatePanel the click event should be asynchronous and won't cause a postback.

Can't find a control in repeateritem.findcontrol

I have a nested repeaters in a form and bind them to tables in a dataset. I can find the controls by name and read and set values in the Itemdatabound event, However I can't find the control by the same name in a button click event. I can find the repeater and the item.
<asp:Repeater ID="rptrDivision" OnItemDataBound="rptrDivision_ItemDataBound" runat="server">
<itemtemplate>
<div class="fluid">
<div class="widget grid12">
<div class="whead"><div class="grid2"><h4 class="fieldDivision" >
<h4 class="fieldDivision" ><asp:Label ID="lblDivName" runat="server" Visible="True" ><%# DataBinder.Eval(Container.DataItem, "LocationName")%></asp:Label></h4></div>
<div class="grid10">
<div class="grid4 divAdmin" ><label><strong>Division Administrator: </strong> </label></div>
<div class="grid8 on_off">
<div class="floatL ml10"><asp:CheckBox ID="cbxDivMgr" name="chbox" runat="server" /></div>
</div>
</div></div>
<asp:Repeater ID="rptrCamera" OnItemDataBound="rptrCamera_ItemDataBound" runat="server" datasource='<%# Container.DataItem.Row.GetChildRows("CameraJoin")%>'>
<HeaderTemplate>
<div class="body">
</HeaderTemplate>
<itemtemplate>
<div class="formRow">
<div class="grid2">
<asp:Label ID="CameraName" runat="server" ><strong><%# Container.DataItem("Name")%></strong></asp:Label> </div>
<div class="grid10" >
<asp:RadioButtonList ID="rblRoles" runat="server" CssClass="mr10" RepeatColumns="5" CellPadding="2" CellSpacing="2">
<asp:ListItem Value="role1" >Role1</asp:ListItem>
<asp:ListItem Value="role2">Role2 </asp:ListItem>
<asp:ListItem Value="role3" >Role3 </asp:ListItem>
<asp:ListItem Value="Role4">role4 </asp:ListItem>
<asp:ListItem Value="none" Selected="True">N/A </asp:ListItem>
</asp:RadioButtonList>
</div>
</div>
</itemtemplate>
<FooterTemplate>
</div>
</FooterTemplate>
</asp:Repeater>
</itemtemplate>
</asp:Repeater>
<asp:Button ID="btnSubmit" runat="server" Text="Submit" CssClass="buttonM bBlue" OnClientClick="btnSubmit_Click" /> <asp:Button ID="btnCancel" runat="server" Text="Cancel" CssClass="buttonM bBlue" OnClientClick="btnCancel_Click"/>
The submit button is outside the repeater but in the same form
Protected Sub btnSubmit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSubmit.Click
For Each Item As RepeaterItem In rptrDivision.Items
If (Item.ItemType = ListItemType.Item) Or (Item.ItemType = ListItemType.AlternatingItem) Then
DivLabel = CType(Item.FindControl("lblDivName"), Label)
DivName = DivLabel.Text
DivMgr = CType(Item.FindControl("cbxDivMgr"), CheckBox)
'''do some logic
End If
Next
End Sub
I've looked in the debugger and item has the correct number of controls so I know I am in the right place, but the findcontrol in the repeater item can't locate the control by name. It always comes back as null.
Every example I can find from here to MSDN forums to asp.net to bytes.com show looping through the items in the repeater and calling the find control the same way. I can't figure out what I am doing wrong.
Edit:
SO here is the kicker just make sure I'm not crazy I did a loop through the controlscollection on the repeater item and on the second control it comes back with the ID "lblDivName" yet if I call the item.findControl("lblDivName") it returns a null value.
Control events (like a Button's click event) occur before DataBound events (see ASP.NET Page Life Cycle on MSDN for more information). Thus, your Repeater is not DataBound yet, so its databound controls have not been initialized (they are null).
You have some options.
Preferably, you would use the Repeater's databound event to work with it's data items - since this is when you know for sure that they are initialized and populated with values.
However, you could just call "DataBind" prior to doing the processing in your Click event:
Protected Sub btnSubmit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSubmit.Click
rptrDivision.DataSource = yourDataSource
rptrDivision.DataBind()
For Each Item As RepeaterItem In rptrDivision.Items
' The rest of your code
End Sub
This should ensure that your controls have values.

Do a Button Click from Code behide

I have a gridview which lists Tools and Access values. To edit I have an edit imagebutton on each row. I have an OnRowBound method which assigns an OnClick attribute to each button so that I will know which record I need to edit.
The code is
Protected Sub ChangeFirstRowIcon(ByVal Sender As Object, ByVal e As GridViewRowEventArgs) Handles gv_AccessRights.RowDataBound
'This sub fires on each gridview row created...
'It first checks that the row is a data row (as opposed to Header, Footer etc.)
'If ib_Edit is true then change add an attribut to button with aid, tid and ac values attached.
If e.Row.RowType = DataControlRowType.DataRow Then
Dim ib_Edit As ImageButton = e.Row.FindControl("ib_Edit")
Dim lb_AccessID As Label = e.Row.FindControl("lb_AccessID")
Dim hd_ToolID As HiddenField = e.Row.FindControl("hd_ToolID")
Dim hd_AccessCode As HiddenField = e.Row.FindControl("hd_AccessCode")
If ib_Edit IsNot Nothing Then
ib_Edit.Attributes.Add("onClick", "proxyClick('" & lb_AccessID.Text & "', '" & hd_ToolID.Value & "', '" & hd_AccessCode.Value & "')")
End If
End If
End Sub
I'm using a hidden proxy button to show a modal popup which the user will use to edit a record... (the same popup will be used to add a new access record... but that will come later). So having passed my details to proxyClick I set values to controls within the modal popup. The javascript is....
<script type="text/javascript">
function proxyClick(aid, tid, ac) {
document.getElementById('hd_AccessID').value = aid;
document.getElementById('hd_ToolIDMod').value = tid;
document.getElementById('hd_AccessCodeMod').value = ac;
document.getElementById('but_SetModalDetails').click();
}
</script>
For reference the main bits of the markup are....
<table class="border">
<tr>
<td>
<asp:Button ID="but_SetModalDetails" runat="server" Style="display: none" Text="Set modal details" ClientIDMode="Static" UseSubmitBehavior="true" />
<asp:Button ID="but_HiddenProxy" runat="server" Style="display: none" Text="Hidden Proxy Button for Modal Popup" ClientIDMode="Static" />
</td>
<td class="rt">
<asp:Button ID="but_AddTool" runat="server" AccessKey="A" CssClass="butGreen" Text="Add Tool" ToolTip="Add Tool - Alt A" />
</td>
</tr>
</table>
<asp:ModalPopupExtender ID="mpx_AddEditAccess" runat="server" CancelControlID="but_Cancel"
BehaviorID="pn_AddEditAccess" PopupControlID="pn_AddEditAccess" TargetControlID="but_HiddenProxy"
BackgroundCssClass="modalBackground" />
<asp:Panel ID="pn_AddEditAccess" runat="server" Width="500px" CssClass="modalPopup"
Style="display: block">
<div class="box">
<h2>
<asp:Label ID="lb_ModTitle" runat="server"></asp:Label>
</h2>
<asp:HiddenField ID="hd_AccessID" runat="server" ClientIDMode="Static"></asp:HiddenField>
<div class="block">
<asp:UpdatePanel ID="up_Access" runat="server" UpdateMode="Always">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ddl_ToolName" EventName="SelectedIndexChanged" />
</Triggers>
<ContentTemplate>
<table>
<tr>
<th class="p66 rt">
Tool Name:
</th>
<td class="p66">
<asp:HiddenField ID="hd_ToolIDMod" runat="server" ClientIDMode="Static" />
<asp:DropDownList ID="ddl_ToolName" runat="server" AutoPostBack="true" AppendDataBoundItems="True"
DataSourceID="SqlDS_Tools" DataTextField="ToolName" DataValueField="ToolID" OnSelectedIndexChanged="ddl_ToolName_SIC">
<asp:ListItem Text="Please Select..." Value="0"></asp:ListItem>
</asp:DropDownList>
<asp:SqlDataSource ID="SqlDS_Tools" runat="server" ConnectionString="<%$ ConnectionStrings:ToolsConnString %>"
SelectCommand="SELECT [ToolID], [ToolName] FROM [tbl_Tools] WHERE ([Redundant] = #Redundant)">
<SelectParameters>
<asp:Parameter DefaultValue="False" Name="Redundant" Type="Boolean" />
</SelectParameters>
</asp:SqlDataSource>
<asp:RequiredFieldValidator ID="rfv_ddl_ToolName" runat="server" ControlToValidate="ddl_ToolName"
CssClass="error" Display="Dynamic" ErrorMessage="Please Select Tool Name" InitialValue="0">
</asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<th class="p66 rt">
Access Rights:
</th>
<td class="p66">
<asp:HiddenField ID="hd_AccessCodeMod" runat="server" ClientIDMode="Static" />
<asp:DropDownList ID="ddl_AccessCode" runat="server" Enabled="false">
<asp:ListItem Text="No Access" Value="0"></asp:ListItem>
</asp:DropDownList>
</td>
</tr>
<tr>
<td class="p66">
<asp:Button ID="but_Cancel" runat="server" Text="Cancel" />
</td>
<td class="p66 rt">
<asp:Button ID="but_Save" runat="server" Text="Save" />
</td>
</tr>
</table>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</div>
</asp:Panel>
As you can see I have implemented two hidden buttons but_SetModalDetails and but_HiddenProxy. but_SetModalDetails has some codebehind which sets a couple of dropdown lists (one populated from a datasource, the other is populated dynamically based on the value of the first. The codebehind is...
Protected Sub but_SetModalDetails_Click(ByVal sender As Object, ByVal e As EventArgs) Handles but_SetModalDetails.Click
If hd_AccessID.Value = "0" Then
lb_ModTitle.Text = "Assigning Access Rights to:"
ddl_ToolName.SelectedIndex = 0
ddl_AccessCode.SelectedIndex = 0
ddl_AccessCode.Enabled = False
Else
lb_ModTitle.Text = "Edit Access Rights to:"
ddl_ToolName.SelectedValue = hd_ToolIDMod.Value
ddl_ToolName.Enabled = False
SqlStr = "SELECT AccessID AS ddlValue, AccessText as ddlText FROM tbl_AccessCodes WHERE ToolID = " & hd_ToolIDMod.Value
PopulateDDLvalue(ddl_AccessCode, SqlStr)
ddl_AccessCode.SelectedValue = hd_AccessCodeMod.Value
ddl_AccessCode.Enabled = True
End If
'NOW I NEED TO SIMULATE but_HiddenProxy Click
End Sub
As you can see at the end I need to simulate a click of but_HiddenProxy so that the modalPopup is shown populated with the correct data.
Any Ideas? Thanks
After all that... I was able to do everything in codebehind...
I only needed one hidden button but_HiddenProxy.
In the gridview instead of setting an onClick attribute for each edit image button I just set a commandname of 'AccessEdit' (don't use 'Edit'). I then had a method that handled the gridview.RowCommand event. This found the various info I needed by using findControl on the selected row. These values were then used to populate the dropdowns in the popup and then use the show command to make the popup visible.
One bit that did stump me for a while was why my RowCommand was not triggering when an imagebutton was clicked. I'd forgotten that I had validation in the modal which stopped the RowCommand being executed. I stuck a CausesValidation="false" in the imagebutton and all was OK.
Talk about using a hammer to crack a nut!

Resources