DOC

Partial rendering control using JQuery

By Crystal Perez,2014-05-25 08:18
6 views 0
In the last few years is very common work on n-layer web application where the front end is represented by an ASP.net website that talk with the layer below where, in a SOA context, one layer is usually represented by either WebServices or WCF to expose all the functionality using a standard completely decouple from the consumer. In the last few years the necessity to query the services using an asynchronous way is getting a key of a well done web application to avoid to refresh all the page against HTTP requests especially when we need to refresh only a portion of the web page(Partial Rendering).JQuery is getting the standard to do this job allowing the front end to post and get data using JSON format. Unfortunately in my experience to achieve this behavior I saw so many bad things first of all web services that returns HTML against a jquery call to have partial rendering. For my point of view webservice/WCF must return always either POCO objects or JSON, in the case we are querying it using JQUERY but never HTML.Some other solution are based on some kind of client side "template" that are going to be filled up by a client script using Jquery or javascript. With this solution against any change on the front end we have to change the template and probabily the login to bind it with the JSON response. In this article I'm going to show a good way to do partial rendering using a custom control that can used in the web page without dealing with JQuery at all!

This article show a web custom control that allows partial rendering using JQuery

    ? Download JqueryControl.zip - 44.73 KB

    Introduction

    In the last few years is very common work on n-layer web application where the front end is represented by an ASP.net website that talk with the layer below where, in a SOA context, one layer is usually represented by either WebServices or WCF to expose all the functionality using a standard completely decouple from the consumer. In the last few years the necessity to query the services using an asynchronous way is getting a key of a well done web application to avoid to refresh all the page against HTTP requests especially when we need to refresh only a portion of the web page(Partial Rendering).JQuery is getting the standard to do this job allowing the front end to post and get data using JSON format. Unfortunately in my experience to achieve this behavior I saw so many bad things first of all web services that returns HTML against a jquery call to have partial rendering. For my point of view webservice/WCF must return always either POCO objects or JSON, in the case we are querying it using JQUERY but never HTML.Some other solution are based on some kind of client side

    "template" that are going to be filled up by a client script using Jquery or javascript. With this solution against any change on the front end we have to change the template and probabily the login to bind it with the JSON response. In this article I'm going to show a good way to do partial rendering using a custom control that can used in the web page without dealing with JQuery at all!

    How it works

    First of all we have to create a web site project . After that we have to add the JQueryControllor on the toolbox bar clicking on choose items and selecting JqueryController.dll.

    Basically this control inherits from the Panel web control and it's going to work as container for the portion of the page we want to refresh(more or less the same behaviour of the AJAX update panel).Each JaqueyControll must contains at most one web user control (.ascx) that represent the portion of the page that is going to be refreshed.If you need refresh more then on section you just need add more then one

    JqueryControll each one with their web user control.The key concept of this solution is instead of call a web service using Jquery to bind the JSON response to the interface, it does a post to a web page passing any parameter we need on the server side to satisfy the request. On the page (that must inherits from PageBase that is explained later) you can find already filled up a collection with all the parameters you post.Thus you have everything you need on the server side to satisfy the request.Then you just need call Refresh method on the JqueryController to refresh the interface on the client side with out deal with Jquery or javascript! If you need you can also provide a Javascript call back function that is going to be called after the refresh bringing back also any parameters you may need to inizialize again the web form  or for any other reasons.Below you can see the Sequence diagram of that process.

    As you can see on the diagam the process it very similar to a classic Asp.net postback but instead of render back the wole page it calls a method on JqueryControll that return just the portion of the HTML that has to be refreshed

    In this example we got a web page that contains GridView that is bounded to a datasource. The user

    wants add one record to this datasource(an employee in this case) and then we have to refresh the GridView to update the result.The web form should look like the one below:

    All the process starts by call a specil javascript function that is going to start the process. That function is showed below:

    function JqueryPost() {

     var argv = JqueryPost.arguments;

     var argc = argv.length;

     var strParms=new String()

     page = argv[0];

     for (var i = 1; i < argc; i++) {

     strParms += argv[i] + '&'

     }

     strParms = strParms.substr(0, strParms.length - 1);

     $.post(page, { __parameters: strParms },

     function(data){

     jQuery.globalEval(data);

     });

     }

    This is the javascript code we have to add to the control we want make as trigger. In this case is a button click of an asp:Button.By requirement if we use a serevr control, like in this example, we have to add "return false" after the call to avoid a post back

    Collapse

    onclientclick="JqueryPost('default.aspx','action=add');return false">

    By Requirement that function can accept any parameters that we could need on server side to satisfy the request(for exapmple could be a selected item of a drop down list). The firts parameter must be the page where we want to post the data to.

    As you can see this function use the Jquery Post method that post the web form to the page whit all the parameters we have included into the call.Then the function execute the jquery code that come back from the request that contains the JQuery code to inject the HTML we want refresh. On the server side the PageBase is going to do all the work:

    -it get the parameter from the request

    -create the html to send back to the client

    -add the jquery code to inject that Html

    -call the javascript call back function if there is one

    -it ends the response to send back just the HTML that has to be refreshed Below there is showed the PageBase code. The are two main point I would like to focus : the function that create the HTML and the one that return the Jquery to inject that HTML Below you can see the function that create the HTML to be rendered:

     public static string RenderUserControl(Control crtl)

     {

     Control control = null;

     const string STR_BeginRenderControlBlock = "";

     const string STR_EndRenderControlBlock = "";

     StringWriter tw = new StringWriter();

     Page page = new Page();

     page.EnableViewState = false;

     HtmlForm form = new HtmlForm();

     form.ID = "__temporanyForm";

     page.Controls.Add(form);

     form.Controls.Add(new LiteralControl(STR_BeginRenderControlBlock));

     form.Controls.Add(crtl);

     form.Controls.Add(new LiteralControl(STR_EndRenderControlBlock));

     HttpContext.Current.Server.Execute(page, tw, true);

     string Html = tw.ToString();

     //TO DO:clean the response!!!!!

     int start = Html.IndexOf("");

     int end = Html.Length - start;

     Html = Html.Substring(start,end);

     return Html;

     }

    This function get in input the user control that we want render back(in this case the user control that contains the gridview) and generate at runtime the HTML. First it dynamically creates a new Web Page instance then add the control passed in input to the page.Then the controll will be added to that page. After that using server.execute we it execute the page end return the HTML of it but having just the control we want to refresh on that page it return just that HTML.

    At this point we could think that everything is done but we just miss thr Jquery code that injects that HTML into the page and where(the container) it has to be injected.

    Below is showed the fucntion to do that:

     public void AddToRender(string PaneldId, string htmlToAdd)

     {

     this.ResponseToRender.Append("$('#" + PaneldId + "').html('" +

    htmlToAdd + "');");

     }

    After this call the page return just the Jquery code that inject the HTML on the page. On the client side that code is execute by the function we call at the begin of the process (JqueryPost) and the page will be refreshed.

    All this stuff encampsulated into the JqueryController and the PageBase. All we need is call the JqueryController.Refresh() method to have partial rendering! That method accept also a callback function that get a list of parameter and a name of a JavaScript function we could need after the render to do something more on the client side(for example select an item on a drop down list).Now we are going through the page's code to understand how we can use that control. As we said at the begin everything starts by handling a client event (in this case a button click) that has to call the JquryPost() function.This call does a post to the server so that let's move the focus on the page.

using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Web;

    using System.Web.UI;

    using System.Web.UI.WebControls;

    using JqueryController;

public partial class _Default : PageBase

    {

     Employee emp = new Employee();

     protected void Page_Load(object sender, EventArgs e)

     {

     if (this.IsPartialRendering)

     {

     if (this.PostParameter.ContainsKey("action")) {

     string action = this.PostParameter["action"];

     switch (action) {

     case "add":

     emp.AddOneEmployee();

     break;

     case "remove":

     emp.RemoveTheLastEmployee();

     break;

     }

     BindDataGrid(emp.GetAllEmployee());

     }

     if (this.PostParameter.ContainsKey("selectedId"))

     {

     int selectedId = int.Parse(this.PostParameter["selectedId"]);

     SelectEmployees(selectedId);

     }

     }

     }

     private void BindDataGrid(IEnumerable datasource) {

     GridUserControl1.GridDetails.DataSource = datasource;

     GridUserControl1.GridDetails.DataBind();

     JqueryControllerGrid.RefreshPanel("parameterBack");

     }

     private void SelectEmployees(int selectedId) {

     switch(selectedId){

     case 0:

     BindDataGrid(emp.GetAllEmployee());

     break;

     case 1:

     BindDataGrid(emp.GetAllEmployee().Where(x =>x.ID > 30));

     break;

     case 2:

     BindDataGrid(emp.GetAllEmployee().Where(x => x.ID < 30));

     break;

     }

     }

}

    As you can see on the page load we have a new method called IsPartialRendering that allow the developer to understand if the post was raised from a JqueryControl.Thus after checking if is a partial rendering post we can understand what kind of operation we want perform getting the parameters we sent along the http post. To do that we can access PostParameter collection. In this example we post a parameter named "Action" that contains the action we want perform(in this case add or remove and employ). After that we are able to call the right function to perform the action

    required.In this example we just call a method on the page that insert or delete the employee but on a real context we could call a WCF or what ever there is below the frond end layer on our architecture. The good point is that if our front-end is based on MCV or MVP we can carry on to use that patterns because we are just posting data to the page as a classic post back but we don't by-pass any layer as you could do calling for example a Service layer with out pass through all the layers between the fron end end the service layer itself.Anyway let't focus on the example.After know what action we have to perfom we are able to call the function that add or remove and employee. At this point all we need to do is bind again the datagrid to the datasource and call JqueryContorl.Refresh() to update the interface.In this example we want call a callback funtion on the client side passing a string "parameterBack". We can see that after that call the datagrid has been refreshed and the call back function has been called showing the paramater we sent back.Below you can see the callBack funtion that is contained on the page:

     function showParams() {

     alert(showParams.arguments[0]);

     }

Points of Interest

     I think that is a good way to do partial rendering with out change anything on our architecture expecially when we use patterns as MVP/MVC. The scope of this article is just show a easy way to do it without deal with client page template or complex Jquery call.It's also easy to maintain because you can use a user control approach to design your interface instead of do it dynamically on the client side. Probabily this is not the best way to do that but for sure it's quite elegant and easy to use.

Report this document

For any questions or suggestions please email
cust-service@docsford.com