Javascript string encoding in C#

In a previous post I explained how you can use the C# System.Uri.EscapeDataString() to encode strings to be later decoded by the equvivalent JavaScript decodeURIComponent().

The method above is still valid when encoding HTML tags, but fails short when encoding quotations and ampersands.

The following string in C# will fail when rendered as JavaScript:

string s = "hello's are better than goodbye's";
Response.Write("<script language='javascript'>alert('" + s + "');</script>");

We need to encode the ampersands (the ‘). This will produce a correct output:

string s = @"hello\'s are better than goodbye\'s";
Response.Write("<script language='javascript'>alert('" + s + "');</script>");

The \ will escape the ‘ signs.

Now, .NET 4.0 have introduced a function, HttpUtility.JavaScriptStringEncode() method. This function escapes quotes and double quotes as well as ?’s and &’s.

For us who does not have the possibility to use .NET 4.0, the function is pretty easy to develop. And why not pair it with the System.Uri.EscapeDataString() so you get a complete clean string encoding.

This Extension Method will escape the data and all quotes in one go:

public static class StringExtensions
{
  public static string ToJavaScriptString(this String instr)
  {
    return Uri.EscapeDataString(instr).Replace("'", @"\'").Replace(@"""", @"\""");
  }
}

To use the function you can do the following:

string s = "<h1>hello's</h1>";
Response.Write("<script language='javascript'>alert(decodeURIComponent('" + s.ToJavaScriptString() "'));</script>");

Now you will never have any problems with HTML tags, quotes, double quotes, ampersands or other special signs.

Modal windows does not resize automatically

I’m not sure if this is a bug or a feature, but when using modal windows in Internet Explorer, your HTML is not updated when the window.onresize event is fired. This is pretty annoying, since it is possible and even valid to open modal windows that is resizable:

var result = window.showModalDialog("/mypage.aspx", window, "dialogHeight:500px; dialogWidth:700px; resizable:Yes; scroll:No");

Notice the resizable:Yes parameter, which allows the modal window to be resized.

If your window contains HTML that resizes to the client width and height, and you resize the window, the window.onresize event is in fact fired, but your HTML does not change.

How do you overcome this issue? You will have to resize the HTML yourself, by hooking into the window.onresize event. Add the following to your HTML:

<script language="javascript" type="text/javascript">
  window.onresize = function() {
  }
</script>

There is several ways to write HTML that can be resized. First of all, and most important, the elements that needs to be resized must be accessible from Javascript, so you will have to add the id attribute to the HTML elements to resize.
In my own project I added a table to my HTML. The table has the advantage of being dynamic in nature, and it is possible to select which columns that have a variable size and which have a dynamic size. Observe the following example:

<table id="tbl" width="700px" border="0" cellpadding="0" cellspacing="0">
  <tr>
    <td width="200px">
      <div id="colLeft">
        <!-- Some html -->
      </div>
    </td>
    <td width="100%" valign="top">
      <div id="colCenter">
        <!-- Some html -->
      </div>
    </td>
    <td width="200px">
      <div id="colRight">
        <!-- Some html -->
      </div>
    </td>
  </tr>
</table>

My table has an id called “tbl” and starts with a width of 700px which is the default size of the modal dialog. The first and last columns are fixed in size, leaving the middle column resizable. To resize the table by width, all I have to add to my window.onresize is:

window.onresize = function() {
  document.getElementById("tbl").width = document.documentElement.clientWidth;
}

The height is pushed to the default modal box height of 700px using the 3 div tags in each column, by adding a fixed height of 700px to each column:

#colLeft, #colCenter, #colRight {
  height:700px;
}

To resize in height i will need to resize each div tag individually:

window.onresize = function() {
  document.getElementById("tbl").width = document.documentElement.clientWidth;
  document.getElementById("colLeft").style.height = document.documentElement.clientHeight;
  document.getElementById("colCenter").style.height = document.documentElement.clientHeight;
  document.getElementById("colRight").style.height = document.documentElement.clientHeight;
}

Please notice that 2 onresize events are fired: One when resized in height and one when resized in width. You can therefore make your Javascript more effeicient by saving the old clientWidth and clientHeight in variables, and only resize the HTML if the values are changed:

var oldClientHeight = 0;
var oldClientWidth = 0;

window.onresize = function() {
  if (document.documentElement.clientWidth != oldClientWidth) {
    document.getElementById("tbl").width = document.documentElement.clientWidth;
    oldClientWidth = document.documentElement.clientWidth;
  }
  if (document.documentElement.clientHeight != oldClientHeight) {
    document.getElementById("colLeft").style.height = document.documentElement.clientHeight;
    document.getElementById("colCenter").style.height = document.documentElement.clientHeight;
    document.getElementById("colRight").style.height = document.documentElement.clientHeight;
    oldClientHeight = document.documentElement.clientHeight;
  }
}

This reduces flickering a little bit.

Waiting for gg.google.com

I am developing a Google Maps module for Sitecore, and when I test it in Firefox my Google Javascript won’t load. All I get is: “Waiting for gg.google.com…”.

Waiting for gg.google.com

Waiting for gg.google.com

It seemes to be a problem with certain versions of Firefox and Firebug. If Firebug has Script debugging enabled, the Google Maps script will not load.

Disabling Script debugging in Firebug solves the problem:

Disable Script Debugging in Firebug

Disable Script Debugging in Firebug

But now I cannot debug the Javascript I am creating using Firefox. Well… I’m glad I got Google Chrome.

decodeURIComponent() equivalent in C#

The Javascript decodeURIComponent()  function decodes a string that was URI encoded with the encodeURIComponent() Javascript function. If you wish to encode a string in C# that can be decoded with decodeURIComponent you have to use the EscapeDataString function:

System.Uri.EscapeDataString("This is my text");

The escaping an unescaping of strings can for example be used to add HTML strings to a Javascript array from C#. Adding HTML strings to an array using the ClientScript.RegisterArrayDeclaration() function will produce an error when the page is executed. But if you encode/decode the strings, the function will succeed:

protected void Page_Load(object sender, EventArgs e)
{
  StringBuilder sb = new StringBuilder();
  sb.AppendFormat("\"{0}\"", Uri.EscapeDataString("
<h1>This is my first heading</h1>
"));
  sb.AppendFormat("\"{0}\"", Uri.EscapeDataString("
<h2>This is my second heading</h2>
"));
  sb.AppendFormat("\"{0}\"", Uri.EscapeDataString("
<h3>This is my third heading</h3>
"));
  Page.ClientScript.RegisterArrayDeclaration("myArray", sb.ToString());
}

This function appends 3 HTML strings to an array and adds the array to the page. The strings are now accessible from Javascript. This pseudo function will take an ID of a DIV tag and the index of the array and output the text from the above created array in the DIV tag:

<script language="javascript" type="text/javascript">
  function ShowDescription(divID, index)
  {
    var divTag = document.getElementById(divID);
    divTag.innerHTML = decodeURIComponent( myArray[index] );
  }
</script>

Follow

Get every new post delivered to your Inbox.

Join 92 other followers