Thursday, February 17, 2011

jQuery Templates


I am a big fan of jquery, as it is my favorite javascript framework. It has many great features already, and even more are being developed everyday. It simply makes developing responsive web applications much, much faster.

I am currently working on a large application that displays the user a lot of grids practically on every screen. The data inside the grids, as well as there basic structure can change according to different selections the user makes. It is very important for me to make this web application very responsive and fast, so it was pretty obvious from the start that I'd be using a lot of ajax and depending heavily on the client to do the rendering.

I had a standard ajax call, returning me a json object to work with. I then found myself trying to dynamically build a string that would represent the html markup of a
inside a table, appending it to the table as i iterate over the json properties.
This isn't very difficult to do at first, but will always look very messy, and will be much uglier to maintain...

Luckily, just in time, I came across the jQuery documentation of their new templates feature.
This allows you to design a small template of html, mark where the parameters will be, and bind a json object to that template.
Then, you can practically do whatever you want with it- append it to a table, or just use it as a list of data, and the best part is that the UI is seperated from the 'code', meaning it is very easy to maintain since you can change your template around freely and easily, while never changing the ajax calls nor javascripts.

I'll show some simple examples so you can see what i mean, and to help get you started on your own.

First, you obviously need to include the templates plugin into your html file (can be found here) :
<script language="javascript" type="text/javascript" src="Scripts/jquery-1.4.1.js"></script>
<script language="javascript" type="text/javascript" src="Scripts/jquery.tmpl.js"></script>

The template you want to use, could be inserted into a script tag like this :
<script id="templateStructure" type="text/x-jquery-tmpl">
    <tr>
        <td>${FirstName}</td>
        <td>${LastName}</td>
        <td>${Email}</td>
    </tr>
</script>
Notice that I gave the script an id, which we'll need soon, and the type is marked 'text/x-jquery-tmpl'.

The ${} brackets tell the jquery where to place the data of the json object we will bind. The name inside the brackets must correlate with the properties of the binded json object.
This means our json object will be an array of objects (or one object if thats all we have) that all have the properties 'FirstName', 'LastName' and 'Email'.

The template I created represents a row in a table that i will bind to, and the table im going to bind it to, looks like this :
<table border="1" id="templateTable">
    <tr>
        <td><b>First Name</b></td>
        <td><b>Last Name</b></td>
        <td><b>Email</b></td>
    </tr>
</table>
So when I add the rows, the table will be filled with data.

In order to load the template, I use the template() method :
$('#templateStructure').template('myTemplate');
This will load the template we defined in the script tag and call it 'myTemplate'.

Now, all we need to do is give the template a data source, and place it wherever we want. In our case we'll append it to the table so it 'fill' the table's data.

$(document).ready(function() {
    // our data object we will bind
    var myData = [ {FirstName:'Bob', LastName:'Jannovitz', Email:'bobby@gmail.com'},
                   {FirstName:'Howard', LastName:'Shennaniganz', Email:'howard@yahoo.com'},
                   {FirstName:'Joe', LastName:'Stoozi', Email:'joeii@hotmail.com'} ];

    // load the template and name it 'myTemplate'
    $('#templateStructure').template('myTemplate');

    // bind the data to the template and append to the table
    $.tmpl('myTemplate', myData).appendTo('#templateTable');
});

The final result will be the table with the data rendered into it.

So in conclusion...
The templates jQuery plugin can be extremely useful in binding data to an html template on the client for fast responsive applications. It also has many more great features like instructions that can cause your template to act different to different data situations.
It is important to note though, that all this is only in beta stage, and is subject to change. I however, already started using it, and so far so good... :)

I might be posting something more advanced about this soon, but until then -
You can read more about it here : http://api.jquery.com/category/plugins/templates/

Monday, February 14, 2011

Working with Entities instead of DataTable objects...


I started working on a big new project at work, with a couple of other programmers. This project involves a really big ERD, meaning there are a bunch of entities in the DB, with a lot of relationships between them.

I personally am very fond of working with ORM's, and I am especially familiar with NHibernate which is great in my opinion, and would really work fine in this scenario.
Unfortunately though, some people involved in the project didn't want to work with NHibernate, or any other ORM, with the excuse of "some people aren't familiar with ORM's", "I had bad experiencing working with ORM's in the past", yada, yada, yada...

I'm guessing a lot of you are familiar with this kind of frustration at the work place, with corporate politics and people that aren't keen on learning new technologies.
Instead of getting all frustrated about it this time and trying to fight over a lost cause, I decided to make the best of it...

Obviously, this project, like all the others, is on a very tight schedule.
...So writing up my own ORM, without calling it an "ORM" is out of the question! :-P
I decided to do the least that will help.

Here's my solution :
- I Built the ERD in the db. In this case it's Oracle 11g.
- Then I built a lot of different views so that I will see all the data like the Entities I would've used in an ORM.
- I created a simple DAL, using plain ADO.NET, that has the ability to execute stored procedures, and return DataTable objects (super-straight-forward here).
- I created a class for every entity I will need to work with. Each entities class is built in such a way that all it's properties match all the columns in a certain view that I built in the db.
- I created a small utility that will convert my DataTable's into the entities I built, and then I can work with all the data like i would with objects and not DataTables.

The method that converts a single DataRow into the chosen entity uses reflection (obviously), and looks like this :
public static T ConvertToEntity<T>(this DataRow tableRow) where T : new()
{
    // Create a new type of the entity I want
    Type t = typeof(T);
    T returnObject = new T();

    foreach (DataColumn col in tableRow.Table.Columns)
    {
        string colName = col.ColumnName;

        // Look for the object's property with the columns name, ignore case
        PropertyInfo pInfo = t.GetProperty(colName.ToLower(),
            BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);

        // did we find the property ?
        if (pInfo != null)
        {
            object val = tableRow[colName];

            // is this a Nullable<> type
            bool IsNullable = (Nullable.GetUnderlyingType(pInfo.PropertyType) != null);
            if (IsNullable)
            {
                if (val is System.DBNull)
                {
                    val = null;
                }
                else
                {
                    // Convert the db type into the T we have in our Nullable<T> type
                    val = Convert.ChangeType(val, Nullable.GetUnderlyingType(pInfo.PropertyType));
                }
            }
            else
            {
                // Convert the db type into the type of the property in our entity
                val = Convert.ChangeType(val, pInfo.PropertyType);
            }
            // Set the value of the property with the value from the db
            pInfo.SetValue(returnObject, val, null);
        }
    }

    // return the entity object with values
    return returnObject;
}

In order to use this method on a DataTable as well, we just need to iterate on the rows and insert them into a list.
I did it like this :
public static List<T> ConvertToList<T>(this DataTable table) where T : new()
{
    Type t = typeof(T);

    // Create a list of the entities we want to return
    List<T> returnObject = new List<T>();

    // Iterate through the DataTable's rows
    foreach (DataRow dr in table.Rows)
    {
        // Convert each row into an entity object and add to the list
        T newRow = dr.ConvertToEntity<T>();
        returnObject.Add(newRow);
    }

    // Return the finished list
    return returnObject;
}

Both of these are extension methods. A great use of them in my opinion.
You just need to stick these into a static class, and it gives you the ability to invoke this method on any DataTable you like throughout your project and getting back any type of object you like.
DataTable dt = Dal.GetCompanies();
List<Entities.Company> companyList = dt.ConvertToList<Entities.Company>();

Now, when my DAL returns me a DataTable, I can easily convert it to a list, and work with that as if I were with regular objects.
In my case, most of the project is supposed to end up to be a couple of web services, that select the data from the db, do a bunch of manipulations, and return it in a big xml. So using this concept in this specific case helps me out a lot, since after manipulating the data, I just need to serialize it as XML, and send it as a web service response.

If I needed to insert it back to the DB though, It would be pretty easy to create a method to convert entities back to DataTable objects.
Probably something like this :
public static DataTable ConvertToDataTable(this object obj)
{
    // Retrieve the entities property info of all the properties
    PropertyInfo[] pInfos = obj.GetType().GetProperties();

    // Create the new DataTable
    var table = new DataTable();

    // Iterate on all the entitie's properties
    foreach (PropertyInfo pInfo in pInfos)
    {
        // Create a column in the DataTable for the property
        table.Columns.Add(pInfo.Name, pInfo.GetType());
    }

    // Create a new row of values for this entity
    DataRow row = table.NewRow();
    // Iterate again on all the entitie's properties
    foreach (PropertyInfo pInfo in pInfos)
    {
        // Copy the entitie's property value into the DataRow
        row[pInfo.Name] = pInfo.GetValue(obj, null);
    }

    // Return the finished DataTable
    return table;
}

Some final thoughts on this...
This obviously isn't the best solution to this case, and obviously isn't something ground-breaking neither. I decided to show this as presenting a simple solution that helps a lot when it comes to trying to deal with shitty (in my opinion, obviously) circumstances.

Hope this helps, at least some... :)