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
Related
I have an ASPX page that includes a GridView. I want to be able to select a row from the grid, and populate another section of the page based on the selected row. It works if I have EnableEventValidation="false" in the <%# Page %> line, but I have been told that I cannot use that because of a security concern. When I don't include it, selecting a grid row throws an "Invalid postback or callback argument" exception.
How can I implement row selection without disabling event validation?
Here is my code:
ASPX page:
<asp:GridView runat="server" ID="TheGrid" AutoGenerateColumns="false" DataKeyNames="id" EmptyDataText="No Data Found" AllowSorting="true">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="First Name" ReadOnly="true" SortExpression="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="Last Name" ReadOnly="true" SortExpression="LastName" />
<asp:BoundField DataField="Email" HeaderText="Email" ReadOnly="true" SortExpression="Email" />
</Columns>
</asp:GridView>
ASPX.VB code:
Protected Sub TheGrid_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles TheGrid.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
e.Row.Attributes("onclick") = Page.ClientScript.GetPostBackClientHyperlink(TheGrid, "Select$" & e.Row.RowIndex)
e.Row.Attributes("style") = "cursor:pointer"
End If
End Sub
Protected Overrides Sub Render(writer As HtmlTextWriter)
ClientScript.RegisterForEventValidation("TheGrid")
MyBase.Render(writer)
End Sub
Note that when I select a row, the exception is thrown somewhere between Page_Load and Render.
Ok, lets wire up the GV two ways.
First way, drop in a plane jane button for the row click
(we will delete the button and add row click in 2nd example).
so, say this simple GV
<div id="MyGridArea" runat="server" clientidmode="static">
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID"
CssClass="table table-hover" Width="60em" GridLines="None"
ShowHeaderWhenEmpty="true">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="cmdEdit" runat="server" Text="Edit" CssClass="btn myshadow"
OnClick="cmdEdit_Click" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
Note how we just dropped in a plane jane button.
And our code to fill out above 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()
Dim strSQL = "SELECT * FROM tblHotelsA ORDER BY HotelName"
GridView1.DataSource = Myrst(strSQL)
GridView1.DataBind()
End Sub
And now we have this:
Ok, so next part is to drop in a "div" area that allows edit of one row.
So, again, quite much plan jane controls.
And we can "hide" grid when we edit, and show edit area div.
But, I often use jQuery.UI. Really amounts to much the same code as simple hide/show, but this way jQuery.UI turns that SAME div into a nice pop up area.
So, that div area might look like this:
<div id="EditRecord" runat="server" style="float: left; display: none" clientidmode="Static">
<br />
<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:TextBox ID="tCity" runat="server" f="City" Width="140"></asp:TextBox>
<br />
<label>Province</label><asp:TextBox ID="tProvince" runat="server" f="Province" Width="75"></asp:TextBox>
</div>
etc. etc. etc.
so, now lets wire up the button above.
The button will simple:
Get current grid row
Get PK id
Load up div and display.
So, that code is this:
Protected Sub cmdEdit_Click(sender As Object, e As EventArgs)
Dim btn As Button = sender
Dim gRow As GridViewRow = btn.NamingContainer
EditRow(gRow.RowIndex)
End Sub
Sub EditRow(rowNum As Integer)
Dim intPK As Integer = GridView1.DataKeys(rowNum).Item("ID")
Dim strSQL As String = "SELECT * FROM tblHotelsA WHERE ID = " & intPK
Dim rstData As DataTable = Myrst(strSQL)
' load up our edit div
fLoader(Me.EditRecord, rstData.Rows(0))
ViewState("PK") = intPK
ScriptManager.RegisterStartupScript(Me.Page, Page.GetType, "mypopedit", "popedit()", True)
End Sub
As noted, I added a popup from jQuery.UI, but we could just use plain jane "div" and hide/show the grid and show the edit area (or like you have, have that edit area in full view).
(fLoader is a routine I built some time ago - I like everyone became VERY tired of typing code over and over to fill out text boxes etc., so for any text box etc., I use a "made up" attribute called f="Data base column name", and that routine just loops the controls on the form and fills them out. No different than hand coding simple assignments to controls, but with this code I can re-use it over and over.
So, we now see, get this:
Ok, so the only next goal is to add a row click
(and not use that edit button).
So, then all we need is a routine that will get the current row index, and call our edit row routine we have above.
So, we use row data bound, and add that click event that way.
but, do note how the above button click gets the current row. That nice short code works for repeaters, listview etc. (we used naming container).
But, if you want a row click in place of that button?
Then on row data bound, add this code:
Protected Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
e.Row.Attributes.Add("onclick",
"__doPostBack('myrowedit'," & e.Row.RowIndex & ")")
End If
End Sub
And in our page load event, we have this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadGrid()
Else
If Request("__EVENTTARGET") = "myrowedit" Then
EditRow(Request("__EVENTARGUMENT"))
End If
End If
End Sub
And a handy dandy routine that returns a table based on SQL I used above was this:
Public Function Myrst(strSQL As String) As DataTable
Dim rstData As New DataTable
Using mycon As New SqlConnection(My.Settings.TEST4)
Using cmdSQL As New SqlCommand(strSQL, mycon)
mycon.Open()
rstData.Load(cmdSQL.ExecuteReader)
End Using
End Using
Return rstData
End Function
So, all in all, not a lot of code.
You can try the above working example here:
http://www.kallal.ca/Website11/WebForm2
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.
I need to replace the link for each data bound item. I already checked out the databound event of the datarow. The problem with that is I can't control where the link shows up. I'm trying to stay away from javascript and keep it mostly in the code behind. Below is my asp code and the code behind I have. I also want to try to keep as much the same as possible, not changing to the html template items. The process Im using is as follows.
I have a custom object which contains all the fields and data of a blog entry. Those items are put into a list and then supplied to the datagrid.
<asp:GridView ID="grdRecentNews" runat="server" AutoGenerateColumns="False" DataKeyNames="Key"
GridLines="None" PageSize="4" ShowHeader="False"
AllowPaging="True">
<PagerSettings Visible="False" />
<Columns>
<asp:TemplateField>
<ItemTemplate>
<blockquote>
<%-- <strong><a href=**"News.aspx"**>--%>
<strong><a href="News.aspx">
<%#Eval("NewsDesc")%></a></strong>
<br />
<span class="italic">
<%#Eval("NewsDate")%></span>
</blockquote>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
This is the code I had in the Databound event, problem being I only want to provide a link for one of the fields of the Rss object. as above below. I want to replace News.aspx" for each item added to the datagrid with the rssobject's link property.
Protected Sub grdRecentNews_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles grdRecentNews.RowDataBound
If e.Row.DataItem IsNot Nothing AndAlso e.Row.DataItem.ToString = "RssEntry" Then
Dim curItem As RssEntry = CType(e.Row.DataItem, RssEntry)
e.Row.Attributes.Add("href", curItem.Link) 'data-url
End If
End Sub
I found a way to insert an <%#Eval %> statement into the attribute I wanted to change. I point it towards the correct property of the rssobject, and its working.
<Columns>
<asp:TemplateField>
<ItemTemplate>
<blockquote>
<strong><a href='<%#Eval("Link")%>'>
<%#Eval("NewsDesc")%></a></strong>
<br />
<span class="italic">
<%#Eval("NewsDate")%></span>
</blockquote>
</ItemTemplate>
</asp:TemplateField>
</Columns>
I understand that this is a very common issue, I have been reading documentation on it for days, and I am about to pull my hair out over this issue.
BACKGROUND
I have multiple Gridviews inside of an UpdatePanel. What is happening, is someone is importing an Excel spreadsheet, I am using OpenXML to shread the data and store it in a VB.NET datatable object. I then run all of that data through a custom validation (based on DB information) and then spit out the exceptions (errors) that occur into a Gridview depending on the exception. the max number is 4 Gridviews in one UpdatePanel (each Gridview has it's own functionality). There are two Gridviews that I am using a button to do an action using the data contained in the Gridview. Those two buttons are also located in the Update Panel, just underneath the corresponding Gridviews. Each Gridview is wrapped in an AJAX Collapsible Panel Extender.
Now, when the user clicks on the button, I have a click event in the code behind where I take the information and depending on the exception that occurred, Update or Insert the DB. I loop through the rows, and if no error occurs, I call the datatable.ImportRow and pass the current row to my "Ready" table. I use a ScriptManager.RegisterStartupScript in order to display an alert box letting them know if any errors occurred. Then, I rebind the exception table and the "Ready" table. I have tried just adding an AsyncPostbackTrigger, I have attempted simply calling udpMain.Update() in the code behind, and tried both options of setting the UpdatePanel's UpdateMode property to "Always" and "Conditional".
HTML
<asp:UpdatePanel ID="udpMain" runat="server" UpdateMode="Always">
<ContentTemplate>
<asp:Panel ID="pnlOwnershipDetailsHead" runat="server" Visible="false">
<div class="windHeader" style="cursor: pointer">
<asp:Label id="lblOwnershipDetails" runat="server">Ownership Exceptions</asp:Label>
<asp:ImageButton id="btnOwnershipHead" runat="server"/>
</div>
</asp:Panel>
<asp:Panel ID="pnlOwnershipDetailsBody" runat="server" Visible="false" CssClass="pnl">
<asp:GridView ID="gvOwnershipDetails" runat="server" CssClass="wind" CellPadding="5" AutoGenerateColumns="false">
<HeaderStyle CssClass="windHeader" />
<Columns>
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:BoundField DataField="Serial Number" HeaderText="Serial Number" />
<asp:BoundField DataField="Facility" HeaderText="Facility" />
<asp:BoundField DataField="Department" HeaderText="Department" />
<asp:BoundField DataField="EmpID" HeaderText="EmpID" />
<asp:BoundField DataField="Configuration" HeaderText="Config" />
<asp:BoundField DataField="Error" HeaderText="Errors" />
<asp:TemplateField>
<HeaderTemplate>
<asp:CheckBox ID="chkHeader" ToolTip="Select All" runat="server" onclick="changeAllCheckBoxes(this)" />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="chkItem" runat="server" ToolTip="Select this item" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="btnOwnershipDetails" Text="Change Information" runat="server" CssClass="btn editBtn" />
<ajax:ConfirmButtonExtender ID="cbeOwnershipDetails" runat="server" TargetControlID="btnOwnershipDetails"
ConfirmText="Are you sure you would like to change the ownership information for the selected items?"
OnClientCancel="CancelClick" />
</asp:Panel>
</ContentTemplate>
<asp:UpdatePanel>
CODE BEHIND
Protected Sub btnOwnershipDetails_Click(sender As Object, e As System.EventArgs) Handles btnOwnershipDetails.Click
Dim importdata As New ImportData
Dim ownershipdt As Data.DataTable = Session("ownershipdt")
Dim finalimportdt As Data.DataTable = Session("finalimportdt")
Dim existsError As Boolean = False
For Each Row As Data.DataRow In ownershipdt.Rows
Dim i As Integer = 0
Dim cb As CheckBox = CType(gvOwnershipDetails.Rows(i).Cells(7).Controls(1), CheckBox)
If cb.Checked Then
If importdata.CheckEmpExists(Row("EmpID").ToString) And importdata.CheckSiteExists(Row("Facility").ToString) And importdata.CheckDeptExists(Row("Department").ToString) Then
importdata.UpdateDBOwnership(Row("Serial Number").ToString, ClientInfo.GetEmpID(Row("EmpID").ToString), ClientInfo.GetSiteID(Row("Facility").ToString), ClientInfo.GetDeptID(Row("Department").ToString), _
Row("Description").ToString, Row("Configuration").ToString, portalUser.EmployeeText)
finalimportdt.ImportRow(Row)
Else
existsError = True
End If
End If
i += 1
Next
If existsError = False Then 'Show alert box
ScriptManager.RegisterStartupScript(udpMain, udpMain.GetType(), "alert", "alert('You have changed the ownership information for the selected rows.')", True)
Else
ScriptManager.RegisterStartupScript(udpMain, udpMain.GetType(), "alert", "alert('There was an issue changing ownership to all of the selected rows.')", True)
End If
bindGV(gvOwnershipDetails, ownershipdt)
bindGV(gvImportDetails, finalimportdt)
'udpMain.Update()
Session("ownershipdt") = ownershipdt
Session("finalimportdt") = finalimportdt
btnEmail.Enabled = True
End Sub
Put your panel code between ContentTemplate under asp:UpdatePanel
<asp:UpdatePanel>
<ContentTemplate>
</ContentTemplate>
</asp:UpdatePanel>
Finally! I Have found the answer! https://sites.google.com/site/arlen4mysite/full-postback-for-templatef
Or a single line of code in the Page_Load() does the same thing
ScriptManager.GetCurrent(this).RegisterPostBackControl(btnOwnershipDetails);
I am creating a button at run time and on it's click i want to open a ajax model pop up.
But i am unable to set model pop up's target control id to this run time created button id.
Could some body suggest me how to achieve this? or any alternate way exist?
My code is as following.
This is how i am creaing a run time button.
protected void grdSurveyMaster_ItemCreated(object sender, GridItemEventArgs e)
{
if (e.Item is GridFooterItem)
{
GridFooterItem footerItem = (GridFooterItem)e.Item;
// RadScriptManager1.RegisterAsyncPostBackControl(btn);
Button btn = new Button();
btn.Text = "Take a new survey";
btn.CommandName = "newAssess";
btn.Click += new System.EventHandler(grdMasterbtnClick);
footerItem.Cells[2].Controls.Add(btn);
//ModalPopupExtender1.TargetControlID = "btn";// Convert.ToString(Page.FindControl(Convert.ToString(btn.ClientID)));
}
}
And following is my HTMl
<asp:UpdatePanel ID="updatepanel1" runat="server">
<ContentTemplate>
<cc1:ModalPopupExtender CancelControlID="btnCancel" PopupControlID="modelPopUp" ID="ModalPopupExtender1"
runat="server" TargetControlID="btnDefault">
</cc1:ModalPopupExtender>
<asp:Button ID="btnDefault" runat="server" Visible="false" />
<asp:Panel ID="modelPopUp" runat="server" Visible="false" BackColor="AliceBlue">
<p>
These items will be permanently deleted and cannot be recovered. Are you sure?
</p>
<asp:Button ID="btnOk" Text="OK" runat="server" />
<asp:Button ID="btnCancel" Text="Cancel" runat="server" />
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
Well you're doing right setting the Popup's TargetControl an invisible unused button. Now the best way to show/hide your popup is from Javascript. For this you have to set the behaviorid="someString" of your ModalPopupExtender and create a javascript function like this:
function ShowModalPopup(behaviourId) {
$find(behaviourId).show();
}
Then you can assign the javascript function to a button:
btn.OnClientClick = String.Format("ShowModalPopup('{0}')",
ModalPopupExtender1.behaviorid);