Showing posts with label steps. Show all posts
Showing posts with label steps. Show all posts

Saturday, March 24, 2012

Exclude are from UpdatePanel

Is there a way to exclude an area from the UpdatePanel?

I ask because I have a usercontrol that has a StepWizard and one of the steps has a file upload. The page that contains the usercontrol has an UpdatePanel that wraps the usercontrol.

The same issue + suggestion ishere.

"I made something named PopupCallback feature for popups calling a server side method on it's opener."

Could you elaborate on this? I'm not really sure what you are doing.

I can't believe this ability wasn't built in to Atlas...hopefully future versions will look at this.


Well you probably have been into the scenario where you have this "Oh crap, I saved something in my popup, now I want the opener page to rebind is grid, to show that the changes were reflected!"
And this should be done without any nasty hacks like window.opener.document.getElementById("fuglyHack").click();

So what I did was to make something a bit more elegant:

First off, I should make it a singleton control that has to exist on Page (like ScriptManager), now I have it embedded in the actual page:

using System;using System.Text;using System.Collections;using System.Collections.Generic;using System.Data;using System.Configuration;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Web.UI.HtmlControls;namespace SomeMysticCompany.Web.SomeWebProject.SiteCore{/// <summary> /// Summary description for BasePage /// </summary>public abstract class BasePage : System.Web.UI.Page, IPostBackEventHandler {private static readonly object EventCommand =new object();public event CommandEventHandler PopUpCallback { add {base.Events.AddHandler( EventCommand,value ); } remove {base.Events.RemoveHandler( EventCommand,value ); } }protected override void OnPreRender( EventArgs e ) {this.Page.ClientScript.RegisterClientScriptBlock(typeof( Page ),"PopUpCallback","function BasePage_PopupPostBack( argument ) { __doPostBack('__Page', argument); }",true );base.OnPreRender( e ); }public void SetCloseScript() {this.ClientScript.RegisterStartupScript(typeof( Page ),"close","window.close();",true ); }public void SetPopupCallbackScript(string commandName,params object[] arguments ) {this.ClientScript.RegisterStartupScript(typeof( Page ),string.Format("PopupCallback_{0}", commandName ),this.GetPopupPostBackReference( commandName, arguments ),true ); }public string GetPopupPostBackReference(string commandName,params object[] arguments ) {object[] data =new object[ 2 ]; data[ 0 ] = commandName; data[ 1 ] = arguments;return string.Format("window.opener.BasePage_PopupPostBack('{0}');", Server.HtmlEncode( Util.GetBase64String( data ) ) ); }#region IPostBackEventHandler Memberspublic void RaisePostBackEvent(string eventArgument ) { CommandEventHandler handler =base.Events[ EventCommand ]as CommandEventHandler;if ( handler ==null )return;object[] data = Util.GetDataByBase64ObjectString( Server.HtmlDecode( eventArgument ) )as object[];if ( data ==null )return; CommandEventArgs args =new CommandEventArgs( data[ 0 ]as string, ( data.Length > 1 ) ? data[ 1 ] :null ); handler(this, args ); }#endregion }}

That's the first piece of code. Now, to get a reference to create a popup callback script you just call
"SetPopupCallbackScript", or just use "GetPopupPostBackReference" if you want it on a client click or something.

Now, the interesting part is the server side HANDLER of the callback... what happens is that when you execute the script returned from these methods, you will set a serialized object array on the window.opener and submit.
The only thing you need to do is to hook up to the event exposed:

// Some user control or whateverprotected override void OnInit( EventArgs e ){this.Page.PopUpCallback +=new CommandEventHandler( Page_PopUpCallback );base.OnInit( e );}private void Page_PopUpCallback(object sender, CommandEventArgs e ){if ( e.CommandName !="GetData" )return;this.LoadData();}
This will call "LoadData" if you have the popup executing the script:
// In popup, actually outputting script to raise event on openerprivate void Finish(){this.Page.SetPopupCallbackScript("GetData" );}
Is this clear to you? This provides a bit more clean way to pass data without losing it's integrity.
Sorry, referencing this.Page instead of base is just stupid, I am just so used to doing that, replace it!

I'll have to take some time to look it over. I'm actually trying to exclude a file upload control from a step wizard. I don't usually code at this level but I think I see how it's working.

Thanks for working with me!

Exception: Either Path or Type must be set on a ServiceReference

I am getting an exception with the script manager on my page. I just would like some basic troubleshooting steps to elimate this problem.

Maybe what it means, what I should look for, etc.

StackTrace:

[InvalidOperationException: Either Path or Type must be set on a ServiceReference]
Microsoft.Web.UI.ServiceReference.GetProxyPath(Control control) +217
Microsoft.Web.UI.ScriptManager.GetScriptReferences() +847
Microsoft.Web.UI.ScriptManager.RenderXmlScript(TextWriter writer) +43
Microsoft.Web.UI.ScriptManager.OnPagePreRenderComplete(Object sender, EventArgs e) +402
System.EventHandler.Invoke(Object sender, EventArgs e) +0
System.Web.UI.Page.OnPreRenderComplete(EventArgs e) +75
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +6198

Hi Bill,

What does your <atlas:ServiceReference> look like? As the error message explains, it must have either a Path or Type attribute (in most cases, you want 'Path'). You may want to look through the quickstart for examples. e.g.here.

thanks,
David


I was manually creating my ServiceReference because it was wrapped inside a Custom Server Control. I just needed to set the Path attribute. I forgot all about that when I moved it from a page level declaration to a code level declaration.

Thanks for pointing that out!

bill

Wednesday, March 21, 2012

Event handler gets removed after AJAX refresh.

Hi,

I add an event handler on window.onload.
However, this seems to get removed after AJAX refresh.

Following are steps to reproduce behavior.
What may I have missed.

Thanks.
yagimay

[steps]

1. Create an ASP.NET AJAX-Enabled Web Site.
2. Add ScriptManager, UpdatePanel and a TextBox (inside the panel) on web form.
3. Add following script block to web form.

<script type="text/javascript">
window.onload=init;
function init(){
var tx=$get("TextBox1");
$addHandler(tx,"click",txt_click);
}
function txt_click(e){
var tx=e.target;
alert(tx.id+": input numbers.");
}
</script>

4. Add following server side code.

Protected Sub TextBox1_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged

Dim str As String = TextBox1.Text
If Not IsNumeric(str) Then
str = "N/A"
Else
Dim val As Double = Double.Parse(TextBox1.Text)
str = val.ToString("c")
End If
TextBox1.Text = str

End Sub

5. Debug.
6. Click TextBox.
-- TextBox.onclick event occurs (alert appears).
7. Input anything and press [Enter] key.
-- UpdatePanel refresh and TextBox.Text is updated.
8. Click TextBox.
-- TextBox.onclick event does not occurs anymore.

I was able to get this work by using PageRequestManager.add_pageLoaded instead of window.onload.

<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server"/>
<script type="text/javascript">
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(init);

function init(sender,args){
var tx=$get("TextBox1");
$addHandler(tx,"click",txt_click);
}
function txt_click(e){
var tx=e.target;
alert(tx.id+": input numbers.");
}
</script>

Thanks.

yagimay