This document explains how to customize the display of the list tab using INI files, templates, and delegate classes.
The list tab is probably the most frequently visited tab in a Xataface application. A default Xataface application provides a powerful tabular list view complete with paging and sorting ability. However it won't be long before you find yourself wanting to customize this view to suit your user's requirements better.
So what sort of customizations might you want to make to the list view? Here are a few possibilities:
- Hide or show columns from the list view.
- Change the default sort order
- Change the way a some of the columns are displayed (e.g. show an image instead of text).
- Simply change the styles and colors used.
- Modify the controller text.
- Change the template altogether.
- Add actions that can be performed on selected items of the list.
Most of these customizations can be made quite easily using delegate classes and INI files.
Hiding Columns
Out of the box, the list view displays most of the columns in the table. If the table has a lot of columns then this may start to look bad on the user's screen. This is where the visibility:list attribute comes in handy in the fields.ini file. Adding visibility:list=hidden to any field will cause it to be hidden from the list view.
e.g.: In the fields.ini file for a the people table, if we wanted to make it so that the person's bio doesn't show up in list view we could do:
[bio]
visibility:list = hidden
Now the bio won't show up in list view.
Please note that this method of hiding columns is not meant to be used as a security measure to stop users from seeing the bio field. If you want this field to be private, then you should use permissions instead:
class tables_people {
function bio__permissions(&$record){
if ( !isAdmin() ) return Dataface_PermissionsTool::NO_ACCESS();
}
}
Changing the Default Sort Order
Users can always sort the result lists in any order they wish by clicking on the column headings at the top of the list tab. However, sometimes a developer may want to provide a default sort order on a particular table. One way to do this is by manipulating the HTTP request parameters before Xataface gets to them. Xataface looks for the '-sort' parameter to indicate how the results should be sorted. Any of the following are valid values for the -sort parameter.
- first_name - This will sort the results in ascending order on the first_name field.
- first_name asc - Same as the previous option.
- first_name desc - This will sort the results in descending order on the first_name field.
- first_name desc, age asc - This will sort the results in descending order on the first_name field, and where two names are the same, they will be sorted by age in descending order.
Using this knowlege, we can set up a check at the beginning of our application's index.php file to see if the user has specified a sort parameter. If it hasn't we will impose our own default sort parameter:
Example: index.php
<?php
if ( !isset($_REQUEST['-sort']) and @$_REQUEST['-table'] == 'people' ){
$_REQUEST['-sort'] = $_GET['-sort'] = 'age';
}
...
This makes the default sort on the age column when we are in the people table.
Customizing the way the list is rendered
Xataface 0.7 adds the ability to override how lists are rendered using delegate classes. This means that you can change the way that individual table cells are rendered, or entire rows, or the header. The following is a list of the methods that are available to be implemented for this purpose. These methods may be implemented in the application delegate class or the individual table delegate classes.
- renderRow
- Returns the HTML that should be used to display a row for a particular record. This should return one or more <td> tags that will be used to render the row in list view. Xataface handles the rendering of the outer <tr> tags so that it can maintain the checkbox functions to be able to select rows. If this method is implemented, then the renderRowHeader() method should also be implemented <th> tags corresponding to each <td> tag returned by this method.
Signature | function renderRow( Dataface_Record &$record ) returns string
|
Parameters |
|
&$record
|
A Dataface_Record object encapsulating the data to be displayed in this row.
|
returns
|
A String containing HTML to be used to render a row. Should be one or more <td> tags.
|
Example
class table_people {
...
function renderRow( &$record ){
return '<td>'.$record->display('first_name').'</td>'.
'<td>'.$record->display('last_name').'</td>'.
'<td>'.$record->display('phone').'</td>';
}
...
}
Notice in the above example how we omit the <tr> tags. This is important as Xataface will provide them for us. Also note that the method in this example must be accompanied by a renderRowHeader method to render the proper <th> tags to correspond with this row.
- renderRowHeader
- Returns the HTML that should be used to display the table header. This should be one or more <th> tags that contain the column headings the correspond to the columns returned by the renderRow method. This method should always be implemented in conjunction with the renderRow method.
Signature | function renderRowHeader( string tablename ) returns string
|
Parameters |
|
$tablename
|
The name of the table on which the list is being built. You can use the Dataface_Table::loadTable($tablename) function to obtain information about this table.
|
returns
|
A string containing HTML to be used to render the table header. Should be one or more <th> tags.
|
Example
class table_people {
...
function renderRowHeader( $tablename ){
// First let's load the Dataface_Table object so we know what the labels are that we want to use.
// ** NOTE: in this case the $tablename parameter is a little redundant because we already know
// that we're working on the people table. However, if we were implementing this method in the
// application delegate class, we would need to use this parameter.
$table =& Dataface_Table::loadTable($tablename);
$fields =& $table->fields();
return '<th>'.$fields['first_name']['widget']['label'].'</th>'.
'<th>'.$fields['last_name']['widget']['label'].'</th>'.
'<th>'.$fields['phone']['widget']['label'].'</th>';
}
...
}
- %fieldname%__renderCell
- Returns the HTML that should be displayed inside table cells for the given field. This method cannot be used in conjunction with the renderRow method, as the renderRow method will override anything that is output in this method. This method is useful if you want to change the way a field is displayed in list view, but not in the view tab. If you want to change the way a field is rendered in both the list tab and the view tab it may be better to use the %fieldname%__display() method.
Signature | function %fieldname%__renderCell( Dataface_Record &$record ) returns string
|
Parameters |
|
&$record
|
The record whose value we are rendering.
|
returns
|
A string containing the content that should be displayed in the given record's row and the specified field's column of the table.
|
Example
class table_people {
...
function email__renderCell( &$record ){
return $record->strval('email').' (<a href="mailto:'.$record->strval('email').'"> Email this person</a>)';
}
...
}
The above example alters the display of the email column, adding a link for the user to be able to send an email the person.
- css__tableRowClass
- Returns the name of a CSS (Cascading Style Sheet) class that should be assigned to the <tr> tag for a particular record. This is helpful if you want to be able to customize the rendering of a row using CSS.
Signature | function css__tableRowClass( Dataface_Record &$record ) returns string
|
Parameters |
|
&$record
|
A Dataface_Record object which is being rendered in the current row.
|
returns
|
A String CSS class name that can be referenced from your stylesheets to change the style of the row.
|
Example
class table_people {
...
function css__tableRowClass( &$record ){
if ( $record->val('age') > 18 ) return 'adult-row';
else return 'child-row';
}
...
}
The above example would cause rows where the person is older than 18 to use the CSS class 'adult-row', while younger people's rows use the CSS class 'child-row'. This would allow us to make rows of Adult records rendered with a red background by adding the following to our stylesheet:
tr.adult-row td { background-color: red;}
Adding Custom Content to the List Tab
This section describes ways to customize the content of the list tab, other than the list itself. There are two main ways to do this:
- Override the template.
- Insert content into some of the pre-defined slots (i.e. insert content before or after the list.)
It is a good idea to read the Customizing Xataface's Look & Feel tutorial before reading this section so that you have a basic understanding of Xataface templates, slots, and blocks.
Overriding the List Template
The Dataface_List_View.html template (located in the Dataface/templates directory) is used to display the list action in Xataface. To customize this template, copy this template into your application's templates directory and make modifications as desired. Your application's copy will automatically override Xataface's version. If you make a mistake, just delete your copy and start over.
Inserting Custom Content (Blocks and Slots)
The Dataface_List_View.html template provides the following blocks and slots that can be used to insert content in particular places in the list tab:
- before_result_list
- Inserts content immediately before the result list. It can be handy to add quick links, instructions, or a mini-search form to the top of each list page.
Example
class table_people {
...
// This will replace the registration form so that user's can no longer register
function block__before_result_list(){
echo '<div>Below is a list of people in the company. Happy browsing!</div>';
return true;
}
...
}
- result_list
- This slot allows you to replace the actual list with your own list.
Example:
This example is taken from the Web Auction application. The web
auction application overrides the list view for the products table for
public users. It is made to be less tabular and easier for average web
users to look at.
function block__result_list(){
if ( isAdmin() ) return PEAR::raiseError("Just show the default list");
$app =& Dataface_Application::getInstance();
$query =& $app->getQuery();
$products = df_get_records_array('products', $query);
df_display(array('products'=>&$products), 'public_product_list.html');
}
Notice how this method throws a PEAR_Error object if the logged in
user is an administrator. The PEAR_Error object indicates to Xataface
that it should not use this block, but should rather just show the
default content for this slot. It obtains the current query using the
Dataface_Application object's getQuery() method, then it obtains the
current found set using the df_get_records_array() function. This
returns an array of Dataface_Record objects that are passed directly to
the template.
Also notice that this method calls the df_display function() to
display a template rather than using echo statements to output the
content inside this function. This is better form as it allows us to
separate logic from presentation. The template that it calls looks
like:
<ol id="product-list">
{foreach from=$products item=product name=product}
<li><a class="product-link" href="{$product->getURL('-action=view')}">
<h3>{$product->display('product_name')}</h3>
<img src="{$product->display('product_image')}" width="75" />
<p class="product-description">{$product->preview('product_description')}</p>
<dl class="product-details">
<dt>Minimum Bid</dt><dd>{$product->display('minimum_bid')}</dd>
<dt>Current Bid</dt><dd>{$product->display('current_high_bid')}</dd>
</dl>
<div style="clear: both"></div>
</a></li>
{/foreach}
</ol>
<div style="clear: both"></div>
{result_controller}
Notice the {result_controller} tag at the end. This is a nifty tag
that allows you to place the result controller in any part of the page
(i.e. the bit that helps you navigate the result set - 1, 2, 3, next
previous, etc..).
The Web Auction application also has a stylesheet that helps display this list nicely. You can see all of the source code for the Web Auction application at http://demo.weblite.ca/source-browser.php?-path=webauction -
-
- after_result_list
- Inserts content immediately following the result list.