Postback problem when PopupExtender is placed inside a user control - asp.net

I am creating a ModalPopupExtender inside a Web User Control.
When i click on the OK Button in the panel, which is showing as model popup, the Event Handeler of the button is not executing.
This problen does not occure when i do not use the Web User Control.
Here is the user control (.ascx) file code.
<script type="text/javascript" language="javascript">
function OkClicked(sender, e) {
__doPostBack('Button1', e);
}
</script>
<asp:Button ID="Button2" runat="server" Text="Show" />
<asp:Panel ID="Panel1" runat="server">
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
</asp:Panel>
<asp:ModalPopupExtender ID="ModalPopupExtender1" runat="server"
DropShadow="True" OkControlID="Button1" PopupControlID="Panel1"
TargetControlID="Button2" onokscript="OkClicked()">
</asp:ModalPopupExtender>
<p>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</p>
And the Event Handeler for the click event of the 'Button1' is
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = TextBox1.Text;
}

In the javascript you shouldn't put 'Button1' as the name of the control. Instead, on the PreRender event of your control, fill that out with this.Button1.ClientID .
ClientID is the unique identifier across the entire generated page of your button control, allowing the server to pinpoint exactly what control triggered the postback.
If this wasn't like that, you wouldn't be able to place multiple instances of a same control on one page.
In code:
<script type="text/javascript" language="javascript">
function OkClicked(sender, e) {
__doPostBack('<%= this.Button1.ClientID %>', e);
}

Couple of suggestions:
Do you have any kind of validation on this page. If so, then it's possible that when you click the ok button, that validation is failing. When you click the button, likely the ModalPopup Extender will close, and if validation fails it may cancel the event happening. If this is the case, add an attribute: CausesValidation="false"
If that doesn't work, you may add an attribute to MAKE it post back, I believe there's an attribute -> AutoPostBack="true".
#Joachim is correct that you'll need to use the clientID, but at the same time, I don't think you'll need to call javascript to run the backend code.
Also, you may consider putting this into an UpdatePanel so that you do an AJAX postback without sending the entire page back and forth when the page is posted back.

Related

How to use a custom ValidatorUpdateDisplay function when the controls / validators are loaded on postback in an UpdatePanel the first time?

In ASP.NET when using validation controls (i.e. RequiredFieldValidator) the client sided framework will execute the JS function Page_ClientValidate. This function will validate all controls on the page (of the given ValidationGroup) and call the JS function ValidatorUpdateDisplay with a parameter of the DOM element of the span tag of the validator control.
ValidatorUpdateDisplay toggles the visibility of the span tag depending on the result of the validation.
In my web application I've overridden the ValidatorUpdateDisplay JS function to provide more functionality on the validation scenario (i.e. red borders around the controls, showing popover on the first failed control and scrolling to it).
Now this works very well until my controls (incl. submit button) are shown the first time after a postback in an UpdatePanel.
<asp:ScriptManager runat="server" />
<asp:UpdatePanel ID="upTest" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Button ID="bShow" runat="server" UseSubmitBehavior="false" Text="SHOW" OnClick="bShow_Click" />
<asp:Panel ID="pContent" runat="server" Visible="false">
<asp:TextBox ID="tbTest" runat="server" />
<asp:RequiredFieldValidator ID="rfvTest" runat="server" ControlToValidate="tbTest" Text="Not valid" />
<asp:Button ID="bTest" runat="server" UseSubmitBehavior="false" Text="TEST" />
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
<script type="text/javascript">
function ValidatorUpdateDisplay(val) {
debugger; // this will not be reached
}
</script>
protected void bShow_Click(object sender, EventArgs e)
{
this.pContent.Visible = true;
}
After initial load press bShow to display pContent.
Now, if you leave tbTest.Text empty and press on bTest it should enter the overridden ValidatorUpdateDisplay function, however it enters the function of the framework and displays "Not valid" from rfvTest.
If you change pContent.Visible to true and press bTest after initial load the desired effect will happen: It will enter the custom ValidatorUpdateDisplay function and not display "Not valid".
If you move the button bTest out of the UpdatePanel the problem persists.
How can I make it work inside an UpdatePanel?
ASP.NET uses a lazy loading approach to insert the ValidatorUpdateDisplay function when it needs it the first time, hence in my example it will load the function after the postback of the UpdatePanel.
This will override my own implementation of the ValidatorUpdateDisplay function, because it's inserting the function at the end of the page.
There is a dirty workaround, I just inserted an empty CustomValidator on initial load that is always valid:
<asp:CustomValidator runat="server" />
I wish there was a cleaner solution.

UpdateProgress won't show when causing an UpdatePanel to refresh with javascript

I have an UpdatePanel and inside the update panel I have a button. The updatepanel also has an updateprogress control tied to it in order to display a loading graphic when the updatepanel does a postback.
If I click the button in the update panel then the progress loader shows up just fine. However, if I select the button with jQuery and do .click() the loader doesn't show up. The panel does post back and load content correctly but the progress loader doesn't trigger.
Any ideas why this would be?
I just have tried your scenario. It works fine here.
Here is the html
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:UpdateProgress runat="server" ID="UpdateProgress1">
<ProgressTemplate>
<img src="Images/ajax-loader.gif" />
</ProgressTemplate>
</asp:UpdateProgress>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
</ContentTemplate>
</asp:UpdatePanel>
<input id="btnTest" title="JQuery Click" onclick="ClickButton1()" type="button" value="JQuery Click" />
<script type="text/javascript">
function ClickButton1() {
// alert('#<%=Button1.ClientID %>');
$('#<%=Button1.ClientID %>').click();
}
</script>
Here is the back end code to show loading image for 5 seconds
protected void Button1_Click(object sender, EventArgs e)
{
Thread.Sleep(5000);
}
I never did find the answer to this question but it doesn't matter. I learned that update panels only make one request at a time for a reason. The page life-cycle and viewstate cannot be broken, therefore asynchronous requests can only be made one at a time.
MVC for the win.

Update Panel and triggers from a repeater control

Hi I found code similiar to the following online. It's seems really great for getting a button buried in a repeater control to trigger a full cycle back to the server.
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<%=DateTime.Now.ToString() %>
</ContentTemplate>
<Triggers>
<asp:PostBackTrigger ControlID="HiddenButton" />
</Triggers>
</asp:UpdatePanel>
<!--Make a hidden button to treat as the postback trigger-->
<asp:Button ID="HiddenButton" runat="server" Style="display: none" Text="HiddenButton" />
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="SqlDataSource1">
<ItemTemplate>
<!--when cick the button1, it will fire the hiddenButton-->
<asp:Button ID="Button1" Text="Trigger" CommandArgument='<%# Eval("Id") %>' OnClientClick="$get('HiddenButton').click();return false;"
runat="server" />
</ItemTemplate>
</asp:Repeater>
It uses a hiddenButton to achieve this by hooking the click event of the original button to this one. However my addition to this was the setting of the CommandArgument for the button. I would also need it to be set for the HiddenButton.
Does anyone know a way of going about this?
First I will like to explain the Disadvantage of using the Update Panel using the very same example posted by you.
Below is the Original Code
Output
To display the 22 character string you can check how much data is being received and sent to server. Just imagine following
If you would consider send each request to Database using Update Panel and your GridView is in Update Panel!!!!!!
Suppose you would use ViewState data for each request and with GridView Inside the Update Panel.
Both the above techniques are worst as per my understanding.
Now I will describe you Page Methods
Page Method over Update panel
Page Methods allow ASP.NET AJAX pages to directly execute a Page’s Static Methods, using JSON (JavaScript Object Notation). Instead of posting back and then receiving HTML markup to completely replace our UpdatePanel’s contents, we can use a Web Method to request only the information that we’re interested.
Sample Code
Output
Hope this clearly explains the difference of usage.
Answer to the original Query
You have to register the ItemDataBound event of the below Repeater and use below code for it.
Code Behind
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
Button btn = (Button)e.Item.FindControl("Button1");
btn.OnClientClick = string.Format("SubmitButton('{0}');return false;"
, HiddenButton.ClientID);
}
}
JavaScript
<script type="text/javascript">
function SubmitButton(btn)
{
$("#" + btn).click();
}
</script>
//Alternative
<script type="text/javascript">
function SubmitButton(btn)
{
document.getElementById(btn).click();
}
</script>
Reference & Here
Your HiddenButton control is a server control but you are trying to access it in JQuery using it's ASP.Net ID,
<asp:Button ID="Button1" Text="Trigger" CommandArgument='<%# Eval("Id") %>' OnClientClick="$get('**HiddenButton**').click();return false;"
runat="server" />
A quick way to fix it is to make a separate function,
<script type="text/javascript">
function SubmitButton(btn)
{
$get("#" . btn).click();
}
</script>
and change your button code to ,
<asp:Button ID="Button1" Text="Trigger" CommandArgument='<%# Eval("Id") %>'
runat="server" />
In code behind, in repeater's ItemDataBound event, find the button and HiddenControl and set Button1's OnClientClick property,
Button1.OnClientClick= string.Format("SubmitButton('{0}');return false;",HiddenButton.ClientID);

javascript __doPostBack doesn't seem to work for me

I use yui datatable in my asp.net application... I have a link button in one of my columns and it works fine but doesn't do a postback of a hidden button...
myDataTable.subscribe("linkClickEvent", function(oArgs) {
javascript: __doPostBack('ctl00_ContentPlaceHolder1_Button1', '');
YAHOO.util.Event.stopEvent(oArgs.event);
});
and in my page
<asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button"
style="display:none;" />
protected void Button1_Click(object sender, EventArgs e)
{
DownloadFile(Hfhref.Value, true);
}
I used break point but it doesn't seem to get the __dopostback.. Any suggestion...
add unique id on __doPostBackMethod from Button.
I just did this and it worked,
document.getElementById("ctl00_ContentPlaceHolder1_Button1").click();
just call click() my button it worked...
I want to know whether it works in all browsers...
If you're using ASP.Net 4.0 framework, add ClientIDMode="Static" to your control declaration and you can call __doPostBack('Button1',''); directly.
<asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button"
style="display:none;" ClientIDMode="Static" />
The ClientIDMode attribute is new to 4.0 and allows you the option of having a known unique id for controls. Calling postback for the control will run whatever postback method is defined in the control's OnClick attribute.
In your markup, make sure to properly case the OnClick handler.
onclick="Button1_Click"
should be
OnClick="Button1_Click"
The way you have written it, onclick will be interpreted as an attribute of the control and onclick="Button1_Click" will be rendered to the browser, instead of being handled on the server side.

Issue with Multiple ModalPopups, ValidationSummary and UpdatePanels

I am having an issue when a page contains multiple ModalPopups each containing a ValidationSummary Control.
Here is the functionality I need:
A user clicks a button and a Modal Popup appears with dynamic content based on the button that was clicked. (This functionality is working. Buttons are wrapped in UpdatePanels and the partial page postback calls .Show() on the ModalPopup)
"Save" button in ModalPopup causes client side validation, then causes a full page postback so the entire ModalPopup disappears. (ModalPopup could disappear another way - the ModalPopup just needs to disappear after a successful save operation)
If errors occur in the codebehind during Save operation, messages are added to the ValidationSummary (contained within the ModalPopup) and the ModalPopup is displayed again.
When the ValidationSummary's are added to the PopupPanel's, the ModalPopups no longer display correctly after a full page postback caused by the "Save" button within the second PopupPanel. (the first panel continues to function correctly) Both PopupPanels are displayed, and neither is "Popped-Up", they are displayed in-line.
Any ideas on how to solve this?
EDIT: Functionality in each Popup is different - that is why there must be two different ModalPopups.
EDIT 2: Javascript error I was receiving:
function () {
Array.remove(Page_ValidationSummaries, document.getElementById(VALIDATION_SUMMARY_ID));
}
(function () {
var fn = function () {
AjaxControlToolkit.ModalPopupBehavior.invokeViaServer("MODAL_POPUP_ID", true);
Sys.Application.remove_load(fn);
};
Sys.Application.add_load(fn);
}) is not a function
Missing ";" in injected javascript. see answer below
Image of Error State (after "PostBack Popup2" button has been clicked)
ASPX markup
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<%--*********************************************************************
Popup1
*********************************************************************--%>
<asp:UpdatePanel ID="Popup1ShowButtonUpdatePanel" runat="server">
<ContentTemplate>
<%--This button will cause a partial page postback and pass a parameter to the Popup1ModalPopup in code behind
and call its .Show() method to make it visible--%>
<asp:Button ID="Popup1ShowButton" runat="server" Text="Show Popup1" OnClick="Popup1ShowButton_Click"
CommandArgument="1" />
</ContentTemplate>
</asp:UpdatePanel>
<%--Hidden Control is used as ModalPopup's TargetControlID .Usually this is the ID of control that causes the Popup,
but we want to control the modal popup from code behind --%>
<asp:HiddenField ID="Popup1ModalPopupTargetControl" runat="server" />
<ajax:ModalPopupExtender ID="Popup1ModalPopup" runat="server" TargetControlID="Popup1ModalPopupTargetControl"
PopupControlID="Popup1PopupControl" CancelControlID="Popup1CancelButton">
</ajax:ModalPopupExtender>
<asp:Panel ID="Popup1PopupControl" runat="server" CssClass="ModalPopup" Style="width: 600px;
background-color: #FFFFFF; border: solid 1px #000000;">
<%--This button causes validation and a full-page post back. Full page postback will causes the ModalPopup to be Hid.
If there are errors in code behind, the code behind will add a message to the ValidationSummary,
and make the ModalPopup visible again--%>
<asp:Button ID="Popup1PostBackButton" runat="server" Text="PostBack Popup1" OnClick="Popup1PostBackButton_Click" />
<asp:Button ID="Popup1CancelButton" runat="server" Text="Cancel Popup1" />
<asp:UpdatePanel ID="Popup1UpdatePanel" runat="server">
<ContentTemplate>
<%--*************ISSUE HERE***************
The two ValidationSummary's are causing an issue. When the second ModalPopup's PostBack button is clicked,
Both ModalPopup's become visible, but neither are "Popped-Up".
If ValidationSummary's are removed, both ModalPopups Function Correctly--%>
<asp:ValidationSummary ID="Popup1ValidationSummary" runat="server" />
<%--Will display dynamically passed paramter during partial page post-back--%>
Popup1 Parameter:<asp:Literal ID="Popup1Parameter" runat="server"></asp:Literal><br />
</ContentTemplate>
</asp:UpdatePanel>
<br />
<br />
<br />
</asp:Panel>
<br />
<br />
<br />
<%--*********************************************************************
Popup2
*********************************************************************--%>
<asp:UpdatePanel ID="Popup2ShowButtonUpdatePanel" runat="server">
<ContentTemplate>
<%--This button will cause a partial page postback and pass a parameter to the Popup2ModalPopup in code behind
and call its .Show() method to make it visible--%>
<asp:Button ID="Popup2ShowButton" runat="server" Text="Show Popup2" OnClick="Popup2ShowButton_Click"
CommandArgument="2" />
</ContentTemplate>
</asp:UpdatePanel>
<%--Hidden Control is used as ModalPopup's TargetControlID .Usually this is the ID of control that causes the Popup,
but we want to control the modal popup from code behind --%>
<asp:HiddenField ID="Popup2ModalPopupTargetControl" runat="server" />
<ajax:ModalPopupExtender ID="Popup2ModalPopup" runat="server" TargetControlID="Popup2ModalPopupTargetControl"
PopupControlID="Popup2PopupControl" CancelControlID="Popup2CancelButton">
</ajax:ModalPopupExtender>
<asp:Panel ID="Popup2PopupControl" runat="server" CssClass="ModalPopup" Style="width: 600px;
background-color: #FFFFFF; border: solid 1px #000000;">
<%--This button causes validation and a full-page post back. Full page postback will causes the ModalPopup to be Hid.
If there are errors in code behind, the code behind will add a message to the ValidationSummary,
and make the ModalPopup visible again--%>
<asp:Button ID="Popup2PostBackButton" runat="server" Text="PostBack Popup2" OnClick="Popup2PostBackButton_Click" />
<asp:Button ID="Popup2CancelButton" runat="server" Text="Cancel Popup2" />
<asp:UpdatePanel ID="Popup2UpdatePanel" runat="server">
<ContentTemplate>
<%--*************ISSUE HERE***************
The two ValidationSummary's are causing an issue. When the second ModalPopup's PostBack button is clicked,
Both ModalPopup's become visible, but neither are "Popped-Up".
If ValidationSummary's are removed, both ModalPopups Function Correctly--%>
<asp:ValidationSummary ID="Popup2ValidationSummary" runat="server" />
<%--Will display dynamically passed paramter during partial page post-back--%>
Popup2 Parameter:<asp:Literal ID="Popup2Parameter" runat="server"></asp:Literal><br />
</ContentTemplate>
</asp:UpdatePanel>
<br />
<br />
<br />
</asp:Panel>
Code Behind
protected void Popup1ShowButton_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
//Dynamically pass parameter to ModalPopup during partial page postback
Popup1Parameter.Text = btn.CommandArgument;
Popup1ModalPopup.Show();
}
protected void Popup1PostBackButton_Click(object sender, EventArgs e)
{
//if there is an error, add a message to the validation summary and
//show the ModalPopup again
//TODO: add message to validation summary
//show ModalPopup after page refresh (request/response)
Popup1ModalPopup.Show();
}
protected void Popup2ShowButton_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
//Dynamically pass parameter to ModalPopup during partial page postback
Popup2Parameter.Text = btn.CommandArgument;
Popup2ModalPopup.Show();
}
protected void Popup2PostBackButton_Click(object sender, EventArgs e)
{
//***********After This is when the issue appears**********************
//if there is an error, add a message to the validation summary and
//show the ModalPopup again
//TODO: add message to validation summary
//show ModalPopup after page refresh (request/response)
Popup2ModalPopup.Show();
}
This is an issue with using both ValidationSummary and ModalPopup.
see here: http://ajaxcontroltoolkit.codeplex.com/WorkItem/View.aspx?WorkItemId=12835
The problem is that there is a missing ";" between the two injected scripts.
Their solution is to create/use a custom server control that inherits from ValidationSummary, that injects a ";" into the page startup script to fix the bug:
[ToolboxData("")]
public class AjaxValidationSummary : ValidationSummary
{
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), this.ClientID, ";", true);
}
}
Put all the <asp:ValidationSummary controls at the end of the document.
Error will be resolved.
Did you seto a different "ValidationGroup" of each popup (ValidationSummary + validators) ?
it seems there is bug in modal pop extender with validation summary in panel. to avoid the scenario always put the validation summary modal popup extender and panel at the bottom of code.
add the respective code at bottom of page
<%--This button causes validation and a full-page post back. Full page postback will causes the ModalPopup to be Hid.
If there are errors in code behind, the code behind will add a message to the ValidationSummary,
and make the ModalPopup visible again--%>
<%--*************ISSUE HERE***************
The two ValidationSummary's are causing an issue. When the second ModalPopup's PostBack button is clicked,
Both ModalPopup's become visible, but neither are "Popped-Up".
If ValidationSummary's are removed, both ModalPopups Function Correctly--%>
<%--Will display dynamically passed paramter during partial page post-back--%>
Popup1 Parameter:

Resources