Let’s answer the most popular question about UpdatePanels; "How can I update an UpdatePanel with JavaScript on client-side?" Officially there is no tool or library/interface providing this feature. However there is always a solution :) Before going under the hood, I will introduce you my simple solution; UpdatePanelJavaScriptExtender. You can download it and use JavaScript to update your UpdatePanel. Moreover you can send parameters to the code-behind too.
How to use the UpdatePanelJavaScript Extender?
Download the control (link at the end of the article) and add it to your toolbox. Visual Studio will automatically add AjaxControlToolkit reference to your web site as well. The
UpdatePanelJavaScript Extender is build on AjaxControlToolkit Extender base libraries.
Secondly, just drag-n-drop the control to your web site.
<cc1:UpdatePanelJavaScriptExtender
ID="UpdatePanelJavaScriptExtender1"
runat="server"
ClientCommand="UpdateMe"
TargetControlID="UpdatePanel1"
OnUpdate="UpdatePanelJavaScriptExtender1_Update"></cc1:UpdatePanelJavaScriptExtender>
The extender control has three properties. One of them is the well-know ajax extender property
TargetControlID. The ID of the UpdatePanel, which will be refreshed with JavaScript, should be assigned to TargetControlID. The second property is
ClientCommand. This is the name of the JavaScript command, which you will use to update the UpdatePanel assigned to TargetControlID. The final property is
OnUpdate. OnUpdate property should have the name of the code-behind function to run when a client-side update request happens.
Client-side JavaScript command example;
UpdateMe(prompt('Write
anything to pass to the UpdatePanel with JavaScript?', ''));
The function name is provided by the ClientCommand property of UpdatePanelJavaScript Extender. The javascript function can have only one parameter, however you can pass as many parameter as you want and any type of object by serializing them with JSON. Of course you will need to de-serialize it on the server-side.
Protected
Sub UpdatePanelJavaScriptExtender1_Update(ByVal
Sender As Object,
ByVal E As System.EventArgs, ByVal parameter
As String)
Label1.Text = parameter
End Sub
The server-side event handler has an extra parameter named as “parameter”. This is the parameter send by the JavaScript function. In our tutorial we are just asking the user to enter any string and passing it to the server side. On the server-side the parameter is transferred to
Label1.Text property. Here, in the event handler you can do anything you want. The UpdatePanel will be refreshed after the
onload event handler is completed.
The idea behind
When we put a TextBox control inside an UpdatePanel
and set its AutoPostBack property to True, the textbox controls
onchanged HTML event is filled by a special code causing an asynchronous postback. In order to simulate a client side
UpdatePanel.Update function we will insert an invisible TextBox control inside our
UpdatePanel and call the javascript function hidden inside
onchanged event. The content of the above mentioned TextBox will be our parameter to send to server-side.
Hands-on-Lab
Welcome to the laboratory :) Now we will start building our UpdatePanelJavaScript Extender control. When you start a new
ASP.NET AJAX Control Project you will have to edit two files. One of them is a JavaScript file which will work on the client side. The other one is the server side file, which I like the most as a Visual Basic developer :)
First of all, we will add some code to the JavaScript file. The default JavaScript file is already full of code. In order to let you understand what we need to add, I will put extra comment lines.
Type.registerNamespace('UpdatePanelJavaScript');
UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior =
function(element) {
UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior.initializeBase(this,
[element]);
<!--Our CliendCommand Property variable-->
this._ClientCommandValue =
null;
}
UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior.prototype = {
initialize :
function() {
UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior.callBaseMethod(this,
'initialize');
},
dispose :
function() {
UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior.callBaseMethod(this,
'dispose');
},
<!--Our CliendCommand Property Code starts here-->
get_ClientCommand
: function() {
return this._ClientCommandValue;
},
set_ClientCommand :
function(value) {
this._ClientCommandValue = value;
}
<!--Our CliendCommand Property Code ends here-->
}
UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior.registerClass('UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior',
AjaxControlToolkit.BehaviorBase);
<!-- Our TextBox onchange event fires up here -->
UpdatePanelJavaScript.Update = function(HiddenBoxID,
parameter) {
var
HiddenBox =$get(HiddenBoxID);
if
(typeof(parameter)=="undefined")
{
parameter
=
"RANDOMPARAM"
+
Math.random();
};
if
(HiddenBox.value
==
parameter)
{
parameter
=
parameter
+
"RANDOMPARAM"
+
Math.random();
};
HiddenBox.value = parameter;
var
MyCommand = String(HiddenBox.onchange).replace('function
anonymous()\n{\n','');
MyCommand = MyCommand.replace('\n}','');
MyCommand = MyCommand.replace('function
onchange(event) {\njavascript:\n','');
eval(MyCommand);
};
<!-- Our TextBox onchange event cathcer ends up here -->
First, we need to add a private variable for ClientCommand and define
set and get methods for it. This was the simple job. The hard one is to write the
Update method attached to the UpdatePanelJavaScript namespace at the end of our code. The
Update method gets two parameters. One of them is the ID of our
hidden TextBox and the other one is the parameter to transfer to server-side. The code finds the hidden TextBox and transfers our parameter inside the TextBox. If the parameter is undefined we assign a random parameter with the prefix of "RANDOMPARAM". This is needed because if the content of the textbox doesn’t change we can’t do a postpack. In addition if the incoming parameter is equal to the content of the textbox we need to add a suffix to our parameter in order to get the textboxs content changed. Further on the
onchange event of the TextBox is transferred to a string variable and unwanted codes are cleared. Finally, to start the postback we can launch the code with
eval JavaScript function. This Update JavaScript function will be used by other JavaScript functions created by our server-side extender code.
Now is the time for our server-side code. The code-behind file of our extender controls comes with lots of codes as well. First, we will set our base
TargetControlID type to UpdatePanel.
<TargetControlType(GetType(UpdatePanel))>
We will define a TextBox control to add to the target
UpdatePanel. We need to define it with WithEvents keyword in order to handle its
TextChanged event.
WithEvents MyTextBox
As New System.Web.UI.WebControls.TextBox
Our extender control will have an Update event. The update event should be defined
public. In addition our event will have a third parameter to transfer the incoming parameter from JavaScript, or the text property of our hidden TextBox.
Public Event Update(ByVal
Sender As Object,
ByVal E As EventArgs,
ByVal parameter As
String)
We need to define our ClientCommand property on the server-side as well.
<ExtenderControlProperty()>
_
<DefaultValue("Update")>
_
Public Property
ClientCommand() As String
Get
Return GetPropertyValue("ClientCommand",
"")
End Get
Set(ByVal
value As String)
SetPropertyValue("ClientCommand", value)
End Set
End Property
Now, we will write the server-side code to set the properties of our hidden TextBox and add it to the UpdatePanel. The
visibility and display CSS properties should be
hidden and none. On the second step we will create a
label control and put our JavaScript code inside it. This is the only way I was able to create control specific code for each extender instance on the same page. The JavaScript file created inside our project will be used globally by all extenders on the web page, nevertheless we need separated codes for each extender to let the user update different panels attached to different extenders. We are creating a JavaScript function pointing to our global
Update function inside our JavaScript file by getting the function name from
ClientCommand property and transferring the ID of our extenders hidden
TextBox. This is one of the tricky parts of this extender
control.
Private Sub UpdatePanelJavaScriptExtender_Init(ByVal
sender As Object,
ByVal e As System.EventArgs)
Handles Me.Init
MyTextBox.AutoPostBack = True
MyTextBox.Style.Add("visibility",
"hidden")
MyTextBox.Style.Add("display",
"none")
Dim TargetPanel
As System.Web.UI.UpdatePanel =
Me.TargetControl
TargetPanel.ContentTemplateContainer.Controls.Add(MyTextBox)
Dim script As
New System.Web.UI.WebControls.Label
Dim builder As
New System.Text.StringBuilder
builder.AppendLine("<script language='javascript'
type='text/javascript'>")
builder.Append("function ")
builder.Append(Me.ClientCommand)
builder.AppendLine("(parameter) {")
builder.Append("UpdatePanelJavaScript.Update('")
builder.Append(MyTextBox.ClientID)
builder.AppendLine("', parameter);")
builder.AppendLine("};")
builder.AppendLine("</script>")
script.Text = builder.ToString
Me.Controls.Add(script)
End Sub
Finally, we will handle our hidden TextBoxs TextChanged event in order to get its
Text and transfer as a parameter. We will raise our own event with extra
parameter. If the incoming parameter is a random one generated by our JavaScript code, we will delete it. If the incoming parameter contains a random parameter in order to allow sending same parameter to cause postpack, we will just remove the random parameter and send the rest to the user.
Sub
Control_TextChanged(ByVal
sender
As
Object,
ByVal
e
As
System.EventArgs)
Handles
MyTextBox.TextChanged
Dim
SenderControl
As
System.Web.UI.WebControls.TextBox
= sender
If
SenderControl.Text.IndexOf("RANDOMPARAM")
<> -1
Then
If
SenderControl.Text.IndexOf("RANDOMPARAM")
= 0
Then
RaiseEvent
Update(Me,
e,
"")
Else
RaiseEvent
Update(Me,
e,
SenderControl.Text.Substring(0,
SenderControl.Text.IndexOf("RANDOMPARAM")))
End
If
Else
RaiseEvent
Update(Me,
e,
SenderControl.Text)
End
If
End
Sub
Here is the final code of our code-behind file.
Imports System
Imports System.ComponentModel
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports AjaxControlToolkit
#Region "Assembly
Resource Attribute"
<Assembly: System.Web.UI.WebResource("UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior.js",
"text/javascript")>
#End Region
Namespace UpdatePanelJavaScript
<Description("Creates
JavaScript interface simulating UpdatePanel.Update()")> _
<Designer(GetType(UpdatePanelJavaScriptDesigner))>
_
<ClientScriptResource("UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior",
"UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior.js")>
_
<TargetControlType(GetType(UpdatePanel))>
_
Public
Class UpdatePanelJavaScriptExtender
Inherits ExtenderControlBase
WithEvents MyTextBox
As New System.Web.UI.WebControls.TextBox
Public Event Update(ByVal
Sender As Object,
ByVal E As EventArgs,
ByVal parameter As
String)
<ExtenderControlProperty()>
_
<DefaultValue("Update")>
_
Public Property
ClientCommand() As String
Get
Return GetPropertyValue("ClientCommand",
"")
End Get
Set(ByVal
value As String)
SetPropertyValue("ClientCommand", value)
End Set
End Property
Private Sub UpdatePanelJavaScriptExtender_Init(ByVal
sender As Object,
ByVal e As System.EventArgs)
Handles Me.Init
MyTextBox.AutoPostBack = True
MyTextBox.Style.Add("visibility",
"hidden")
MyTextBox.Style.Add("display",
"none")
Dim TargetPanel
As System.Web.UI.UpdatePanel =
Me.TargetControl
TargetPanel.ContentTemplateContainer.Controls.Add(MyTextBox)
Dim script As
New System.Web.UI.WebControls.Label
Dim builder As
New System.Text.StringBuilder
builder.AppendLine("<script language='javascript'
type='text/javascript'>")
builder.Append("function ")
builder.Append(Me.ClientCommand)
builder.AppendLine("(parameter) {")
builder.Append("UpdatePanelJavaScript.Update('")
builder.Append(MyTextBox.ClientID)
builder.AppendLine("', parameter);")
builder.AppendLine("};")
builder.AppendLine("</script>")
script.Text = builder.ToString
Me.Controls.Add(script)
End Sub
Sub
Control_TextChanged(ByVal
sender
As
Object,
ByVal
e
As
System.EventArgs)
Handles
MyTextBox.TextChanged
Dim
SenderControl
As
System.Web.UI.WebControls.TextBox
= sender
If
SenderControl.Text.IndexOf("RANDOMPARAM")
<> -1
Then
If
SenderControl.Text.IndexOf("RANDOMPARAM")
= 0
Then
RaiseEvent
Update(Me,
e,
"")
Else
RaiseEvent
Update(Me,
e,
SenderControl.Text.Substring(0,
SenderControl.Text.IndexOf("RANDOMPARAM")))
End
If
Else
RaiseEvent
Update(Me,
e,
SenderControl.Text)
End
If
End
Sub
End
Class
End Namespace
Hope this control helps and makes your life easier :) If you don't need any of the features of this extender, but only to simulate a click on a button or textbox you can use the code below.
onclick="<%=
ClientScript.GetPostBackEventReference(new PostBackOptions(TextBox1, ""))
%>"
The advantage of the extender is that you don’t need to add any specific button or textbox in order to cause a postback and handle it. Moreover you get a simple JavaScript function with a parameter passing to server-side, which you can use everywhere on your page.
UpdatePanelJavaScript.zip (492.89 KB)