One of the key features of the Rico LiveGrid is its ability to load data dynamically via AJAX. This document focuses on the format of the LiveGrid AJAX requests and responses. More specifically, it is the LiveGrid Buffer object that is generating requests and processing responses. So if you are in a situation where data is coming from a web service that is out of your control, you could create a custom LiveGrid buffer class that would serve as an interface between the web service and LiveGrid. However, in this document we will focus on the request and response formats of the buffer classes that come with the Rico distribution.
The Rico distribution includes 4 distinct buffer classes:
An AjaxXML buffer will only perform a single XMLHttpRequest regardless of the amount of scrolling a user does in a LiveGrid. An AjaxXML buffer is created using the following javascript:
buffer=new Rico.Buffer.AjaxXML(url,options,ajaxOptions)
buffer=new Rico.Buffer.AjaxXML( url, {waitMsg: "<img src='MySpinner.gif'>"}, ajaxOptions);
buffer=new Rico.Buffer.AjaxXML('ricoXMLquery.php'); ex3=new Rico.LiveGrid ('ex3', buffer, grid_options);
Assuming grid_options.prefetchBuffer is true (which is the default), then a single XMLHttpRequest will be generated during grid initialization that will fetch data from ricoXMLquery.php. The URL will include the following querystring (search) parameters:
Plus, if any options.requestParameters were specified, they would be included also. So the complete URL that would be used to fetch data for ex3 would be:
ricoXMLquery.php?id=ex3&offset=0&page_size=-1
Here is a sample response that will populate our ex3 LiveGrid:
<?xml version="1.0" encoding="UTF-8"?> <ajax-response> <response type='object' id='ex3_updater'> <rows update_ui='true' offset='0'> <tr><td>Data for row 1, cell 1</td><td>Data for row 1, cell 2</td></tr> <tr><td>Data for row 2, cell 1</td><td>Data for row 2, cell 2</td></tr> </rows> <rowcount>2</rowcount> <debug>Generated by test server</debug> </response> </ajax-response>
When you are creating the response in your request handler you must set the content-type of the response header to text/xml. Also you will need to specify the xml version and character encoding. The encoding value is very important and depends on your specific environment. Two common values are "UTF-8" and "iso-8859-1". Here is how the first couple of lines would look in Java Server Pages (JSP):
<% response.setHeader(“Content-Type”, “text/xml”); %> <?xml version="1.0" encoding="UTF-8"?>And this is how they would look in PHP:
header("Content-type: text/xml"); echo "<?xml version='1.0' encoding='UTF-8'?".">\n";
Notice several important items about the Ajax response.
First the response is wrapped in the tags <ajax-response></ajax-response>. Every Rico Ajax response must have this element as the root of the XML returned. Second, notice the response contained within the ajax-response. The response tags (<response></response>) wrap the response content. The type and id attributes of the <response> tag were required in Rico 1.1, but are ignored by Rico 2.0. Finally, notice the <rowcount> element. This specifies the total number of rows in the dataset. In an AjaxXML response, this should match the number of <tr> elements.
The debug tag (<debug></debug>) is optional. The response may contain 0, 1, or more of them. The content of each debug tag is sent to Rico's message logging facility. The Rico plug-ins can return the actual SQL queries that get executed by setting ricoXmlResponse.sendDebugMsgs to true in ricoXMLquery.php/asp/aspx. This can be very useful during development but should be turned off in production, as it is a security risk (gives users visibility to actual table and column names).
If an error occurs on the server during the processing of the request, the server can return error information to the user by enclosing an error message in <error></error> tags. For example:
<?xml version="1.0" encoding="UTF-8"?> <ajax-response> <response type='object' id='ex3_updater'> <rows update_ui='true' offset='0'> </rows> <rowcount>0</rowcount> <error>Unable to retrieve the data</error> </response> </ajax-response>
The mere presence of the <error> tag will cause any row data and the rowcount to be ignored. Thus, <rows> and <rowcount> can be included or omitted when returning an error. The Rico plug-ins will send the database-generated error message when an error occurs.
The AjaxSQL buffer extends the capabilities provided by the AjaxXML buffer. Many of the concepts are the same, but the AjaxSQL buffer is more complex. Query results are returned to the buffer in chunks, rather than returning all rows in a single response. Also, an AjaxSQL buffer assumes filtering and sorting will occur on the server. So filtering and sorting parameters must be sent in each request and the server must process those parameters correctly. Fortunately, the Rico plug-ins take care of this complexity for you.
An AjaxSQL buffer is created using the following javascript:
buffer=new Rico.Buffer.AjaxSQL(url,options,ajaxOptions)Here is an example taken from ex2simple.php:
buffer=new Rico.Buffer.AjaxSQL( 'ricoXMLquery.php', {TimeOut:<? print array_shift(session_get_cookie_params())/60 ?>}); orderGrid=new Rico.LiveGrid ('ex2', buffer, opts);
buffer=new Rico.Buffer.AjaxXML( url, {waitMsg: "<img src='MySpinner.gif'>"}, ajaxOptions);
ricoXMLquery.php?id=ex2&...&sort_col=Column0&sort_dir=ASCSet to "index" in order generate requests in this format:
ricoXMLquery.php?id=ex2&...&sort_col=0&sort_dir=ASCWhen unspecified (the default), then sort parameters are sent in this format ('s' followed by the column number). This is what the Rico plug-ins expect.
ricoXMLquery.php?id=ex2&...&s0=ASC
An XMLHttpRequest will be generated every time the AjaxSQL buffer needs more data. Data is requested in chunks as specified by the offset and page_size parameters. This makes it possible for a LiveGrid to efficiently display hundreds of thousands of records; because only a small portion of those records would reside in the client-side buffer at any one time. The URL will include the following querystring (search) parameters:
ricoXMLquery.php?id=ex2&...&get_total=true
ricoXMLquery.php?id=ex2&...&s0=ASC
ricoXMLquery.php?id=ex2&...&f[0][op]=EQ
ricoXMLquery.php?id=ex2&...&f[0][op]=EQ&f[0][len]=1
ricoXMLquery.php?id=ex2&...&f[0][op]=EQ&f[0][len]=1&f[0][0]=Column0Value
Plus, if any options.requestParameters were specified, they would be included also. So the complete URL that would be used to fetch data for ex2 would be:
ricoXMLquery.php?id=ex2&offset=0&page_size=28
The format of the AjaxSQL response is exactly the same as the AjaxXML response.
The AjaxJSON buffer was created by Jeremy Green and is an extension to the AjaxSQL buffer. An AjaxJSON buffer is created using the following javascript:
buffer=new Rico.Buffer.AjaxJSON(jsonUrl,options)
The format of AjaxJSON requests are exactly the same as AjaxSQL requests.
Here is an example of a LiveGrid response in JSON format.
{ "update_ui": true, "offset": 0, "rows": [ ["10248","VINET","Vins et alcools Chevalier","Reims","France","1996-07-04 00:00:00","1996-07-16 00:00:00"], ["10249","TOMSP","Toms Spezialitäten","Münster","Germany","1996-07-05 00:00:00","1996-07-10 00:00:00"], ["10250","HANAR","Hanari Carnes","Rio de Janeiro","Brazil","1996-07-08 00:00:00","1996-07-12 00:00:00"], ["10251","VICTE","Victuailles en stock","Lyon","France","1996-07-08 00:00:00","1996-07-15 00:00:00"], ["10252","SUPRD","Suprêmes délices","Charleroi","Belgium","1996-07-09 00:00:00","1996-07-11 00:00:00"], ["10253","HANAR","Hanari Carnes","Rio de Janeiro","Brazil","1996-07-10 00:00:00","1996-07-16 00:00:00"], ["10254","CHOPS","Chop-suey Chinese","Bern","Switzerland","1996-07-11 00:00:00","1996-07-23 00:00:00"] ], "rowCount": 830 }
The format closely follows the XML based data consumed by the Rico.Buffer.AjaxSQL buffer and all values should be returned accordingly. The ‘rows’ value object of the data object is a normal JS Array with each element being a JS hash that represents the row. For the hash the key/value combo should be colName/colValue.