Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Data Linking with jQuery

0.00/5 (No votes)
5 Dec 2010 2  
This article discusses an exciting feature of jQuery that is Data Linking

Table of Contents

Introduction

Recently, Microsoft announced three jQuery plugins as Official plugin.

  • jQuery Client Templating
  • Data linking
  • Globalisation

In my last article, I discussed about jQuery Templating. You can view that article here. So I think, you all must find the Templating article very useful. Because, by the time web applications development is evolving, we are moving towards Client side development/scripting, to provide fast and very trendy/flashy look and feel.

So in this article, I am going to discuss another very cool feature, i.e. Data linking. This helps us link the data and the UI.

What is jQuery

jQuery is a JavaScript library that works on top of the JavaScript. jQuery provides a very simple way for HTML document traversing, DOM manipulation, event handling, animating, and Ajax interactions for rapid web development. That could have been very complex while working with normal JavaScript.

jQuery is becoming more and more popular day by day. Even it was integrated with VS2008 and also available with VS2010. jQuery is open source. Due to its features, Microsoft started to support jQuery team and also working with them, to provide better web based tools to their Clients.

Prerequisite

  • jQuery library
  • A plugin for datalinking
  • JSON library

jQuery already comes with VS2008/2010. But if you are working in VS 2005, then you can download from this link.

To download JSON library, click here.

Data Linking

Data linking provides us a way to link our data/objects to UI controls. This means, if the controls get updated, the underlying data object would also be updated. In the same way, if the data objects get updated, the controls on UI will also get updated (in case of two way linking).

This means once you linked your data with the controls, you don't need think about the data object. The syncing between data object and your UI will be taken care of by the jQuery plug in.

So you can imagine, you don't need to get the updated data from the controls and update the object, which is required at the time of saving the data at server, which requires a lot more code to be written and is also error prone.

There are several options to link the data:

  • One way Linking
  • Two way Linking

One Way Linking

One can link the UI controls to some object. This means the object will always be in sync with the UI. Whenever the data in UI will get changed, the underlying object will also get updated. So one need not worry about the data once it is done, one can send the object directly to the server for further processing.

I have explained it with one sample.

In my example, there is a form named as Add Vehicle, where the user can enter the Vehicle name and its price, then click on the Add Vehicle to add the vehicle at server side. One can also see the state of the underlying object at any point of time, using Show Updated Object button. Now let's go through the code.
Lets see the aspx code first:

 <table>
   <tr>
       <td colspan="2"><h2>Add Vehiclie to Vehicle Store</h2></td>
   </tr>
   <tr>
       <td>Vehicle Name</td>
       <td><input id="txtVName" type="text" /></td>
   </tr>
   <tr>
       <td>Price</td>
       <td><input id="txtVPrice" type="text" /></td>
   </tr>
   <tr>
       <td><input id="btnShow" type="button"
       	value="Show updated object" onclick="ShowUpdatedData();"/></td>
       <td><input id="btnAdd" type="button"
       	value="Add vehicle to store" onclick="AddVehicle();"/> </td>
   </tr>
 </table>

Here, I have two input boxes to enter the name and price of the vehicle, and two buttons, one to show the object and other one to add it. Now let's move to the Javascript code:

 var vehicle = {};
 //linking the UI controls with vehicle object
        $(document).ready(function() {
        $(vehicle)
            .linkFrom('Name', '#txtVName', 'val')
            .linkFrom('Price', '#txtVPrice', 'val')
    }); 

Here, I have a global variable vehicle that is linked with the using linkForm method for the plugin as shown above. I have also written the code for adding the data at server, using jQuery Ajax Call as:

 function AddVehicle() {
        var inputs = new Object();
        inputs.vehicle = JSON.stringify(vehicle);
        $.ajax({
            type: "POST",
            url: "AddVehcle.aspx/AdVehicle",
            contentType: "application/json; charset=utf-8",
            data: JSON.stringify(inputs),
            dataType: "json",
            success: ShowStatus,
            error: AjaxFailed
        });
    }
    function ShowStatus(result) {
        alert(result.d);
    }
    function AjaxFailed(result) {
        alert('Ajax failed');
    }

    //to show the state of the object
     function ShowUpdatedData() {
        alert([vehicle.Name, vehicle.Price]);
    }      

Also let's have a look at the server side code:

public partial class AddVehicle : System.Web.UI.Page
{
    public static List<vehicle> lstVehicle = null;
    protected void Page_Load(object sender, EventArgs e)
    {

    }
    //This method adds one vehicle
    [WebMethod()]
    public static string AdVehicle(string vehicle)
    {
        if (lstVehicle == null)
        {
            lstVehicle = new List<vehicle>();
        }
        JavaScriptSerializer ser = new JavaScriptSerializer();
        Vehicle objVehicle = ser.Deserialize<vehicle>(vehicle);
        lstVehicle.Add(objVehicle);
        return "Vehicle added successfully";
    }
}

public class Vehicle
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}

The above code is self-explanatory. AdVehicle() is called to add a vehicle using Ajax call. Now let's run the application. Here I have entered data about one vehicle. Now when I click to see the updated object, ShowUpdatedData then gets to see the vehicle object as below:

vehicleupdated.JPG

Converters

There is also a good feature provided. We may not want to save the data as we show at UI. Like if there is some price or quantity, we may want to format the quantity in some manner before saving. So for that, we can put some converters at the time of linking as:

 $(document).ready(function() {
    $(vehicle)
        .linkFrom('Name', '#txtVName', 'val')
        .linkFrom('Price', '#txtVPrice', 'val',
        //Converter that will be called before updating the underlying object
        function(value) { return value.replace(/[^0-9.]/g, "") }
        );
     }); 

As you can see, I have a converter with Price, that will return only numbers and dot. Let's see it running:

vehicleConverternew.JPG

What it is doing here is that it is taking the value from the textbox converting it with the converter and the setting to property Price of the vehicle object.

Two Way Linking

It also does all the things as above but has one more feature. You can update the object from code also, as soon as the object will get updated that will also be reflected in the UI.

This feature can be very useful in editing/searching feature. You searched some data and now want to update it. Now you can update UI as well as the underlying object, both UI and data will always be in sync.

I have discussed it with one sample.

In my example, let's have a list of person at server. One can fetch the details of an existing person. One also update the existing person or can add a new person.

So I have created one class person as:

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string SSN { get; set; }
    public string Gender { get; set; }
    public string ContactNo { get; set; }
}

My aspx page is as:

<table>
   <tr>
       <td> Name </td>
       <td>
           <input id="txtPersonName" type="text" />
           <input id="Button1" type="button" value="GetPersonDetails"
           onclick="PopulatePersonDetails();"/>
       </td>
   </tr>
   <tr>
       <td colspan="3"> Person Details</td>
   </tr>
   <tr>
       <td>Name</td>
       <td><input id="txtName" type="text" /></td>
   </tr>
   <tr>
       <td>Age</td>
       <td><input id="txtAge" type="text" /></td>
   </tr>
   <tr>
       <td>SSN</td>
       <td><input id="txtSSN" type="text" /></td>
   </tr>
   <tr>
       <td>Gender</td>
       <td><input id="txtGender" type="text" /></td>
   </tr>
   <tr>
       <td>Contact Number</td>
       <td><input id="txtCNo" type="text" /></td>
   </tr>
   <tr>
       <td colspan="2">
           <input id="Button3" type="button" value="Show Updated JS Object"
           onclick="ShowUpdatedData();"/>
           <input id="Button2" type="button" value="Add/Update Person"
           onclick="UpdateorAddData();"/>
       </td>
   </tr>
   </table>

As you can see, in my page, I have put the input boxes for every property of person.

At the start of the page, I have also provided an input box to enter the person name and a button to fetch the requested person from the server.

I have provided two more buttons, one to see the updated objects in JavaScript alert and another one to update the data at the server. It actually looks at the list for the SSN if it found then updates the existing record else adds the new person. We'll see the code in a moment. Now let's move the Javascript code that is written. The code is used to link the data. First, I have declared one global object that object will be linked to the UI controls as:

var person = {}; 

and the code for linking the data is:

//Linking the controls from the object
 $(document).ready(function()
    {
        $(person)
        .linkBoth('Name','#txtName','val')
        .linkBoth('Age','#txtAge','val')
        .linkBoth('SSN','#txtSSN','val')
        .linkBoth('Gender','#txtGender','val')
        .linkBoth('ContactNo','#txtCNo','val');
    });

As from the above, you can see that person object is used and linked using linkBoth method, which takes three parameters, first the name of the property of the object, second the id of the control with sign # third val Now, after this, you don't need to worry about the data, all things will be taken care of by the plugin itself. Rest JavaScript method, I have used:

 // To fetch the detail from the server of the entered person name
 function PopulatePersonDetails() {

        var inputs = new Object();
        inputs.name = document.getElementById('txtPersonName').value;

        $.ajax({
            type: "POST",
            url: "EditPerson.aspx/GetPerson",
            contentType: "application/json; charset=utf-8",
            data: JSON.stringify(inputs),
            dataType: "json",
            success: AjaxSucceeded,
            error: AjaxFailed
        });

        // To be called when ajax call succeeded
        //If no object will be found, it'll show an error message as
        //'Person Not found' else call update the person object
         function AjaxSucceeded(result) {
            if (result.d == 'null')
                alert('Person Not found');
            else
                $(person).attr(JSON.parse(result.d));
        }

        //Will be called, if ajax call gets failed somehow.
        function AjaxFailed(result) {
            alert('Ajax failed');
        }
    }

For the functionality of the updating or adding the person object at server, we have the following methods:

//This function get the global variable person object
//which is always sync with UI and sends it
//to server to add/update
function UpdateorAddData() {

    var inputs = new Object();
    inputs.person = JSON.stringify(person);
    $.ajax({
        type: "POST",
        url: "EditPerson.aspx/AddUpdatePerson",
        contentType: "application/json; charset=utf-8",
        data: JSON.stringify(inputs),
        dataType: "json",
        success: ShowStatus,
        error: AjaxFailed
    });
    
    }
    
    //This function is to show the status whether a new person is added or updated
     function ShowStatus(result) {
        alert(result.d);
    }        

As I have linked the object to the UI controls, I am just picking or updating the person object, that always gives the most updated and synced data. Also let's have a look at the server side code:

public partial class EditPerson : System.Web.UI.Page
{
    public static List<person> lstPerson = null;
    protected void Page_Load(object sender, EventArgs e)
    {
    }

    //This method will return the searched person.
    [WebMethod()]
    public static string GetPerson(string name)
    {
        InitializePersons();
        JavaScriptSerializer ser = new JavaScriptSerializer();
        // ser.Serialize(persons);
        return ser.Serialize(lstPerson.Find(p => p.Name == name));
    }

    //This method will add or update a person based on SSN
    [WebMethod()]
    public static string AddUpdatePerson(string person)
    {
        string status;
        JavaScriptSerializer ser = new JavaScriptSerializer();
        Person obj = ser.Deserialize<person>(person);
        InitializePersons();
        Person per = lstPerson.Find(p => p.SSN == obj.SSN);
        if (per == null)
        {
            lstPerson.Add(obj);
            status = "New person added";
        }
        else
        {
            // Updating the person
            lstPerson.Remove(per);
            lstPerson.Add(obj);
            status = "Person updated";
        }

        // ser.Serialize(persons);
        return status;
    }

    public static void InitializePersons()
    {
        if (lstPerson == null)
        {
            lstPerson = new List<person>()
            {
                new Person { Age = 27, Name= "Brij",
                Gender="Male", ContactNo="123456789",
                SSN="CC123456"},
                new Person { Age = 18, Name = "Ravi",
                Gender = "Male", ContactNo = "987654321",
                SSN="AB654321"}
            };
        }
    }
}

Now let's see the running application, I have a few person data at server. When I am entering and clicking for getting the person details, UI gets updated, while actually I am making an Ajax call to get the person data and updating the underlying object as discussed in above code.

personadded.JPG

Rest things are as per the Vehicle Store example.

I have also to add a button, which one can click to see the state of the person object at any point of time, when one wants.

Please find the full sample in the attachment.

Conclusion

I found this feature very useful, while using Ajax and jQuery as I discussed in the above example. One should go for the one way or two way linking based on their requirements.

Feedback and Suggestions

Hope you all must have enjoyed my above article. Please share your valuable feedback, that will help me a lot to write better articles.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here