Site

Sunday, March 6, 2011

Client side behaviour for ASP .NET control

A very useful feature in ASP .NET control is the possibility to add a client side (JavaScript) behaviour  linked to the common server side code.
Very useful because you can obtain a set of functionalities adding very little code to your User Control, Custom Control, Web Part .. etc.:
  1. JavaScript code is loaded always and only with the rendering of the control.
  2. The server side code makes sure that references and loading of JavaScript code are right. Server side code automatically give JavaScript class a reference to the rendered control (html object) so it is ready to use (you don’t have to worry about finding the right instance of the control in the html page).
  3. You can share information between server side code and client side one, using properties that are valued when the client class is instanced.

Server Side:

The server side code has three requirements:
  1. Inherits from IScriptControl (then it must have implementation of GetScriptDescriptors and GetScriptReferences methods).
  2. OnPreRender and Render method must call one of methods in the point 1
  3. You must be able to retrieve a ScriptManager in the page or control container.
1: public class YouOwnControl : Control, IScriptControl
2: {
3:     private string _fieldOne;
4:     // Other code, fields or properties
5: 
6:     /// <summary>
7:     /// Gets the current page script manager instance
8:     /// </summary>       
9:     protected ScriptManager ScriptManager
10:     {
11:         get
12:         {
13:             ScriptManager sm = ScriptManager.GetCurrent(this.Page);
14:             if (sm == null)
15:                 throw new HttpException("A ScriptManager control must exist on the current page.");
16: 
17:             return sm;
18:         }
19:     }
20: 
21:     protected override void OnPreRender(EventArgs e)
22:     {
23:         base.OnPreRender(e);
24: 
25:         this.ScriptManager.RegisterScriptControl(this);
26:     }
27: 
28:     protected override void RenderContents(HtmlTextWriter writer)
29:     {
30:         base.RenderContents(writer);
31: 
32:         this.ScriptManager.RegisterScriptDescriptors(this);
33:     }
34: 
35:     #region IScriptControl Members
36: 
37:     public IEnumerable<ScriptDescriptor> GetScriptDescriptors()
38:     {
39:         ScriptControlDescriptor descriptor =
40:             new ScriptControlDescriptor("MyControls.Js.YourOwnControl", this.ClientID);
41: 
42:         descriptor.AddProperty("properyOne", String.IsNullOrEmpty(this._fieldOne) ? "" : this._fieldOne);
43: 
44:         return
45:             new ScriptDescriptor[] { descriptor };
46:     }
47: 
48:     public IEnumerable<ScriptReference> GetScriptReferences()
49:     {
50:         ScriptReference reference = new ScriptReference();
51:         // Path to the JavaScript file  
52:         reference.Path = "/scripts/MyControls.Js.YourOwnControl.js";
53: 
54:         return
55:             new ScriptReference[] { reference };
56:     }
57: 
58:     #endregion
59: }

Client side script

A “client control” can be created with a particular template of Visual Studio (Visual Studio 2008). In every case the structure are quite easy to create and you can see it in the follow example of code:
1: Type.registerNamespace("MyControls.Js");
2: 
3: MyControls.Js.YourOwnControl = function (element) {
4:     MyControls.Js.YourOwnControl.initializeBase(this, [element]);
5: 
6:     // --- Members ------
7:     // My suggestion: use this._jself to have a common reference 
8:     // to your control (html element) (Thanks to Francesco Colombo)
9:     this._jself = $(element);
10:     // Variables to store property value
11:     this._propertyOne = null;
12: }
13: 
14: MyControls.Js.YourOwnControl.prototype = {
15: 
16:     // --- Properties ------
17:     // get and set of the properties (naming convention!!)
18:     get_propertyOne: function () {
19:         return this._productID;
20:     },
21:     set_propertyOne: function (value) {
22:         this._propertyOne = value;
23:     },
24: 
25:     //--- Methods ------
26: 
27:     initialize: function () {
28:         MyControls.Js.YourOwnControl.callBaseMethod(this, 'initialize');        
29: 
30:         // some custom code to execute at the load of the control (client side)
31: 
32:         // you can use this._propertyOne value
33: 
34:     },
35:     dispose: function () {
36:         //Add custom dispose actions here
37:         MyControls.Js.YourOwnControl.callBaseMethod(this, 'dispose');
38:     },
39: 
40: 
41: 
42: }
43: MyControls.Js.YourOwnControl.registerClass('MyControls.Js.YourOwnControl', Sys.UI.Control);
44: 
45: if (typeof (Sys) !== 'undefined')
46:     Sys.Application.notifyScriptLoaded();

No comments:

Post a Comment