Binding HTML Form Fields To Javascript Objects

Consider that I have a object called ‘person’ with a property called ‘Name’ which returns me the name of a particular person. I want to assign this object property to a form element such that:

  1. The form element will display the value of object property (In our case, the value of person.Name)
  2. If I change the value in form, then it should automatically get assigned to the object property

In C#, it could be done by using the following piece of code:

nameTextBox.DataBindings.Add("Text", person, "Name");

I really like the way DataBinding works and would really like have something like this when I’m working on web applications to bind a object property to input elements in HTML forms. So I decided to write a small javascript that would allow me to bind object properties to form elements. For example, I wanted to write something like this:

<input type="text" object="person" property="firstName" />

Thanks to the power of Javascript and prototype library, I was able to use data binding in html forms using code:

function initializeFormBinding()
{
	var formElements = document.getElementsByTagName('input');
	$A(formElements).each(function(formElement)
				{
					Element.extend(formElement);
					initializeFormElement(formElement);
				});
}
 
function initializeFormElement(formElement)
{
	if (!(formElementHasObjectAttribute(formElement) &amp;&amp; formElementHasPropertyAttribute(formElement)))
		return;
	var objectName = getAttributeValue(formElement,'object');
	var propertyName = getAttributeValue(formElement,'property');
	window.eval('formElement.value = '+objectName+'.'+propertyName);
	window.eval('formElement.onchange=function(){ '+objectName+'.'+propertyName+' = formElement.value; }');
}
 
function formElementHasObjectAttribute(formElement)
{
	return getAttributeValue(formElement,'object')!=null;
}
 
function formElementHasPropertyAttribute(formElement)
{
	return getAttributeValue(formElement,'property')!=null;
}
 
function getAttributeValue(element, attributeName)
{
	return element.readAttribute(attributeName);
}

Lets see how to use this: First, create a javascript object. For example:

var person = {};
person.firstName = '';
person.lastName = '';
person.age = '';
person.country = '';

After that call initializeFormBinding() function using onLoad attribute of body tag. For example:

<body onLoad="javascript:initializeFormBinding();">

Now, in each of your input elements, put the name of the object in ‘object’ attribute and name of property in ‘property’ attribute as follows:

<form>
First Name:
<input type="text" object="person" property="firstName" /><br>
Last Name:
<input type="text" object="person" property="lastName" /><br>
Age:
<input type="text" object="person" property="age" /><br>
Country:
<input type="text" object="person" property="country" /><br>
</form>

Thats it…. If you initialize properties of person object, you would see those values in respective form elements. On the other hand, if you modify the value in a particular input element then it would get reflected in the corresponding object property. Anybody is free to use this code in their applications.

Download a small example application..

Using JSON in Alfresco WebScripts

In my current project, we are using Alfresco for the content repository and all the extra functionalities required are developed using Webscripts. While working on one functionality, I had to serialize javascript objects to JSON and also deserialize it. For doing this, there is a nice javascript code on Alfresco Wiki for converting the object to JSON and vice versa. But to use it, you need to make some slight modifications to the code. The original code doesn’t generate proper JSON code and also has a syntax error in method to obtain the javascript object back from the JSON string. So here is the proper code for handling JSON:

/*
   json.js
(modified 2006-09-07): added support for RHINO
(modified 2006-05-02): json.parse, json,stringify added
  USAGE:
  var jsObj = JSON.parse(jsonStr);
  var jsonStr = JSON.stringify(jsObj);
*/
if (!this.json) {
  var json = (function () {
      var m = {
              'b': 'b',
              't': 't',
              'n': 'n',
              'f': 'f',
              'r': 'r',
              '"' : '\"',
              '': ''
          },
          s = {
              array: function (x) {
                  var a = [], b, f, i, l = x.length, v;
                  for (i = 0; i < l; i += 1) {
                      v = x[i];
                      f = s[typeof v];
                      if (f) {
                          v = f(v);
                          if (typeof v == 'string') {
                              a[a.length] = v;
                              b = true;
                          }
                      }
                  }
                  return '['+a.join()+']';
              },
              'boolean': function (x) {
                  return String(x);
              },
              'null': function (x) {
                  return "null";
              },
              number: function (x) {
                  return isFinite(x) ? String(x) : 'null';
              },
              object: function (x) {
                  if (x) {

                      if (x instanceof Array) {
                          return s.array(x);
                      }
                      if (x.hashCode) return s.string(+x.toString());

                      var a = [], b, f, i, v;
                      for (i in x) {
                          v = x[i];
                          f = s[typeof v];
                          if (f) {

                              v = f(v);

                              if (typeof v == 'string') {
                                  a.push(""+s.string(i)+':'+ v+"");
                                  b = true;
                              }
                          }
                      }
                      return '{'+a.join()+'}';
                  }
                  return 'null';
              },
              string: function (x) {
                  if (/["x00-x1f]/.test(x)) {
                      x = x.replace(/([x00-x1f\"])/g, function(a, b) {
                          var c = m[b];
                          if (c) {
                              return c;
                          }
                          c = b.charCodeAt();
                          return 'u00' +
                              Math.floor(c / 16).toString(16) +
                              (c % 16).toString(16);
                      });
                  }
                  return '"' + x + '"';
              }
          };

     return {
        parse: function(s) {
           try {
              return !(/[^,:{}[]0-9.-+Eaeflnr-u nrt]/.test(s.replace(/"(.|[^"])*"/g,""))) && eval('(' + s + ')');
           } catch (e) {
              return false;
           }
        },
        stringify: s.object
     };
  })();
}

Here is how to use this code to serialize a javascript object:

	o={};
	o.name = "Name";
	o.id = 1;
	j = json.stringify(o);

Also, to obtain the object back from JSON string, you can use following method:

	x = json.parse(j);