Tuesday, November 25, 2008

Using Server Tags in External JS files

Context: Accessing Controls of a Content Page in external Javascript files using server tags like <%= <ControlID>.ClientID %>

ASP.NET compiler generates a UniqueID for each of the control declared. When a control is declared in Content Page of a Master Page say TextBox1, compiler will generate a UniqueID for TextBox like ctl00_ContentPlaceHolder1_TextBox1 i.e. ctl<ControlIndex>_<ContentPlaceHolderID>_<TextBoxID>. To access this control in Javascript, you can hardcode 'ctl00_ContentPlaceHolder1_' as a prefix to actual control id. But, it is not a good practice to hardcode as adding another ContentPlaceHolder/Control before to 'ContentPlaceHolder1' in Master Page will change the UniqueID. Also, if you change the ID of ContentPlaceHolder, you need to go back to all places to change the hardcoded control id.
To overcome this, you can use server tags to get the client id of the control at runtime like '<%= <ControlID>.ClientID %>' for example '<%=TextBox1.ClientID%>' in ASPX page.

When you move this code to an external JS file, all of a sudden your code stops working as expected and cases may throw JS errors.

ASP.NET compiler will compile the code inside server tags <% %> specified with in the aspx page and (#)binds/ (=)assigns /replaces<% %> tags with the compiled code and renders compiled ASPX content in browser following the ASP.NET page life cycle.

ASP.NET compiler will not compile any external Java Script file that is refered using <SCRIPT SRC>. It is the ability or one of the job of the browser to Fetch, Load ,Compile and Execute the JS file. So, JavaScript compiler(which is embedded in browser) will treat any code with in server tags inside JS file as a normal JS code and compiles accrodingly/inline to the JavaScript language syntax. If the server tags are with in single/double quotes like '<%= %>' or "<%# %>", compiler will treat it as a string.

In ajax enabled ASP.NET, JS files will be refered in any of the following ways
<script type="text/javascript" src=="~/Scripts/Script1.js" />
[OR]
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Scripts>
<asp:ScriptReference NotifyScriptLoaded="true" Path="~/Scripts/Script1.js" />
</Scripts>
</asp:ScriptManager>

Any code (like control ids) that has to be used in generic JavaScripts(refered across many pages) has to be passed from the ASP.NET [aspx(.cs)] compiled layer to the external JS files as parameters

From .CS
-To add JavaScript method to a Button OnClick event,

ValidateButton.Attributes.Add("onclick","javascript:return Validate('"+StartDateTextBox.ClientID +"','"+EndDateTextBox.ClientID +"');");

- Adding client script to OnUpdating event of UpdatePanelAnimationExtender
AjaxControlToolkit.Animation OnUpdatedAnimation=new AjaxControlToolkit.Animation();
OnUpdatedAnimation.Name = "ScriptAction";
OnUpdatedAnimation.Properties.Add("Script","onUpdated('" + CustomersGridView.ClientID + "');");
CreateRequestUPAnimation.OnUpdated.Children.Add(OnUpdatedAnimation);

References...
http://www.jsworkshop.com/articles/02scriptsrc.html
http://javascript.crockford.com/script.html

No comments: