{"id":23,"date":"2007-12-23T19:44:06","date_gmt":"2007-12-23T18:44:06","guid":{"rendered":"http:\/\/jimblackler.com\/blog\/?p=23"},"modified":"2007-12-23T19:44:06","modified_gmt":"2007-12-23T18:44:06","slug":"modular-javascript-enabled-user-controls-in-aspnet-20","status":"publish","type":"post","link":"https:\/\/jimblackler.com\/?p=23","title":{"rendered":"Modular JavaScript enabled user controls in ASP.NET 2.0"},"content":{"rendered":"<p>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.<\/p>\n<p><img src='http:\/\/jimblackler.com\/blog\/wp-content\/uploads\/2007\/12\/trackbar.gif' alt='A trackBar control for ASP.NET\/Javascript' align='right'\/><\/p>\n<p>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.<\/p>\n<p><a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/aa479011.aspx\">Microsoft&#8217;s suggestions<\/a> 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.<\/p>\n<p>Lately they also provide <a href=\"http:\/\/www.asp.net\/ajax\/\">Ajax tools for ASP.NET<\/a>, and a framework of Ajax controls. There are some nice controls with these tools. However even with everything installed, what you don&#8217;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.<\/p>\n<p>\nI&#8217;ll explain the simpler system I have developed. My aims were:<\/p>\n<ul>\n<li>To neatly include all the JavaScript in a .js file, containing a parallel JavaScript class for the control.<\/li>\n<li>To give the JavaScript part access to DOM elements set up in the .ascx (server side) part of the control (either runat=&#8221;client&#8221; elements type or elements created with runat=&#8221;server&#8221; controls).<\/li>\n<li>To give the JavaScript part access to the attributes set on the server side of the control.<\/li>\n<li>To allow unique HTML IDs, so that there can be more than one control of that type per page, with each control operating independently.<\/li>\n<\/ul>\n<p>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 &#8220;client-side code behind&#8221;.\n<\/p>\n<h1>How it works<\/h1>\n<ol>\n<li>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.<\/li>\n<li>The developer adds a .ascx.js file to the project for the client-side components, with a matching name.<\/li>\n<p>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:<\/p>\n<div id=\"ig-sh-1\" class=\"syntax_hilite\">\n\n\t\n\t<div class=\"code\">\n\t\t<ol class=\"javascript\" style=\"font-family:monospace\"><li><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">function TrackBar(clientID, minimum, maximum, smallChange, barPixelWidth)<\/div><\/li>\n<li><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">{<\/div><\/li>\n<li><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">\/\/....<\/div><\/li>\n<li><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">}<\/div><\/li>\n<\/ol>\t<\/div>\n\n<\/div>\n\n<p>\nThe 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&#8217;s own parent ID. For instance a div declared with &lt;div runat=&#8221;server&#8221; id=&#8221;content&#8221;&gt; in a control with client ID &#8220;myControl1&#8221; will have the client ID &#8220;myControl1_content&#8221;. In code this could be obtained with getElementByID(clientID + &#8220;_content&#8221;);\n<\/p>\n<p>The use of runat=&#8221;server&#8221; 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.<\/p>\n<li>The developer adds two pieces of JavaScript to the .ascx. Firstly, a client-side include to the .ascx.js script:\n<div id=\"ig-sh-2\" class=\"syntax_hilite\">\n\n\t\n\t<div class=\"code\">\n\t\t<ol class=\"html4strict\" style=\"font-family:monospace\"><li><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\"><span style=\"color: #009900\">&lt;<span style=\"color: #000000;font-weight: bold\">script<\/span> <span style=\"color: #000066\">type<\/span><span style=\"color: #66cc66\">=<\/span><span style=\"color: #ff0000\">&quot;text\/javascript&quot;<\/span> <span style=\"color: #000066\">src<\/span><span style=\"color: #66cc66\">=<\/span><span style=\"color: #ff0000\">&quot;TrackBar.ascx.js&quot;<\/span>&gt;&lt;<span style=\"color: #66cc66\">\/<\/span><span style=\"color: #000000;font-weight: bold\">script<\/span>&gt;<\/span><\/div><\/li>\n<\/ol>\t<\/div>\n\n<\/div>\n\n<p>Below that, a script to create a new instance of the JavaScript object with the expected parameters detailed in the previous step.<\/p>\n<div id=\"ig-sh-3\" class=\"syntax_hilite\">\n\n\t\n\t<div class=\"code\">\n\t\t<ol class=\"html4strict\" style=\"font-family:monospace\"><li><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\"><span style=\"color: #009900\">&lt;<span style=\"color: #000000;font-weight: bold\">script<\/span> <span style=\"color: #000066\">type<\/span><span style=\"color: #66cc66\">=<\/span><span style=\"color: #ff0000\">&quot;text\/javascript&quot;<\/span>&gt;<\/span><\/div><\/li>\n<li><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; <span style=\"color: #009900\">&lt;%<span style=\"color: #66cc66\">=<\/span>ID%&gt;<\/span>= new TrackBar('<span style=\"color: #009900\">&lt;%<span style=\"color: #66cc66\">=<\/span>ClientID%&gt;<\/span>', <span style=\"color: #009900\">&lt;%<span style=\"color: #66cc66\">=<\/span>Minimum%&gt;<\/span>, <span style=\"color: #009900\">&lt;%<span style=\"color: #66cc66\">=<\/span>Maximum%&gt;<\/span>, <span style=\"color: #009900\">&lt;%<span style=\"color: #66cc66\">=<\/span>SmallChange%&gt;<\/span>, <span style=\"color: #009900\">&lt;%<span style=\"color: #66cc66\">=<\/span>BarPixelWidth%&gt;<\/span>);<\/div><\/li>\n<li><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\"><span style=\"color: #009900\">&lt;<span style=\"color: #66cc66\">\/<\/span><span style=\"color: #000000;font-weight: bold\">script<\/span>&gt;<\/span><\/div><\/li>\n<\/ol>\t<\/div>\n\n<\/div>\n\n<p>The &#8220;&lt;%=ID%&gt; =&#8221; before the &#8216;new&#8217; 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.\n<\/li>\n<\/ol>\n<\/p>\n<h1>Example<\/h1>\n<p><img src='http:\/\/jimblackler.com\/blog\/wp-content\/uploads\/2007\/12\/trackbars.gif' alt='The example trackBar application.' align='right'\/><\/p>\n<p>An example with <a href=\"http:\/\/jimblackler.com\/JavaScriptUserControlsDemo\/\">an online demo<\/a> and <a href='http:\/\/jimblackler.com\/blog\/wp-content\/uploads\/2007\/12\/javascriptusercontrolsdemo.zip' title='Source for the JavaScript controls demo'>full source<\/a> is presented here. I&#8217;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.<\/p>\n<p>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.<\/p>\n<p>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.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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. It provides a great method to connect HTML elements in an .ascx and back end server code in a .cs file. This approach is [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-23","post","type-post","status-publish","format-standard","hentry","category-web-development"],"_links":{"self":[{"href":"https:\/\/jimblackler.com\/index.php?rest_route=\/wp\/v2\/posts\/23","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jimblackler.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jimblackler.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jimblackler.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/jimblackler.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=23"}],"version-history":[{"count":0,"href":"https:\/\/jimblackler.com\/index.php?rest_route=\/wp\/v2\/posts\/23\/revisions"}],"wp:attachment":[{"href":"https:\/\/jimblackler.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=23"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jimblackler.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=23"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jimblackler.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=23"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}