Table Class API¶
Instantiation¶
The Table class can be instantiated in 2 ways, and is usually best instantiated in the view.
Table ($attributes = NULL)¶
The class constructor returns an instance of the Table class.
You can optionally pass any attributes that apply to the table tag within the constructor.
$table = new Table('id="results" cellpadding="0" cellspacing="0"')
factory ($attributes = NULL)¶
Static method that returns a chainable instance of the Table class.
Table::factory()->set_body_data($data)->render();
Setting data¶
In order to output something meaningful, all Tables must start with some form of input data.
For all tables you will start by setting body data, which by default is automatically rendered in a 1:1 relationship between data values and table cells.
However, as mentioned in the Introduction, data passed to a table does not necessarily need to be "visible" data. For more advanced tables, you will set a variety of data (e.g. body, user, row) and use callbacks to derive cell styles, atributes or alternative content such as form elements.
set_body_data ($data, $append = FALSE)¶
Set the default data for the main body of the table
Body data is the default data that a table will use for rendering content. If no callbacks or filters are in place, the Table class will render to screen an exact representation of the data passed in.
You can also use column filtering to skip rendering of columns, and instead use that data for other purposes, for example, hidden form fields, cell classes or styles.
You can pass in the following data using this method:
- a database result
- an array of objects
- a 2D array (associative or numeric)
$results = $db->query('SELECT * FROM `users`'); $table->set_body_data($results);
set_user_data ($key, $data)¶
Set custom user data that can accessed directly by user callbacks
User data is not rendered directly, it is in fact only used as a mechanism to allow data access to callbacks (user functions) which would otherwise be out of scope when called from within the class, unless you set the variables as global.
In the following example, user data is used to store random colors that might be assigned to table cells:
$table->set_user_data('random_colors', array('#F00', '#0F0', '#00F')); $table->set_callback('colorize_cells', 'body'); // colorize_cells callback omitted for brevity
set_matrix_data ($row_data, $column_data)¶
Set data that can be used to build matrix-style tables that derive their content from the product of row and column data
Matrix data in itself does not get rendered directly - you need to set a "body" callback which fires each time a table cell is to be created, then returns data derived from the values of the data stored, in conjunction with both the row index and the current column key.
function render_cell($value, $index, $key, $body_data, $user_data, $table) { // return a value that is the product of $index and $key (row index and column key) } $members = array('bob', 'sue', 'rita'); $responsibilities = array('hoovering', 'washing up', 'tidying'); $table->set_matrix_data($members, $responsibilities); $table->set_callback('render_cell', 'body');
Internally, set_matrix_data() generates a series of null table values, giving the render() method data to chew thorugh without explicitly adding body data.
set_column_data ($data)¶
Set data that is associated with the columns of the table
Similar to the above, column data is just used as a storage are for extra data that you want associated with columns, and to be accessible at render time by callbacks.
$table->set_column_data('column_classes', array('red', 'green', 'blue')); $table->set_callback('colorize_columns', 'body');
set_row_data ($data, $append = FALSE)¶
Set data that is associated with the rows of the table
Similar to the above, column data is just used as a storage are for extra data that you want associated with rows, and to be accessible at render time by callbacks.
$table->set_column_data('row_data', array('monday', 'tuesday', 'wednesday' /* rest of days */)); $table->set_callback('grab_days', 'row_title');
Setting titles¶
It is often useful to set titles on a table which are separate from the data it contains. You can choose to set titles on both columns and rows, with the option of automatic generation of column titles, with automatic row titles coming in a future release.
set_column_titles ($titles, array $filter_ids = NULL)¶
Creates a element and sets column titles on the table
There are three ways to set titles on a table. The first is to simply pass in an array of titles. This will simply set the titles of the table and they will display no matter what.
$table->set_column_titles('User's name', 'User's email');
The second is to pass in an associative array, the keys of which match the keys being used by the rows of the body data. This method has the added advantage of allowing the heading titles to be filtered dynamically along with the rows when the table is rendered:
$table->set_column_titles('name' => 'User's name', 'email' => 'User's email');
The final way is to pass Table::AUTO
to the class. This allows the table to grab the headings from the row data's keys, transforming them to Sentence Case, and removing any underscores.
$table->set_column_titles(Table::AUTO); // results in columns 'Name', 'Email'
set_row_titles ($titles, $attributes = 'class="row-title"')¶
Creates an additional column on the left of the table that displays row titles
There are 2 ways to set row titles on a table. The first is to simply pass in an array of titles. This will simply set the titles of the table and they will display no matter what.
$table->set_column_titles('User's name', 'User's email');
The second is to pass in an associative array, the keys of which match the keys being used by the rows of the body data. This method has the added advantage of allowing the heading titles to be filtered dynamically along with the rows when the table is rendered:
$table->set_column_titles('name' => 'User's name', 'email' => 'User's email');
The final way is to pass Table::AUTO
to the class. This allows the table to grab the headings from the row data's keys, transforming them to Sentence Case, and removing any underscores.
$table->set_column_titles(Table::AUTO); // results in columns 'Name', 'Email'
Column sizing, filtering and ordering¶
set_column_attributes ($type, $data)¶
Set column attributes that will be applied using HTML colgroup elements
The HTML element is used to set attributes common to all cells in a column. Allowable types are 'width', 'align', and 'style'.
// width $table->set_column_attributes('width', array(200, 150, 150)); // alignment $table->set_column_attributes('align', 'left', 'left', 'right'); // style $table->set_column_attributes('style', array('color:red', 'color:green', 'color:blue'));
You can pass values after the type argument as either an array, or just further method arguments:
// using an array $table->set_column_attributes('width', array(200, 150, 150)); // as method arguments $table->set_column_attributes('width', 200, 150, 150);
*Note:*Webkit browsers currently do _not_correctly render colgroups when a table has a . the issue is currently being looked into.
set_column_filter (array $keys)¶
Display only specific columns, as well as setting column order
Pass in an array of key names to filter the columns that are rendered. The array of key names passed in should match the keys on the keys of each row of body data.
Filtering doesn't remove the underlying data in the table, so it is still accessible in callbacks, it simply redirects the table to iterate over (and thus render) only those columns.
"Why would you want to do this?" you ask, "...setting data on a table that you won't render?". Well, you may want to use a particular database column for non-visible data, for example passing in a user_id to be used only for generating a hidden form field, but you don't want to take up an entire table column.
$results = $db->query('SELECT * FROM `users`'); $table->set_body_data($results); $table->set_column_filter(array('name', 'age', 'gender')); $table->render();
See the Callbacks section for more information.
*Note:*Filtering columns also defines the order the columns are rendered in, so to change the order of some of the columns, simply supply an array of key names that includes ALL the columns you want to render.
You can also add phantom columns by specifying non-existant keys, with which you can do things like add icons, folders, submit buttons, or what have you.
Altering the table content at runtime¶
When the Table class is rendered or updated by calling $table->update(), it updates its internal HTML cache. This is an iterative process, and raw HTML can be injected at any time, allowing you to do things such as add new rows.
add_html ($html)¶
Arbitrarily add html to the table at any point in the build process
You can add HTML to the table at any point in the build process, either as inline PHP code, or from within a callback. It is up to you to make sure it is valid HTML and doesn't interfere with the correct layout of the table!
Note that if there is any existing body data waiting to be rendered, you must call $table->update()
prior to setting any HTML.
This example adds a row at the start of each result set.
$results1 = $db->query('SELECT * FROM `users` WHERE `user_id` < 10'); $results2 = $db->query('SELECT * FROM `users` WHERE `user_id` >= 10'); $table->add_html('First users...'); $table->set_body_data($results); $table->update(); $table->add_html('Last users...'); $table->set_body_data($results); $table->render();
See the demos section for more examples, including how to add row headers when column content changes.
transpose ()¶
Transpose the data (swap rows for columns) in the table
Transpose will fail if rows and columns cannot be successfully swapped, for example you've added extra rows manually.
$table->transpose();
Applying callbacks¶
Callbacks are where the power and flexibility of the Table class really shows.
You can write custom functions outside of the class that can be called whenever the class:
- renders a body cell
- renders a heading cell
- renders a row title cell
- renders cells within a column
- begins a row
These callbacks are then handed data which can be processed in order to return alternative content, transformed data, styled table cells or nested HTML.
See the Callbacks section for more information on how to successfully use callbacks.
set_callback ($function_name, $type = 'body', $key = NULL)¶
Set callbacks for specific events in the table rendering process
The function name must be a string that references an existing function
Callback types must be one of 'body', 'heading', 'column', 'row', or 'row_title'.
Callbacks functions must have the correct signature in order for you to successfully receive and process the passed data:
// Body cells function body_cell_callback($value, $index, $key, $body_data, $user_data, $table){} // Heading cells function heading_cell_callback($value, $key, $column_data, $user_data, $table){} // Rows function row_callback($index, $body_data, $row_data, $user_data, $table){} // Row-title cells function row_title_cell_callback($value, $index, $row_data, $user_data, $table){} // Column cells function column_cell_callback($value, $index, $key, $body_data, $column_data, $user_data, $table){}
The following example shows you how to set all cells to Sentence Case:
function ucwords_cells($value, $index, $key, $body_data, $user_data, $table) { return ucwords($value); } $table->set_callback('ucwords_cells');
The following example shows you how to render the name column in red by applying a class to only that column.
*Note:*the column callback setter is the only setter that takes a third argument, that of the column name.
function make_red($value, $index, $key, $body_data, $column_data, $user_data, $table){} { return new Td($value, 'red'); } $table->set_callback(make_red', 'column', 'name');
Retrieving data¶
Usually, you won't need to retrieve data from the table - as with callbacks all the data is passed via method arguments - but as the variables are held in protected variables, an accessor is supplied for completeness.
get_user_data ($key)¶
$table->get-user_data('colors');
get_row_html ($index)¶
There may be times where you want to retrieve the row HTML generated by a table operation, for example a row generated by an AJAX call.
$table->get_row_html(0); // get the first row
Rendering methods¶
These two methods are used to generate actual HTML content.l
update ($reset = TRUE)¶
Update internal body HTML cache before calling another operation that directly adds to it.
The only time you will ever need to call update will be if you are adding multiple chunks of body data. Update will render the table up to that point, incuding making callbacks, and will then clear any body and row data.
$table->update();
render ($echo = FALSE)¶
Render all table output as HTML.
$table->set_body_data($results); $table->render();