Ajax, Callback, postback and Sys.WebForms.PageRequestManager.getInstance().add_beginRequest
- by user338262
Hi, I have a user control which encapsulates a NumericUpDownExtender. This UserControl implements the interface ICallbackEventHandler, because I want that when a user changes the value of the textbox associated a custom event to be raised in the server. By the other hand each time an async postback is done I shoe a message of loading and disable the whole screen. This works perfect when something is changed in for example an UpdatePanel through this lines of code:
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(
function (sender, args) {
var modalPopupBehavior = $find('programmaticSavingLoadingModalPopupBehavior');
modalPopupBehavior.show();
}
);
The UserControl is placed inside a detailsview which is inside an UpdatePanel in an aspx. When the custom event is raised I want another textbox in the aspx to change its value. So far, When I click on the UpDownExtender, it goes correctly to the server and raises the custom event, and the new value of the textbox is assigned in the server. but it is not changed in the browser.
I suspect that the problem is the callback, since I have the same architecture for a UserControl with an AutoCompleteExtender which implement IPostbackEventHandler and it works.
Any clues how can I solve this here to make the UpDownNumericExtender user control to work like the AutComplete one?
This is the code of the user control and the parent:
using System;
using System.Web.UI;
using System.ComponentModel;
using System.Text;
namespace Corp.UserControls
{
[Themeable(true)]
public partial class CustomNumericUpDown : CorpNumericUpDown, ICallbackEventHandler
{
protected void Page_PreRender(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
currentInstanceNumber = CorpAjaxControlToolkitUserControl.getNextInstanceNumber();
}
registerControl(this.HFNumericUpDown.ClientID, currentInstanceNumber);
string strCallServer = "NumericUpDownCallServer" + currentInstanceNumber.ToString();
// If this function is not written the callback to get the disponibilidadCliente doesn't work
if (!Page.ClientScript.IsClientScriptBlockRegistered("ReceiveServerDataNumericUpDown"))
{
StringBuilder str = new StringBuilder();
str.Append("function ReceiveServerDataNumericUpDown(arg, context) {}").AppendLine();
Page.ClientScript.RegisterClientScriptBlock(typeof(CorpNumericUpDown),
"ReceiveServerDataNumericUpDown", str.ToString(), true);
}
nudeNumericUpDownExtender.BehaviorID = "NumericUpDownEx" + currentInstanceNumber.ToString();
ClientScriptManager cm = Page.ClientScript;
String cbReference = cm.GetCallbackEventReference(this, "arg", "ReceiveServerDataNumericUpDown", "");
String callbackScript = "function " + strCallServer + "(arg, context)" + Environment.NewLine + "{" + Environment.NewLine + cbReference + ";" + Environment.NewLine + "}" + Environment.NewLine;
cm.RegisterClientScriptBlock(typeof(CustomNumericUpDown), strCallServer, callbackScript, true);
base.Page_PreRender(sender,e);
}
[System.ComponentModel.Browsable(true)]
[System.ComponentModel.Bindable(true)]
public Int64 Value
{
get { return (string.IsNullOrEmpty(HFNumericUpDown.Value) ? Int64.Parse("1") : Int64.Parse(HFNumericUpDown.Value)); }
set
{
HFNumericUpDown.Value = value.ToString();
//txtAutoCompleteCliente_AutoCompleteExtender.ContextKey = value.ToString();
// TODO: Change the text of the textbox
}
}
[System.ComponentModel.Browsable(true)]
[System.ComponentModel.Bindable(true)]
[Description("The text of the numeric up down")]
public string Text
{
get { return txtNumericUpDown.Text; }
set { txtNumericUpDown.Text = value; }
}
public delegate void NumericUpDownChangedHandler(object sender, NumericUpDownChangedArgs e);
public event NumericUpDownChangedHandler numericUpDownEvent;
[System.ComponentModel.Browsable(true)]
[System.ComponentModel.Bindable(true)]
[System.ComponentModel.Description("Raised after the number has been increased or decreased")]
protected virtual void OnNumericUpDownEvent(object sender, NumericUpDownChangedArgs e)
{
if (numericUpDownEvent != null) //check to see if anyone has attached to the event
numericUpDownEvent(this, e);
}
#region ICallbackEventHandler Members
public string GetCallbackResult()
{
return "";//throw new NotImplementedException();
}
public void RaiseCallbackEvent(string eventArgument)
{
NumericUpDownChangedArgs nudca = new NumericUpDownChangedArgs(long.Parse(eventArgument));
OnNumericUpDownEvent(this, nudca);
}
#endregion
}
/// <summary>
/// Class that adds the prestamoList to the event
/// </summary>
public class NumericUpDownChangedArgs : System.EventArgs
{
/// <summary>
/// The current selected value.
/// </summary>
public long Value { get; private set; }
public NumericUpDownChangedArgs(long value)
{
Value = value;
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace Corp
{
/// <summary>
/// Summary description for CorpAjaxControlToolkitUserControl
/// </summary>
public class CorpNumericUpDown : CorpAjaxControlToolkitUserControl
{
private Int16 _currentInstanceNumber; // This variable hold the instanceNumber assignated at first place.
public short currentInstanceNumber
{
get { return _currentInstanceNumber; }
set { _currentInstanceNumber = value; }
}
protected void Page_PreRender(object sender, EventArgs e)
{
const string strOnChange = "OnChange";
const string strCallServer = "NumericUpDownCallServer";
StringBuilder str = new StringBuilder();
foreach (KeyValuePair<String, Int16> control in controlsToRegister)
{
str.Append("function ").Append(strOnChange + control.Value).Append("(sender, eventArgs) ").AppendLine();
str.Append("{").AppendLine();
str.Append(" if (sender) {").AppendLine();
str.Append(" var hfield = document.getElementById('").Append(control.Key).Append("');").AppendLine();
str.Append(" if (hfield.value != eventArgs) {").AppendLine();
str.Append(" hfield.value = eventArgs;").AppendLine();
str.Append(" ").Append(strCallServer + control.Value).Append("(eventArgs, eventArgs);").AppendLine();
str.Append(" }").AppendLine();
str.Append(" }").AppendLine();
str.Append("}").AppendLine();
Page.ClientScript.RegisterClientScriptBlock(typeof(CorpNumericUpDown), Guid.NewGuid().ToString(), str.ToString(), true);
}
str = new StringBuilder();
foreach (KeyValuePair<String, Int16> control in controlsToRegister)
{
str.Append(" funcsPageLoad[funcsPageLoad.length] = function() { $find('NumericUpDownEx" + control.Value + "').add_currentChanged(").Append(strOnChange + control.Value).Append(");};").AppendLine();
str.Append(" funcsPageUnLoad[funcsPageUnLoad.length] = function() { $find('NumericUpDownEx" + control.Value + "').remove_currentChanged(").Append(strOnChange + control.Value).Append(");};").AppendLine();
}
Page.ClientScript.RegisterClientScriptBlock(typeof(CorpNumericUpDown), Guid.NewGuid().ToString(), str.ToString(), true);
}
}
}
and to create the loading view I use this:
//The beginRequest event is raised before the processing of an asynchronous postback starts and the postback is sent to the server. You can use this event to call custom script to set a request header or to start an animation that notifies the user that the postback is being processed.
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(
function (sender, args) {
var modalPopupBehavior = $find('programmaticSavingLoadingModalPopupBehavior');
modalPopupBehavior.show();
}
);
//The endRequest event is raised after an asynchronous postback is finished and control has been returned to the browser. You can use this event to provide a notification to users or to log errors.
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(
function (sender, arg) {
var modalPopupBehavior = $find('programmaticSavingLoadingModalPopupBehavior');
modalPopupBehavior.hide();
}
);
Thanks in advance! Daniel.