How do I trigger an update panel postback from a child page?
I have an update panel in a cell for each row within a gridview. The user clicks a link button from this update panel to display (using window.open()) a popup. Action is t开发者_StackOverflow中文版aken in that popup that updates the data contained within the aforementioned update panel. I want to trigger an update only for that update panel when the popup is closed.
What is the best way to do this? I'm researching capturing the window.close event and somehow passing a value that indicates where the popup was called from and then calling a postback for that update panel in javascript. If it makes a difference (in the least it will - ugh - in my javascript code), I am using a master page and only coding for IE.
Found this: http://forums.asp.net/p/1166328/1941797.aspx which uses the window.opener.document... Again, using a master page complicates matters.
You can use javascript function __doPostBack('eventTarget','eventArgument'). In Client side perhaps looks like this.
function showPopup()
{
var return = window.showModalDialog('someurl','','');
if(return)
{
// do postback for update
__doPostBack('<%= hiddenButton.ClientID %>','eventArgument');
}
}
in server side you should use Update Panel with UpdateMode=Conditional and hidden button like rick schott says. The tricky part is to know which cell that needs to update. If you wired OnClick for hiddenbutton then it will fired that event when __doPostBack called. You can access Request.Form["__EVENTARGUMENT"] from server side to access value that __doPostBack sent. You can play with this value for instance which cell that need to update.
I have done this from a Flash application. My "hack" if you will was to hide a real ASP:Button with CSS. The button was inside the UpdatePanel. I passed the Button.ClientId to the external resource(Flash, new window...etc). When the external resource(Flash in my case) was finished, it calls a JavaScript function that accepts the ClientId and it calls .Click() on the button.
JavaScript:
function CallASPNETClick(id) {
var elmt = document.getElementById(id);
elmt.click();
}
Markup:
!--this is uses for capture an event from Flash with javascript, do not remove--->
<asp:Button ID="hiddenButton" runat="server" Text="Button" style="visibility:hidden" OnClick="hiddenButton_Click" />
You could use hidden fields on the calling page to store any values you need for your callback. The pop-up can use window.opener to store the values in these hidden fields.
You can expand your window.open function to update a javascript variable on the page with a reference to the caller:
<asp:button onclientclick="buttonClicked(this)" />
var lastButton;
function buttonClicked(button) {
lastButton = button;
window.open(x);
return false;
}
If you make the hidden fields asp controls then you'll have access to them on the postback of the update panel.
Edit:
Consider a modalpopup to eliminate issues around people clicking on the calling page while you're expecting them to use the popup.
The simpler (and working) solution I chose was to implement this using the ModalPopupExtender within a user control in the gridview cell. The user control contains the read-only results grid and the ModalPopupExtender. The popup allows you to edit the contents of that grid within the cell of the parent grid. Upon clicking the Add button, the mini grid is updated asynchronously.
A few key items that finally got me to a working solution...
- Wrap the contents of the panel referenced in the PopupControlId property in an update panel
- Hide and show the modal popup in code behind
- A simple and good example of a gridview using multiple ModalPopupExtenders
These Both ways works for me
(1) Via referencing ChildPage from MasterPAge
ContentPlaceHolder_content.FindControl("dvwOrder").Controls.Clear(); ((UpdatePanel)this.ContentPlaceHolder_content.FindControl("upOrders")).Update();
This code is inside Master Page and on my button click I am using contentplaceholder to find the reference for control inside it. Here dvwOrder is my DataView and "upOrders" is my UpdatePanel.
(2) Via Delegates
Put this delegate and eventhandler on Master Page outside any method
public delegate void RefreshButtonClickHandler(object
sender, EventArgs e); public event RefreshButtonClickHandler onRefreshButtonClick;
inside the class inyour button click event do this
if(null == onRefreshButtonClick) { return; } onRefreshButtonClick(sender, e);
Then In Child page's Page_Load Method tie this event with local handler
Child child = (child) this.Master; reports.onRefreshButtonClick += new
Child .RefreshButtonClickHandler(reports_onRefreshButtonClick);
Here Child is my codebehind file's name
create
void child_onRefreshButtonClick(object sender, EventArgs e)
{
}
and you are done
I abandoned my efforts to do this in a seperate window and developed the solution instead using an AJAX ModalPopupExtender. Matt Berseth's example was very helpful.
To update the child grid contained in an update panel within the parent grid, I stored the value of the row from which the button was clicked in a session variable and then using that value called the databind method of the child grid once the user had made their selections and clicked save.
protected void btnShowSkillsetPopup_Click(object sender, EventArgs e)
{
// get the gridviewrow from the sender so we can get the datakey we need
Button btnAddSkillsetsFromRow = sender as Button;
GridViewRow row = (GridViewRow)btnAddSkillsetsFromRow.NamingContainer;
Session["CapRes_ResourceRequestID"] = Convert.ToString(this.grdResources.DataKeys[row.RowIndex].Value);
Session["CapRes_SkillsetUpdatePanel_Row"] = Convert.ToString(row.RowIndex);
ModalPopupExtender.Show();
}
Save code...
int nUpdatePanelID = Convert.ToInt32(Session["CapRes_SkillsetUpdatePanel_Row"].ToString());
UpdatePanel pnlSkillsetsMain = grdResources.Rows[nUpdatePanelID].FindControl("pnlSkillsetsMain") as UpdatePanel;
GridView grdSkillsets = pnlSkillsetsMain.Controls[0].FindControl("CascadingSkillsets1").FindControl("grdSkillsets") as GridView;
grdSkillsets.DataBind();
ModalPopupExtender.Hide();
精彩评论