.NET and me Coding dreams since 1998!

14Nov/072

How to access server side variable from client side code on UX friendly way

Armen blogged about the best way how to make java script in code behind, which made me blogging this post.

I really think that the java script doesn't belong to code behind and that in most of the typical use cases can be easily ported to client side

The reasons behind that mine opinion are:

  • It is hard to maintain and update java script made by concatenating strings in code behind
  • Every single change (no matter how small requires rebuilding) which can take 15-20 minutes in some applications
  • UX persons (experts for Java Script kung fu) in general prefer staying in markup level and hate going in code behind
  • DEV persons in general prefer UX staying outside of code behind :)

So an example of typical use case I am seeing on code reviews, is building a java script in code behind because the code need to embed into the script control run time ClientID (in case you don't know what is it take a peak here)

The code I am describing is covering next use case:

There are text box and a button controls on a web form and page defines an integer property called TestProperty.
Click on the button should produce a client side alert message which would show the entered content of the text box and a value of the test property

So the markup looks something like this

   1: <form id="form1" runat="server">
   2: <div>
   3:      <asp:TextBox ID="InputTextBox" runat="server" />
   4:      <input type="button" value="Alert" onclick="Print();" />
   5: </div>
   6: </form>

The string builder code behind approach to implementing use case (and I am pretty sure you've seen it yourself a lot of times)  could look like this:

   1: private int _testProperty;
   2: public int TestProperty
   3: {
   4:     get { return _testProperty; }
   5:     set{_testProperty = value;}
   6: }
   7:  
   8: protected void Page_Load(object sender, EventArgs e)
   9: {
  10:     TestProperty = 3;
  11:     StringBuilder sb = new StringBuilder();
  12:     sb.AppendLine(@"<script type='text/javascript'>");
  13:     sb.AppendLine(@"function Print()");
  14:     sb.AppendLine(@"{");
  15:     sb.AppendFormat(@"alert(document.getElementById('{0}').value);n", InputTextBox.ClientID);
  16:     sb.AppendFormat(@"alert(Test value='{0});n", TestProperty);
  17:     sb.AppendLine(@"}");
  18:     sb.AppendLine(@"</script");
  19:     if (!Page.ClientScript.IsClientScriptBlockRegistered("print"))
  20:         Page.ClientScript.RegisterClientScriptBlock(GetType(), "print", sb.ToString());
  21: }

In lines 1-6 we have a plain old integer property definition which value we set in first line (line 10) of the Page_Load method. 

So, in lines 11-18 code is concatenating the text of the java script function with a special cases happening in:

  • line 15 where we concatenate to java script string ClientID property value of the InputTextBox server side control
  • line 15 where we concatenate to java script string value of the TestProperty

In line 19 then we check if we didn't register the script already and in case not (in line 20) we are registering it.
(I'll live this piece of code in this state fully aware of how unoptimized it is:) )

Obviously, the reason why the server side java script is been used here is the need for accessing some server side property from client side. This java script needs a server side control attribute value and a server side variable value.

The way how to do the same thing on client side is based on very simple idea: usage of good old <%=  something  %> tag which allows (in place of something) referring any server side, code behind variable

So the same functionality implemented on markup (client side) level would look like this:

   1: <form id="form1" runat="server">
   2: <div>
   3:      <asp:TextBox ID="InputTextBox" runat="server" />
   4:      <input type="button" value="Alert" onclick="Print();" />
   5: </div>
   6:  
   7: <script type="text/javascript">
   1:  
   2:     function Print()
   3:     {
   4:      alert(document.getElementById('<%= InputTextBox.ClientID %>').value);
   5:      alert(<%= TestProperty %>);
   6:     }

7: </script>

   8:  
   9: </form>

Notice that:

  •  in line 4, I am using <%= InputTextBox.ClientID %> which means something like "Insert here ClientID value of the server side control InputTextBox"
  • in line 5, I am using <%= TestProperty %> which means something like "Reach out to server side and give me the value of TextProperty variable

With this approach no code in page load is required, Print function can be modified on client side only without the need of rebuilding the web application and making changes in code such is changing property name breaks the build

That contributes a lot to increasing productivity and happiness of UX people :)

Conclusion

Having in mind how natural it is building java script on client side but still "aware of server side" I really think that usage of JavaScriptStringBuilder should be discouraged and used only in use cases when the same thing can not be done on the way described (if there any cases like that in real world)

 

Share this post :

Comments (2) Trackbacks (0)
  1. Other solutions could be maintain the javascript in a resource xml file, and in the code behind replace (via string.format or a custom format list) with the forms/object/data values…

    that could avoid the recompile of the code any time when i need to make changes. Of course this approach must implements caching, etc … to be the most efficient possible.

    Regards

  2. Hi Nikola,

    Thanks for putting this on your website. It really saved lot of my time!


Leave a comment

No trackbacks yet.