Actions

Difference between revisions of "Developer Area/Core Subsystems/Table Renderer"

From Mahara Wiki

< Developer Area‎ | Core Subsystems
(Created page with "<div id="section_1"> === Example Usage === <div class="wikitext"> You simply create an instance of the [http://old.eduforge.org/wiki/wiki/mahara/wiki?pagename=TableRenderer Ta…")
 
 
(4 intermediate revisions by one other user not shown)
Line 1: Line 1:
 
<div id="section_1">
 
<div id="section_1">
  
=== Example Usage ===
+
===Example Usage===
  
 
<div class="wikitext">
 
<div class="wikitext">
Line 15: Line 15:
 
* colspec is an array defining the columns of the table (see below)
 
* colspec is an array defining the columns of the table (see below)
  
<div class="plugin tightenable"><code><font color="#000000"> <font color="#007700">var </font><font color="#0000bb">grouplist </font><font color="#007700"><nowiki>= new </nowiki></font><font color="#0000bb">TableRenderer</font><font color="#007700">(<br />     </font><font color="#dd0000">'grouplist'</font><font color="#007700">,<br />     </font><font color="#dd0000">'index.json.php'</font><font color="#007700">,<br />     [<br />         </font><font color="#dd0000">'name'</font><font color="#007700">,<br />         </font><font color="#dd0000">'count'</font><font color="#007700">,<br />         function(</font><font color="#0000bb">r</font><font color="#007700">) { return </font><font color="#0000bb">TD</font><font color="#007700">(</font><font color="#0000bb">null</font><font color="#007700">,</font><font color="#0000bb">A</font><font color="#007700">({</font><font color="#dd0000">'href'</font><font color="#007700"><nowiki>:</nowiki></font><font color="#dd0000">'edit.php?id=' </font><font color="#007700">+ </font><font color="#0000bb">r</font><font color="#007700">.</font><font color="#0000bb">id</font><font color="#007700">}, </font><font color="#dd0000">'edit'</font><font color="#007700">)); }<br />     ]<br /> );<br /><br /></font><font color="#0000bb">grouplist</font><font color="#007700">.</font><font color="#0000bb">updateOnLoad</font><font color="#007700">();<br /></font> </font> </code></div>
+
<div class="plugin tightenable"><code><font color="#000000"> <font color="#007700">var </font><font color="#0000bb">grouplist </font><font color="#007700">= new </font><font color="#0000bb">TableRenderer</font><font color="#007700">(<br />     </font><font color="#dd0000">'grouplist'</font><font color="#007700">,<br />     </font><font color="#dd0000">'index.json.php'</font><font color="#007700">,<br />     [<br />         </font><font color="#dd0000">'name'</font><font color="#007700">,<br />         </font><font color="#dd0000">'count'</font><font color="#007700">,<br />         function(</font><font color="#0000bb">r</font><font color="#007700">) { return </font><font color="#0000bb">TD</font><font color="#007700">(</font><font color="#0000bb">null</font><font color="#007700">,</font><font color="#0000bb">A</font><font color="#007700">({</font><font color="#dd0000">'href'</font><font color="#007700">:</font><font color="#dd0000">'edit.php?id=' </font><font color="#007700">+ </font><font color="#0000bb">r</font><font color="#007700">.</font><font color="#0000bb">id</font><font color="#007700">}, </font><font color="#dd0000">'edit'</font><font color="#007700">)); }<br />     ]<br /> );<br /><br /></font><font color="#0000bb">grouplist</font><font color="#007700">.</font><font color="#0000bb">updateOnLoad</font><font color="#007700">();<br /></font> </font> </code></div>
  
 
followed by the html table ...
 
followed by the html table ...
Line 27: Line 27:
 
           |}
 
           |}
  
'''note'''<nowiki>: your tables should always include thead for the heading, and tbody for the content, the table renderer will completly replace tbody with each data load.</nowiki>
+
'''note''': your tables should always include thead for the heading, and tbody for the content, the table renderer will completly replace tbody with each data load.
  
 
Your table should also have a class of 'tablerenderer', to add designers.
 
Your table should also have a class of 'tablerenderer', to add designers.
Line 33: Line 33:
 
<div id="section_2">
 
<div id="section_2">
  
=== JSON Specification ===
+
===JSON Specification===
  
 
The JSON script acting as the data source for a given table renderer should always send arrays of records formatted as follows ...
 
The JSON script acting as the data source for a given table renderer should always send arrays of records formatted as follows ...
  
<div class="plugin tightenable"><code><font color="#000000"> <font color="#0000bb">$data </font><font color="#007700"><nowiki>= array(</nowiki><br />     </font><font color="#dd0000">'limit'           </font><font color="#007700"><nowiki>=&gt; </nowiki></font><font color="#0000bb">10</font><font color="#007700">,<br />     </font><font color="#dd0000">'offset'          </font><font color="#007700"><nowiki>=&gt; </nowiki></font><font color="#0000bb">0</font><font color="#007700">,<br />     </font><font color="#dd0000">'count'           </font><font color="#007700"><nowiki>=&gt; </nowiki></font><font color="#0000bb">235</font><font color="#007700">,<br />     </font><font color="#dd0000">'otherstatevar'   </font><font color="#007700"><nowiki>=&gt; </nowiki></font><font color="#dd0000">'randomdata'</font><font color="#007700">,<br />     </font><font color="#dd0000">'otherglobaldata' </font><font color="#007700"><nowiki>=&gt; array(</nowiki><br />         </font><font color="#ff8000">// ...<br />     </font><font color="#007700">),<br />     </font><font color="#dd0000">'data' </font><font color="#007700"><nowiki>=&gt; array(</nowiki><br />         array(    </font><font color="#ff8000">// single record<br />             </font><font color="#dd0000">'field1' </font><font color="#007700"><nowiki>=&gt; </nowiki></font><font color="#dd0000">'value1'</font><font color="#007700">,<br />             </font><font color="#dd0000">'field2' </font><font color="#007700"><nowiki>=&gt; </nowiki></font><font color="#dd0000">'value2'</font><font color="#007700">,<br />             </font><font color="#dd0000">'field3' </font><font color="#007700"><nowiki>=&gt; </nowiki></font><font color="#dd0000">'value3'</font><font color="#007700">,<br />         ),<br />         array(    </font><font color="#ff8000">// single record<br />             </font><font color="#dd0000">'field1' </font><font color="#007700"><nowiki>=&gt; </nowiki></font><font color="#dd0000">'value1'</font><font color="#007700">,<br />             </font><font color="#dd0000">'field2' </font><font color="#007700"><nowiki>=&gt; </nowiki></font><font color="#dd0000">'value2'</font><font color="#007700">,<br />             </font><font color="#dd0000">'field3' </font><font color="#007700"><nowiki>=&gt; </nowiki></font><font color="#dd0000">'value3'</font><font color="#007700">,<br />         ),<br />         </font><font color="#ff8000">// ...<br />     </font><font color="#007700">),<br /> );<br /></font> </font> </code></div>
+
<div class="plugin tightenable"><code><font color="#000000"> <font color="#0000bb">$data </font><font color="#007700">= array(<br />     </font><font color="#dd0000">'limit'           </font><font color="#007700">=&gt; </font><font color="#0000bb">10</font><font color="#007700">,<br />     </font><font color="#dd0000">'offset'          </font><font color="#007700">=&gt; </font><font color="#0000bb">0</font><font color="#007700">,<br />     </font><font color="#dd0000">'count'           </font><font color="#007700">=&gt; </font><font color="#0000bb">235</font><font color="#007700">,<br />     </font><font color="#dd0000">'otherstatevar'   </font><font color="#007700">=&gt; </font><font color="#dd0000">'randomdata'</font><font color="#007700">,<br />     </font><font color="#dd0000">'otherglobaldata' </font><font color="#007700">=&gt; array(<br />         </font><font color="#ff8000">// ...<br />     </font><font color="#007700">),<br />     </font><font color="#dd0000">'data' </font><font color="#007700">=&gt; array(<br />         array(    </font><font color="#ff8000">// single record<br />             </font><font color="#dd0000">'field1' </font><font color="#007700">=&gt; </font><font color="#dd0000">'value1'</font><font color="#007700">,<br />             </font><font color="#dd0000">'field2' </font><font color="#007700">=&gt; </font><font color="#dd0000">'value2'</font><font color="#007700">,<br />             </font><font color="#dd0000">'field3' </font><font color="#007700">=&gt; </font><font color="#dd0000">'value3'</font><font color="#007700">,<br />         ),<br />         array(    </font><font color="#ff8000">// single record<br />             </font><font color="#dd0000">'field1' </font><font color="#007700">=&gt; </font><font color="#dd0000">'value1'</font><font color="#007700">,<br />             </font><font color="#dd0000">'field2' </font><font color="#007700">=&gt; </font><font color="#dd0000">'value2'</font><font color="#007700">,<br />             </font><font color="#dd0000">'field3' </font><font color="#007700">=&gt; </font><font color="#dd0000">'value3'</font><font color="#007700">,<br />         ),<br />         </font><font color="#ff8000">// ...<br />     </font><font color="#007700">),<br /> );<br /></font> </font> </code></div>
  
 
The data key specifies the data for the actual table, this combined with the column specification defines the bulk of the table appearence. The other keys are read as either state variables, or not at all (except perhaps by the column definition). Both these cases are discussed below.
 
The data key specifies the data for the actual table, this combined with the column specification defines the bulk of the table appearence. The other keys are read as either state variables, or not at all (except perhaps by the column definition). Both these cases are discussed below.
Line 43: Line 43:
 
</div><div id="section_3">
 
</div><div id="section_3">
  
=== Column Specification ===
+
===Column Specification===
  
 
The column specification (in javascript) defines how records from the JSON data source are rendered into table cells. The column spec is an array where each element defines a single table cell.
 
The column specification (in javascript) defines how records from the JSON data source are rendered into table cells. The column spec is an array where each element defines a single table cell.
Line 51: Line 51:
 
</div><div id="section_4">
 
</div><div id="section_4">
  
=== Additional state ===
+
===Additional state===
  
 
By default, the table renderer will only send offset and limit parameters to your JSON script. If you want to send additional variables to the JSON script, you want to have additional state.
 
By default, the table renderer will only send offset and limit parameters to your JSON script. If you want to send additional variables to the JSON script, you want to have additional state.
Line 59: Line 59:
 
To add a state variable to the table renderer instance, you push the name of the variable onto the statevars array of the object. Additionaly you may want to set an initial value for the state var ...
 
To add a state variable to the table renderer instance, you push the name of the variable onto the statevars array of the object. Additionaly you may want to set an initial value for the state var ...
  
<div class="plugin tightenable"><code><font color="#000000"> <font color="#0000bb">results</font><font color="#007700">.</font><font color="#0000bb">statevars</font><font color="#007700">.</font><font color="#0000bb">push</font><font color="#007700">(</font><font color="#dd0000">'query'</font><font color="#007700">);<br /></font><font color="#0000bb">results</font><font color="#007700">.</font><font color="#0000bb">query </font><font color="#007700"><nowiki>= </nowiki></font><font color="#dd0000">'frumpy'</font><font color="#007700"><nowiki>;</nowiki><br /></font> </font> </code></div>
+
<div class="plugin tightenable"><code><font color="#000000"> <font color="#0000bb">results</font><font color="#007700">.</font><font color="#0000bb">statevars</font><font color="#007700">.</font><font color="#0000bb">push</font><font color="#007700">(</font><font color="#dd0000">'query'</font><font color="#007700">);<br /></font><font color="#0000bb">results</font><font color="#007700">.</font><font color="#0000bb">query </font><font color="#007700">= </font><font color="#dd0000">'frumpy'</font><font color="#007700">;<br /></font> </font> </code></div>
  
 
It is best to do this before the call to updateOnLoad().
 
It is best to do this before the call to updateOnLoad().
Line 65: Line 65:
 
</div><div id="section_5">
 
</div><div id="section_5">
  
=== Triggering updates ===
+
===Triggering updates===
  
 
If you do something on the page that makes you want to trigger an update of the table content (say the user has entered a new search query), then you can call the doupdate() function. This optionally takes an object parameter defining new values for the state keys (that will be sent to the JSON script). For any keys that are omitted, the existing state values will be used.
 
If you do something on the page that makes you want to trigger an update of the table content (say the user has entered a new search query), then you can call the doupdate() function. This optionally takes an object parameter defining new values for the state keys (that will be sent to the JSON script). For any keys that are omitted, the existing state values will be used.
Line 71: Line 71:
 
Pretend we're on the second page of search results for "frumpy", and the user enters a new search for "flooble". We have 3 state vars (limit=20, offset=20, query="frumpy"). We call doupdate as follows ...
 
Pretend we're on the second page of search results for "frumpy", and the user enters a new search for "flooble". We have 3 state vars (limit=20, offset=20, query="frumpy"). We call doupdate as follows ...
  
<div class="plugin tightenable"><code><font color="#000000"> <font color="#0000bb">results</font><font color="#007700">.</font><font color="#0000bb">doupdate</font><font color="#007700">({</font><font color="#dd0000">'offset'</font><font color="#007700"><nowiki>: </nowiki></font><font color="#0000bb">0</font><font color="#007700">, </font><font color="#dd0000">'query'</font><font color="#007700"><nowiki>: </nowiki></font><font color="#dd0000">'flooble'</font><font color="#007700">});<br /></font> </font> </code></div>
+
<div class="plugin tightenable"><code><font color="#000000"> <font color="#0000bb">results</font><font color="#007700">.</font><font color="#0000bb">doupdate</font><font color="#007700">({</font><font color="#dd0000">'offset'</font><font color="#007700">: </font><font color="#0000bb">0</font><font color="#007700">, </font><font color="#dd0000">'query'</font><font color="#007700">: </font><font color="#dd0000">'flooble'</font><font color="#007700">});<br /></font> </font> </code></div>
  
 
This resets the offset to 0, the query to 'flooble', and keeps the limit at it's previous value (although it's still sent to the JSON script).
 
This resets the offset to 0, the query to 'flooble', and keeps the limit at it's previous value (although it's still sent to the JSON script).
Line 77: Line 77:
 
</div><div id="section_6">
 
</div><div id="section_6">
  
=== Pagination ===
+
===Pagination===
  
 
By default, the table renderer will display pagination controls at the top and bottom of the table (using thead and tfoot). If you want to disable (or modify) this behaviour, the following variables are available (although they should be set immediately after creating the table object.
 
By default, the table renderer will display pagination controls at the top and bottom of the table (using thead and tfoot). If you want to disable (or modify) this behaviour, the following variables are available (although they should be set immediately after creating the table object.
  
<div class="plugin tightenable"><code><font color="#000000"> <font color="#0000bb">myTableRenderer</font><font color="#007700">.</font><font color="#0000bb">paginate </font><font color="#007700"><nowiki>= </nowiki></font><font color="#0000bb">false</font><font color="#007700"><nowiki>; </nowiki></font><font color="#ff8000">// disables pagination entirely<br /></font><font color="#0000bb">myTableRenderer</font><font color="#007700">.</font><font color="#0000bb">paginate_simple </font><font color="#007700"><nowiki>= </nowiki></font><font color="#0000bb">false</font><font color="#007700"><nowiki>; </nowiki></font><font color="#ff8000">// disables the "next" and "previous" page buttons<br /></font><font color="#0000bb">myTableRenderer</font><font color="#007700">.</font><font color="#0000bb">paginate_firstlast </font><font color="#007700"><nowiki>= </nowiki></font><font color="#0000bb">false</font><font color="#007700"><nowiki>; </nowiki></font><font color="#ff8000">// disables the "first" and "last" page buttons<br /></font> </font> </code></div></div><div id="section_7">
+
<div class="plugin tightenable"><code><font color="#000000"> <font color="#0000bb">myTableRenderer</font><font color="#007700">.</font><font color="#0000bb">paginate </font><font color="#007700">= </font><font color="#0000bb">false</font><font color="#007700">; </font><font color="#ff8000">// disables pagination entirely<br /></font><font color="#0000bb">myTableRenderer</font><font color="#007700">.</font><font color="#0000bb">paginate_simple </font><font color="#007700">= </font><font color="#0000bb">false</font><font color="#007700">; </font><font color="#ff8000">// disables the "next" and "previous" page buttons<br /></font><font color="#0000bb">myTableRenderer</font><font color="#007700">.</font><font color="#0000bb">paginate_firstlast </font><font color="#007700">= </font><font color="#0000bb">false</font><font color="#007700">; </font><font color="#ff8000">// disables the "first" and "last" page buttons<br /></font> </font> </code></div></div><div id="section_7">
  
=== Avoiding empty tables ===
+
===Avoiding empty tables===
  
 
If you want the table to be replaced by something else when it receives no data from the json script, set the emptycontent field:
 
If you want the table to be replaced by something else when it receives no data from the json script, set the emptycontent field:
  
<div class="plugin tightenable"><code><font color="#000000"> <font color="#0000bb">results</font><font color="#007700">.</font><font color="#0000bb">emptycontent </font><font color="#007700"><nowiki>= </nowiki></font><font color="#dd0000">'No results found'</font><font color="#007700"><nowiki>;</nowiki><br /></font> </font> </code></div>
+
<div class="plugin tightenable"><code><font color="#000000"> <font color="#0000bb">results</font><font color="#007700">.</font><font color="#0000bb">emptycontent </font><font color="#007700">= </font><font color="#dd0000">'No results found'</font><font color="#007700">;<br /></font> </font> </code></div>
  
 
When the table updates and gets no data, it hides the table element and displays the contents of this field enclosed in a DIV.
 
When the table updates and gets no data, it hides the table element and displays the contents of this field enclosed in a DIV.
  
 
</div></div></div>
 
</div></div></div>
 +
[[Category:Developer Area]]

Latest revision as of 16:02, 16 May 2011

Example Usage

You simply create an instance of the TableRenderer object (in javascript), passing some parameters defining your table.

var myReference = new TableRenderer(id, source, colspec)

where ...

  • id is the id of the TABLE element you wish to put the data in
  • source is a url to the json script providing the data in the specified structure (see below)
  • colspec is an array defining the columns of the table (see below)
var grouplist = new TableRenderer(
    
'grouplist',
    
'index.json.php',
    [
        
'name',
        
'count',
        function(
r) { return TD(null,A({'href':'edit.php?id=' + r.id}, 'edit')); }
    ]
);

grouplist.updateOnLoad();

followed by the html table ...

{str tag="groupname"} {str tag="membercount"}

note: your tables should always include thead for the heading, and tbody for the content, the table renderer will completly replace tbody with each data load.

Your table should also have a class of 'tablerenderer', to add designers.

JSON Specification

The JSON script acting as the data source for a given table renderer should always send arrays of records formatted as follows ...

$data = array(
    
'limit'           => 10,
    
'offset'          => 0,
    
'count'           => 235,
    
'otherstatevar'   => 'randomdata',
    
'otherglobaldata' => array(
        
// ...
    
),
    
'data' => array(
        array(    
// single record
            
'field1' => 'value1',
            
'field2' => 'value2',
            
'field3' => 'value3',
        ),
        array(    
// single record
            
'field1' => 'value1',
            
'field2' => 'value2',
            
'field3' => 'value3',
        ),
        
// ...
    
),
);

The data key specifies the data for the actual table, this combined with the column specification defines the bulk of the table appearence. The other keys are read as either state variables, or not at all (except perhaps by the column definition). Both these cases are discussed below.

Column Specification

The column specification (in javascript) defines how records from the JSON data source are rendered into table cells. The column spec is an array where each element defines a single table cell.

Each element can either be a string (in which case that key is extracted from the record and placed in the cell, of a function, in which case the function is passed the record, and the root-level JSON data as parameters in that order. If a function is used, it needs to manually return the TD() element itself.

Additional state

By default, the table renderer will only send offset and limit parameters to your JSON script. If you want to send additional variables to the JSON script, you want to have additional state.

For example, in a search results table, you may want to have the query remain intact while pagination is happening, and for this to work, you need to send the query along with the limit and offset to the json script.

To add a state variable to the table renderer instance, you push the name of the variable onto the statevars array of the object. Additionaly you may want to set an initial value for the state var ...

results.statevars.push('query');
results.query = 'frumpy';

It is best to do this before the call to updateOnLoad().

Triggering updates

If you do something on the page that makes you want to trigger an update of the table content (say the user has entered a new search query), then you can call the doupdate() function. This optionally takes an object parameter defining new values for the state keys (that will be sent to the JSON script). For any keys that are omitted, the existing state values will be used.

Pretend we're on the second page of search results for "frumpy", and the user enters a new search for "flooble". We have 3 state vars (limit=20, offset=20, query="frumpy"). We call doupdate as follows ...

results.doupdate({'offset': 0, 'query': 'flooble'});

This resets the offset to 0, the query to 'flooble', and keeps the limit at it's previous value (although it's still sent to the JSON script).

Pagination

By default, the table renderer will display pagination controls at the top and bottom of the table (using thead and tfoot). If you want to disable (or modify) this behaviour, the following variables are available (although they should be set immediately after creating the table object.

myTableRenderer.paginate = false; // disables pagination entirely
myTableRenderer.paginate_simple = false; // disables the "next" and "previous" page buttons
myTableRenderer.paginate_firstlast = false; // disables the "first" and "last" page buttons

Avoiding empty tables

If you want the table to be replaced by something else when it receives no data from the json script, set the emptycontent field:

results.emptycontent = 'No results found';

When the table updates and gets no data, it hides the table element and displays the contents of this field enclosed in a DIV.