Dynamic HTML Entities in Form Inputs

I’ve recently re-solved a problem at a client where it’s happened that jQuery is pasting HTML-encoding as form input values instead of the desired HTML entities. It can be done, but it’s a little tricky.

The use case is something along the lines of needing to take a value from elsewhere in a web page’s script and put it into an HTML form. Initially we did this for a form input focus/blur helpful tip; you know the kind where it says something until you click on it or type in it, but if you leave the field blank the helpful tip appears. This can be troublesome when the helpful string in question is an HTML encoded string.

Take the simple example below, which will try to use a string from the JavaScript. Perhaps the string is pulled from a properties file and rendered into HTML by a JSP. However the string gets there, it’s in the script and needs to be in the HTML. Let’s use Chinese, just because it’s obviously different than English.

Consider a simple form and bit of jQuery script that will fill the form input with our helpful text after the page loads, and do the tricky hide on focus, and return if blank on blur:

<html>
<head>
<script type="text/javascript"
 src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js">
</script>
<script type="text/javascript">
 $(function() {
  var encoded = '&#36889;&#26159;&#24456;&#37239;';

  $("#literal").focus(function(){
    if($(this).hasClass("helpful")){
      $(this).val("").removeClass("helpful");
    }
  }).blur(function(){
    if($.trim($(this).val())==""){
      $(this).val(encoded).addClass("helpful");
    }
  });
  $("#literal").blur();
 });
</script>
<style type='text/css'>
.helpful { color: grey; }
</style>
</head>
<body>
  <form>
    <input type="text" name="literal" id="literal" />
  </form>
</body>
</html>

Our encoded string, should render as 這是很酷, which is supposed to say “this is cool,” according to Google Translate. When rendered, however, we’ll find that while our blur effect works just fine, the text it puts into the field is the encoded string, as we see in the source, and not the expected Chinese.

The trouble seems to come with the value of the encoded string skipping some step wherein the encoded characters become HTML entities instead. It doesn’t have to be Chinese, either. &amp; or &quot; or &copy; don’t work, either.

What needs to happen is that the string literal needs to cross some HTML boundary to be evaluated and turn into an HTML entity. We can do this with some on-the-fly creation. A simple change to the spot where we set the value, and we’re suddenly into HTML entities instead of encoded characters. Simply changing the value sent with the .val() call to the HTML of a valid element will do this. The element doesn’t even need to be visible.

Consider this change to the line that sets the input element’s value in our blur event:

$("#literal").val($(document.createElement('div')).html(encoded).html()).addClass("helpful");

Instead of using the variable encoded, which contains our literal value, we replace the variable  the HTML contained in our temporary div element. This HTML contains HTML entities, not encoded characters, so now our problem is solved. Now when the blur effect occurs, the characters will be displayed in the expected Chinese. Very little harm (a tiny bit of latency) if the string has no encoding, too, so it’s safe for simple English phrases, too.

This simple example used a simple blur effect in an input field. The value might not be a static value, but one composed of other elements, or copied out of other script values or variables. The impetus might not be a blur effect, either, but perhaps the response to another action, such as filling in a value after clicking on a different element. The point is to show there’s trouble between the JavaScript and HTML, and that there is a solution as well.

Also, this example doesn’t remove the helpful tip from the form, should it be submitted (and it doesn’t have a submit or action), as these weren’t the focus of the discussion.

One thought on “Dynamic HTML Entities in Form Inputs

  1. Veas says:

    $(this).prop(“helfpul”, true);

    🙂

Leave a Reply

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

*

*