RISE to Bloome Software
Log In    
Home
RISE
Collapse RISERISE
Overview
Product feature list
Expand RISE Visual ModelingRISE Visual Modeling
How to get started
Expand Information ModelingInformation Modeling
Expand Interface ModelingInterface Modeling
Collapse Code generatorsCode generators
Expand Application DevelopmentApplication Development
Expand CustomizationCustomization
Philosophy of RISE
Expand User CommunityUser Community
Marshal
Download
 
 
r2bsoftware.se r2bsoftware.se
 
 
 
Click to hide navigation tree

AJAX code generator

The RISE AJAX code generator renders JavaScript source code, that uses jQuery, for accessing your JSON enabled web services in your Rich Internet Applications or AJAX applications. The generated code implements JavaScript functions corresponding to the information interfaces specified in the RISE model. If you are new to RISE, please read more in the RISE Resource Center and if you haven't done so yet, download RISE it's Free!
 

The source code from the code generator is compliant with any JSON enabled web service, .NET as well as PHP, generated from the same RISE model, i.e. it works with the output from the RISE C#, RISE PHP for MySQL and RISE PHP for PostgreSQL code generators.

All methods, arguments and return values in the generated code are named in accordance with the RISE model and its naming convention

AJAX Code Generator
 

Create an AJAX application

 
When creating an AJAX application using RISE you follow these steps.
  1. Model your solution in the RISE Editor.
  2. Generate your database using a database code generator.
  3. Generate your web service application layer using an application code generator.
  4. Use the AJAX code generator to generate JavaScript functions to access your application layer from your RIA application / AJAX application.

Hello World Sample Application

Create a new model in the RISE Editor and call it Hello World. This example is created using the Hello World template model. Select the top node in the project tree. Enter the prefix hello in the property grid in the bottom right of the RISE Editor.
 
We start by adding the entities, attributes and relations needed for our application. When generating the database, entities are mapped to tables and attributes are mapped to columns. Read more in the article Information Modeling.
 
Hello World Entities, Attributes and relations
 
 
We now add a view to "flatten out" the structure. Read more in the article Working with views. When generating your database, a view is mapped to a database view.
 
 
Hello World model with View
 
 
Finally we add an interface to our model. When generating your application layer, one web service per interfaces is generated, implementing the methods defined in the interface. Read more in the article Interface Modeling.
 
 
Hello World model with Interface
 
 

Generate AJAX Code

The AJAX code generator renders one JavaScript file per interface in your RISE model. The generated code uses jQuery to access the JSON web services.
 
JSON web services produce slightly different result, and expect slighly differenly formatted arguments depending on the web service environment, .NET or PHP. You can read more about this in the application code generator articles, i.e. in the RISE C# for ODBC, RISE PHP for MySQL and RISE PHP for PostgreSQL code generator articles. The generated AJAX code contains a helper class, handling the differences in the environments, making the generated JavaScript code behave identical independent of the web service environment.
 
This is what the generated JavaScript code would look like for the Hello World template model. As you can see, the args parameter is passed back to the callback functions, i.e. onsuccess, onerror and oncomplete. This enables you to use args as your execution context. Args must of course contain the arguments that the web service method expects, but besides that, args can contain any objects you wish.

var IHelloWorld = {
    wsuri: "hello.WS.IHelloWorld.asmx",   // You must enter the correct uri to your installed web service.
    wsenvironment: ".NET",                     // Possible values null, ".NET", "PHP"
    NewCountry: function (args, onsuccess, onerror, oncomplete) {
        $.ajax({
            type: "POST",
            url: IHelloWorld.wsuri + "/NewCountry",
            data: IHelloWorld.JSONHelper.SerializeArgs({ "Name": args["Name"]}),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function(response) {
                if (onsuccess){
                    switch(IHelloWorld.JSONHelper.WSEnv()){
                        case ".NET":
                            onsuccess(response.d, args);
                        break;
                        case "PHP":
                            onsuccess(response, args);
                        break;
                        default:
                            throw new Exception("Unknown target environment");
                        break;
                    }
                }
            },
            error: function(x, msg) {
                if (onerror) onerror(x, msg, args);
            },
            complete: function() {
                if (oncomplete) oncomplete(args);
            }
        });
    },
    DeleteCountry: function (args, onsuccess, onerror, oncomplete) {
        $.ajax({
            type: "POST",
            url: IHelloWorld.wsuri + "/DeleteCountry",
            data: IHelloWorld.JSONHelper.SerializeArgs({ "ID": args["ID"]}),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function(response) {
                if (onsuccess){
                    onsuccess(args);
                }
            },
            error: function(x, msg) {
                if (onerror) onerror(x, msg, args);
            },
            complete: function() {
                if (oncomplete) oncomplete(args);
            }
        });
    },
    GetCountry: function (args, onsuccess, onerror, oncomplete) {
        $.ajax({
            type: "POST",
            url: IHelloWorld.wsuri + "/GetCountry",
            data: IHelloWorld.JSONHelper.SerializeArgs({ "ID": args["ID"]}),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function(response) {
                if (onsuccess){
                    var result = null;
                    switch(IHelloWorld.JSONHelper.WSEnv()){
                        case ".NET":
                            result = response.d;
                        break;
                        case "PHP":
                            result = response;
                        break;
                        default:
                            throw new Exception("Unknown target environment");
                        break;
                    }
                    onsuccess(result, args);
                }
            },
            error: function(x, msg) {
                if (onerror) onerror(x, msg, args);
            },
            complete: function() {
                if (oncomplete) oncomplete(args);
            }
        });
    },
    SetCountry: function (args, onsuccess, onerror, oncomplete) {
        $.ajax({
            type: "POST",
            url: IHelloWorld.wsuri + "/SetCountry",
            data: IHelloWorld.JSONHelper.SerializeArgs({ "ID": args["ID"], "Name": args["Name"]}),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function(response) {
                if (onsuccess){
                    onsuccess(args);
                }
            },
            error: function(x, msg) {
                if (onerror) onerror(x, msg, args);
            },
            complete: function() {
                if (oncomplete) oncomplete(args);
            }
        });
    },
    ListCountry: function (args, onsuccess, onerror, oncomplete) {
        $.ajax({
            type: "POST",
            url: IHelloWorld.wsuri + "/ListCountry",
            data: IHelloWorld.JSONHelper.SerializeArgs({ "maxRowsToReturn": args["maxRowsToReturn"] || null}),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function(response) {
                if (onsuccess){
                    var results = null;
                    switch(IHelloWorld.JSONHelper.WSEnv()){
                        case ".NET":
                            results = response.d;
                        break;
                        case "PHP":
                            results = response;
                        break;
                        default:
                            throw new Exception("Unknown target environment");
                        break;
                    }
                    onsuccess(results, args);
                }
            },
            error: function(x, msg) {
                if (onerror) onerror(x, msg, args);
            },
            complete: function() {
                if (oncomplete) oncomplete(args);
            }
        });
    },
    NewHello: function (args, onsuccess, onerror, oncomplete) {
        $.ajax({
            type: "POST",
            url: IHelloWorld.wsuri + "/NewHello",
            data: IHelloWorld.JSONHelper.SerializeArgs({ "Phrase": args["Phrase"], "Language": args["Language"], "CountryID": args["CountryID"]}),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function(response) {
                if (onsuccess){
                    switch(IHelloWorld.JSONHelper.WSEnv()){
                        case ".NET":
                            onsuccess(response.d, args);
                        break;
                        case "PHP":
                            onsuccess(response, args);
                        break;
                        default:
                            throw new Exception("Unknown target environment");
                        break;
                    }
                }
            },
            error: function(x, msg) {
                if (onerror) onerror(x, msg, args);
            },
            complete: function() {
                if (oncomplete) oncomplete(args);
            }
        });
    },
    DeleteHello: function (args, onsuccess, onerror, oncomplete) {
        $.ajax({
            type: "POST",
            url: IHelloWorld.wsuri + "/DeleteHello",
            data: IHelloWorld.JSONHelper.SerializeArgs({ "ID": args["ID"]}),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function(response) {
                if (onsuccess){
                    onsuccess(args);
                }
            },
            error: function(x, msg) {
                if (onerror) onerror(x, msg, args);
            },
            complete: function() {
                if (oncomplete) oncomplete(args);
            }
        });
    },
    GetHello: function (args, onsuccess, onerror, oncomplete) {
        $.ajax({
            type: "POST",
            url: IHelloWorld.wsuri + "/GetHello",
            data: IHelloWorld.JSONHelper.SerializeArgs({ "ID": args["ID"]}),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function(response) {
                if (onsuccess){
                    var result = null;
                    switch(IHelloWorld.JSONHelper.WSEnv()){
                        case ".NET":
                            result = response.d;
                        break;
                        case "PHP":
                            result = response;
                        break;
                        default:
                            throw new Exception("Unknown target environment");
                        break;
                    }
                    onsuccess(result, args);
                }
            },
            error: function(x, msg) {
                if (onerror) onerror(x, msg, args);
            },
            complete: function() {
                if (oncomplete) oncomplete(args);
            }
        });
    },
    SetHello: function (args, onsuccess, onerror, oncomplete) {
        $.ajax({
            type: "POST",
            url: IHelloWorld.wsuri + "/SetHello",
            data: IHelloWorld.JSONHelper.SerializeArgs({ "ID": args["ID"], "Phrase": args["Phrase"], "Language": args["Language"], "CountryID": args["CountryID"], "IsOfficial": args["IsOfficial"]}),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function(response) {
                if (onsuccess){
                    onsuccess(args);
                }
            },
            error: function(x, msg) {
                if (onerror) onerror(x, msg, args);
            },
            complete: function() {
                if (oncomplete) oncomplete(args);
            }
        });
    },
    ListHello: function (args, onsuccess, onerror, oncomplete) {
        $.ajax({
            type: "POST",
            url: IHelloWorld.wsuri + "/ListHello",
            data: IHelloWorld.JSONHelper.SerializeArgs({ "maxRowsToReturn": args["maxRowsToReturn"] || null}),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function(response) {
                if (onsuccess){
                    var results = null;
                    switch(IHelloWorld.JSONHelper.WSEnv()){
                        case ".NET":
                            results = response.d;
                        break;
                        case "PHP":
                            results = response;
                        break;
                        default:
                            throw new Exception("Unknown target environment");
                        break;
                    }
                    onsuccess(results, args);
                }
            },
            error: function(x, msg) {
                if (onerror) onerror(x, msg, args);
            },
            complete: function() {
                if (oncomplete) oncomplete(args);
            }
        });
    },
    ListHelloByCountry: function (args, onsuccess, onerror, oncomplete) {
        $.ajax({
            type: "POST",
            url: IHelloWorld.wsuri + "/ListHelloByCountry",
            data: IHelloWorld.JSONHelper.SerializeArgs({ "maxRowsToReturn": args["maxRowsToReturn"] || null, "CountryID": args["CountryID"]}),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function(response) {
                if (onsuccess){
                    var results = null;
                    switch(IHelloWorld.JSONHelper.WSEnv()){
                        case ".NET":
                            results = response.d;
                        break;
                        case "PHP":
                            results = response;
                        break;
                        default:
                            throw new Exception("Unknown target environment");
                        break;
                    }
                    onsuccess(results, args);
                }
            },
            error: function(x, msg) {
                if (onerror) onerror(x, msg, args);
            },
            complete: function() {
                if (oncomplete) oncomplete(args);
            }
        });
    },
    HelloWorld: function (args, onsuccess, onerror, oncomplete) {
        $.ajax({
            type: "POST",
            url: IHelloWorld.wsuri + "/HelloWorld",
            data: IHelloWorld.JSONHelper.SerializeArgs({ "maxRowsToReturn": args["maxRowsToReturn"] || null, "languageFilter": args["languageFilter"]}),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function(response) {
                if (onsuccess){
                    var results = null;
                    switch(IHelloWorld.JSONHelper.WSEnv()){
                        case ".NET":
                            results = response.d;
                        break;
                        case "PHP":
                            results = response;
                        break;
                        default:
                            throw new Exception("Unknown target environment");
                        break;
                    }
                    onsuccess(results, args);
                }
            },
            error: function(x, msg) {
                if (onerror) onerror(x, msg, args);
            },
            complete: function() {
                if (oncomplete) oncomplete(args);
            }
        });
    },
    JSONHelper: {
        SerializeArgs: function (args) {
            var s = [];
            if (args) for (var m in args) s[s.length] = '"' + m + '":' + (typeof(args[m]) == 'undefined' || args[m] == null ? 'null' : (typeof(args[m]) == 'string' ? '"' + args[m] + '"' : args[m].toString()));
            return '{' + s.join(',') + '}';
        },
        WSEnv: function () {
                return (IHelloWorld.wsenvironment && (IHelloWorld.wsenvironment == ".NET" || IHelloWorld.wsenvironment == "PHP") ? IHelloWorld.wsenvironment : (IHelloWorld.wsuri ? (IHelloWorld.wsuri.toLowerCase().match(".asmx$") == ".asmx" ? ".NET" : (IHelloWorld.wsuri.toLowerCase().match(".php$") == ".php" ? "PHP" : "UNKNOWN")) : "UNKNOWN"));
        },
        DateToString: function (date) {
            if(date){
                switch(IHelloWorld.JSONHelper.WSEnv()) {
                    case ".NET":
                    case "PHP":
                    {
                        var pad = function (val) {
                            val = val.toString();
                            while (val.length < 2) val = "0" + val;
                            return val;
                        };
                        return (date ? date.getFullYear() + '-' + pad((date.getMonth()+1)) + '-' + pad(date.getDate()) + 'T' + pad(date.getHours()) + ':' + pad(date.getMinutes()) + ':' + pad(date.getSeconds()) : null);
                    }
                    default:
                        throw new Exception("Unknown target environment");
                }
            }
            return "null";
        },
        StringToDate: function (datestring) {
            if(datestring){
                switch(IHelloWorld.JSONHelper.WSEnv()) {
                    case ".NET":
                        return eval('new '+ datestring.replace(/\//g,' '));
                    case "PHP":
                    {
                        var num = function(val, fb) {
                            return (val && val!='' ? parseInt(val,10) : (fb ? fb : 0));
                        };
                        var m = datestring.match(/^\s*((\d\d\d\d)-(\d\d)-(\d\d))((\s|T)(\d\d)(:(\d\d)(:(\d\d))?)?)?\s*$/i);
                        return new Date(num(m[2]), num(m[3])-1, num(m[4]), num(m[7]), num(m[9]), num(m[11]));
                    }
                }
            }
            return null;
        }
    }
}

Generate Sample Code

The AJAX code generator can generate sample code showing how to call the generated functions from your JavaScript code. You should not implement your code in the generated files since if you update your model and generate the new version, your code will be lost.
 
In the sample code below, you should of course replace "your_string", "your_int" etc. with your variables or constants.

/*
    // This code exemplifies how to call the generated function NewCountry
    IHelloWorld.NewCountry(
        {"Name": your_string},
        function(result, args){
            // This function is called on success
            // result is an integer (the primary key) identifying the inserted row
        },
        function(x, msg, args){
            // This function is called on error
        },
        function(args){
            // This function is called after onsuccess/onerror
        }
    );
*/
/*
    // This code exemplifies how to call the generated function DeleteCountry
    IHelloWorld.DeleteCountry(
        {"ID": your_int},
        function(args){
            // This function is called on success
        },
        function(x, msg, args){
            // This function is called on error
        },
        function(args){
            // This function is called after onsuccess/onerror
        }
    );
*/
/*
    // This code exemplifies how to call the generated function GetCountry
    IHelloWorld.GetCountry(
        {"ID": your_int},
        function(result, args){
            // This function is called on success
            // result contains: ID (int), Name (string)
            // Example:
            var yourVariable1 = result["ID"];
            var yourVariable2 = result["Name"];
        },
        function(x, msg, args){
            // This function is called on error
        },
        function(args){
            // This function is called after onsuccess/onerror
        }
    );
*/
/*
    // This code exemplifies how to call the generated function SetCountry
    IHelloWorld.SetCountry(
        {"ID": your_int, "Name": your_string},
        function(args){
            // This function is called on success
        },
        function(x, msg, args){
            // This function is called on error
        },
        function(args){
            // This function is called after onsuccess/onerror
        }
    );
*/
/*
    // This code exemplifies how to call the generated function ListCountry
    IHelloWorld.ListCountry(
        {"maxRowsToReturn": your_int_or_null},
        function(results, args){
            // This function is called on success
            // results contains: ID (int), Name (string)
            // Example:
            for (var i=0; i<results.length; i++) {
                var yourVariable1 = results[i]["ID"];
                var yourVariable2 = results[i]["Name"];
            }
        },
        function(x, msg, args){
            // This function is called on error
        },
        function(args){
            // This function is called after onsuccess/onerror
        }
    );
*/
/*
    // This code exemplifies how to call the generated function NewHello
    IHelloWorld.NewHello(
        {"Phrase": your_string, "Language": your_string, "CountryID": your_int},
        function(result, args){
            // This function is called on success
            // result is an integer (the primary key) identifying the inserted row
        },
        function(x, msg, args){
            // This function is called on error
        },
        function(args){
            // This function is called after onsuccess/onerror
        }
    );
*/
/*
    // This code exemplifies how to call the generated function DeleteHello
    IHelloWorld.DeleteHello(
        {"ID": your_int},
        function(args){
            // This function is called on success
        },
        function(x, msg, args){
            // This function is called on error
        },
        function(args){
            // This function is called after onsuccess/onerror
        }
    );
*/
/*
    // This code exemplifies how to call the generated function GetHello
    IHelloWorld.GetHello(
        {"ID": your_int},
        function(result, args){
            // This function is called on success
            // result contains: ID (int), Phrase (string), Language (string), CountryID (int), IsOfficial (bool)
            // Example:
            var yourVariable1 = result["ID"];
            var yourVariable2 = result["Phrase"];
            var yourVariable3 = result["Language"];
            var yourVariable4 = result["CountryID"];
            var yourVariable5 = result["IsOfficial"];
        },
        function(x, msg, args){
            // This function is called on error
        },
        function(args){
            // This function is called after onsuccess/onerror
        }
    );
*/
/*
    // This code exemplifies how to call the generated function SetHello
    IHelloWorld.SetHello(
        {"ID": your_int, "Phrase": your_string, "Language": your_string, "CountryID": your_int, "IsOfficial": your_bool},
        function(args){
            // This function is called on success
        },
        function(x, msg, args){
            // This function is called on error
        },
        function(args){
            // This function is called after onsuccess/onerror
        }
    );
*/
/*
    // This code exemplifies how to call the generated function ListHello
    IHelloWorld.ListHello(
        {"maxRowsToReturn": your_int_or_null},
        function(results, args){
            // This function is called on success
            // results contains: ID (int), Phrase (string), Language (string), CountryID (int), IsOfficial (bool)
            // Example:
            for (var i=0; i<results.length; i++) {
                var yourVariable1 = results[i]["ID"];
                var yourVariable2 = results[i]["Phrase"];
                var yourVariable3 = results[i]["Language"];
                var yourVariable4 = results[i]["CountryID"];
                var yourVariable5 = results[i]["IsOfficial"];
            }
        },
        function(x, msg, args){
            // This function is called on error
        },
        function(args){
            // This function is called after onsuccess/onerror
        }
    );
*/
/*
    // This code exemplifies how to call the generated function ListHelloByCountry
    IHelloWorld.ListHelloByCountry(
        {"maxRowsToReturn": your_int_or_null, "CountryID": your_int},
        function(results, args){
            // This function is called on success
            // results contains: ID (int), Phrase (string), Language (string), CountryID (int), IsOfficial (bool)
            // Example:
            for (var i=0; i<results.length; i++) {
                var yourVariable1 = results[i]["ID"];
                var yourVariable2 = results[i]["Phrase"];
                var yourVariable3 = results[i]["Language"];
                var yourVariable4 = results[i]["CountryID"];
                var yourVariable5 = results[i]["IsOfficial"];
            }
        },
        function(x, msg, args){
            // This function is called on error
        },
        function(args){
            // This function is called after onsuccess/onerror
        }
    );
*/
/*
    // This code exemplifies how to call the generated function HelloWorld
    IHelloWorld.HelloWorld(
        {"maxRowsToReturn": your_int_or_null, "languageFilter": your_string},
        function(results, args){
            // This function is called on success
            // results contains: ID (int), Name (string), HelloID (int), HelloPhrase (string), HelloLanguage (string), HelloIsOfficial (bool)
            // Example:
            for (var i=0; i<results.length; i++) {
                var yourVariable1 = results[i]["ID"];
                var yourVariable2 = results[i]["Name"];
                var yourVariable3 = results[i]["HelloID"];
                var yourVariable4 = results[i]["HelloPhrase"];
                var yourVariable5 = results[i]["HelloLanguage"];
                var yourVariable6 = results[i]["HelloIsOfficial"];
            }
        },
        function(x, msg, args){
            // This function is called on error
        },
        function(args){
            // This function is called after onsuccess/onerror
        }
    );
*/
 
Below is a simple html page using the generated function HelloWorld to list phrases based on a language filter. Setting maxRowsToReturn to null means that we want to return all matching rows. Note that we have included the jQuery API and the generated JavaScript file IHelloWorld.js.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
    <head>
        <title>Hello World</title>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
        <script type="text/javascript" src="IHelloWorld.js"></script>
        <script type="text/javascript">
      function OnHello() {
                // This code exemplifies how to call the generated function HelloWorld
                IHelloWorld.HelloWorld(
                    {"maxRowsToReturn": null, "languageFilter": document.getElementById("languageFilter").value},
                    function(results, args){
                        // This function is called on success
                        // results contains: ID (int), Name (string), HelloID (int), HelloPhrase (string), HelloLanguage (string), HelloIsOfficial (bool)
                        if(results && results[0])
                        {
                            var htm = "<table cellpadding=\"10\" cellspacing=\"10\" border=\"1\">";
                            var h = [];
                            for (var m in results[0]) h[h.length] = m;
                            htm += "<tr><td>" + h.join("</td><td>") + "</td></tr>";
                            for (var i = 0; i < results.length; i++) {
                                var r = [];
                                for (var m in results[i]) r[r.length] = (results[i][m] == null ? 'null' : results[i][m].toString());
                                htm += "<tr><td>" + r.join("</td><td>") + "</td></tr>";
                            }
                            htm += "</table>";
                            document.getElementById("result").innerHTML = htm;
                        }
                    },
                    function(x, msg, args){
                        // This function is called on error
                        document.getElementById("result").innerHTML = msg;
                    },
                    function(args){
                        // This function is called after onsuccess/onerror
                    }
                );
            }
        </script>
    </head>
    <body>
        <table>
            <tr>
                <td>Language Filter</td>
                <td>Execute</td>
            </tr>
            <tr>
                <td><input id="languageFilter" type="text" value="%" /></td>
                <td><input id="executeButton" type="button" value="Execute" onclick="OnHello()"/></td>
            </tr>
        </table>
        <div id="result"></div>
    </body>
</html>
 

Code generator settings

You may change the settings prior to generating code. It's also possible to store the settings as your default settings. The default settings are automatically used when generating code inside the RISE Editor or from a command-line

The AJAX code generator has the following properties:
wsEnvironment Specify the environment under which the web servises run, i.e. .NET or PHP.
generateSample Specify whether sample code illustrating how the generated methods can be called should be generated.
supportTicket If this flag is set, code is generated for passing a ticket to the web service methods for authentication.
userLogin If this flag is set, code is generated for passing a userid and password to the web service methods for authentication.

jQuery

The generated code uses jQuery to access the web services. This means that you must include the jQuery library in your applications. You can either download the API to your server or access it online, e.g.
 
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
 
Read more about jQuery.