Modular JavaScript enabled user controls in ASP.NET 2.0

ASP.NET is great at separating design and code elements on the server side. This extends to a powerful yet simple way of adding your own custom controls to your ASP.NET websites.

A trackBar control for ASP.NET/Javascript

It provides a great method to connect HTML elements in an .ascx and back end server code in a .cs file. This approach is quick to get going and has long term scalability too. However, on the web today, developers will want to have the option of client side dynamic code too, in the form of JavaScript elements to add to the control.

Microsoft’s suggestions are useful but only suitable for simple applications such as mouseover effects. This is because they tell you how to add isolated fragments of JavaScript to DOM elements. I wanted a single JavaScript class that had permanent links to DOM elements.

Lately they also provide Ajax tools for ASP.NET, and a framework of Ajax controls. There are some nice controls with these tools. However even with everything installed, what you don’t get is an way of adding your own JavaScript enabled custom controls which is as easy as adding a Web User Control from the Add New Item wizard. I was expecting to see a pattern that simply provided a client side .js file to complement the server side .cs and .ascx files. The AJAX tools seem rather over-complex compared to vanilla ASP.NET 2.0, and worse still, this approach requires .dlls to be installed on the server side. I had to telephone my host to ask them to add the components.

I’ll explain the simpler system I have developed. My aims were:

  • To neatly include all the JavaScript in a .js file, containing a parallel JavaScript class for the control.
  • To give the JavaScript part access to DOM elements set up in the .ascx (server side) part of the control (either runat=”client” elements type or elements created with runat=”server” controls).
  • To give the JavaScript part access to the attributes set on the server side of the control.
  • To allow unique HTML IDs, so that there can be more than one control of that type per page, with each control operating independently.

My method enables links not only between server and client sides of a user control, but between controls and their parent elements on the client side (just as could be done on the server side). Think of it as “client-side code behind”.

How it works

  1. An ASP.NET control is set up in the usual way with code behind which adds the .ascx and .ascx.cs files to the project.
  2. The developer adds a .ascx.js file to the project for the client-side components, with a matching name.
  3. This contains a single class wrapped with a single function of the same name, and taking as parameters the client ID of the the control, and any properties that the JavaScript object requires to receive from the server-side part. e.g:

    1. function TrackBar(clientID, minimum, maximum, smallChange, barPixelWidth)
    2. {
    3. //....
    4. }

    The ClientID allows the JavaScript to have access to the DOM relating to its specific instance using the getElementById() function. This is because is possible to predict client IDs of child DOM elements by using the control’s own parent ID. For instance a div declared with <div runat=”server” id=”content”> in a control with client ID “myControl1” will have the client ID “myControl1_content”. In code this could be obtained with getElementByID(clientID + “_content”);

    The use of runat=”server” is necessary because although a static client ID could be provided, this would not have a name unique to the page, and would therefore not allow more than one control of that type per form or parent control.

  4. The developer adds two pieces of JavaScript to the .ascx. Firstly, a client-side include to the .ascx.js script:
    1. <script type="text/javascript" src="TrackBar.ascx.js"></script>

    Below that, a script to create a new instance of the JavaScript object with the expected parameters detailed in the previous step.

    1. <script type="text/javascript">
    2.     <%=ID%>= new TrackBar('<%=ClientID%>', <%=Minimum%>, <%=Maximum%>, <%=SmallChange%>, <%=BarPixelWidth%>);
    3. </script>

    The “<%=ID%> =” before the ‘new’ creates JavaScript code that sets a variable that contains the JavaScript object associated with the control that is named the same as the server side ID for the control. This could allow JavaScript in the parent page to interact with the control object of the child control.

Example

The example trackBar application.

An example with an online demo and full source is presented here. I’ve developed a TrackBar control for ASP.NET similar to the control in Windows Forms. This control is for number entry by a user viewing a web page. It presents a number as a text box, but if the user has JavaScript enabled it also shows a visual slider that can be manipulated with the mouse. The effect on the value can be seen in real time.

The control changes the text in the TextBox which gives a return path of data to the server side. An example of this can be seen in the code in the Default.aspx.cs file.

In addition, a callback can be added to an instance of a TrackBar control on the client (JavaScript) side. An example of this can be seen in the code in Default.ascx.js, where the position and content of a text fragment is changed in real time as the slider is altered.

  1. Sanjay Vasandani’s avatar

    Sorry about commenting on an older thread, but this is a problem I’ve been trying to solve myself for awhile. The problem I see with what you posted is that it works fine in the simple case of controls directly declared on a page, but it would break if you put the control inside a repeater. Once you do that, each control will be trying to create a JS variable with the same name.

    Another complex case is if you want the control to be used inside of another control instead of directly on a page, and then you want multiple instances of the parent control. You once again face the problem of the same ID being used, so the same JS variable name is used.

  2. Scott’s avatar

    Jim –

    Awesome post! I’ve been trying to figure out how to call class methods from element events and you showed me the way. Now I can encapsulate all the javascript in my usercontrols.

    I especially like your javascript code behind technique (simple, but effective).

    Well done, Thanks!

  3. Stephen Vajda’s avatar

    = new TrackBar(”, , , , );

    Its really weird but when I use this in my project the =
    gives me an error but in your project its fine. This really interests me and I’m using it for real work so I would really appreciate some help.

    Thanks very much.
    Steve

Reply

Your email address will not be published. Required fields are marked *