Skip to content

CodeIgniter HTML Table Extension

World Wide Web Server edited this page Jul 4, 2012 · 13 revisions

This class is an extension of the HTML Table class its purpose is to allow the combination of columns as well as special formatting for date values. I created this class mainly for creating tables directly from CI SQL results. Instead of writing a more complex query than I already had it was much easier to set an array of keys and values to combine query results in my table.

Note: this is using the MY_ prefix you would need to change it based on your config.

[code] <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class MY_Table extends CI_Table { var $merge_columns = array(); var $merged_spacer = ' ';

/**
 * Set the columns to merge along with 
 * the spacer that goes in between.
 *
 * @access public
 * @param array
 * @param string
 * @return void
 **/
function set_columns_to_merge($merge_columns, $merged_spacer = ' ')
{
    if(!is_array($merge_columns))return FALSE;
    $this->merge_columns = $merge_columns;
    if(is_null($merged_spacer))$merged_spacer = ' ';
    $this->merged_spacer = $merged_spacer;
}

/**
 * Generate the table, format special cells (Dates, etc).
 * Columns can also be merged by specifying the master and slave
 * columns (master => slave)in the merge_column array. The
 * merged_spacer goes in between all merged column values.
 *
 * NOTE: Merged columns always take the header of the
 * master (key) column.
 *
 * @access    public
 * @param    mixed
 * @return    string
 */
 function generate($table_data = NULL, $merge_columns = array(), $merged_spacer = ' ')
{
    // The table data can optionally be passed to this function
    // either as a database result object or an array
    if(!is_null($table_data))
    {
        if(is_object($table_data))$this->_set_from_object($table_data);
        elseif(is_array($table_data))
        {
            $set_heading = (count($this->heading) == 0 AND $this->auto_heading == FALSE) ? FALSE : TRUE;
            $this->_set_from_array($table_data, $set_heading);
        }
    }
    
    // Set the merged column array and the spacer
    $this->set_columns_to_merge($merge_columns, $merged_spacer);

    // Is there anything to display?  No?  Smite them!
    if(count($this->heading) == 0 AND count($this->rows) == 0)return 'Undefined table data';
    
    // Compile and validate the template date
    $this->_compile_template();

    // Build the table!
    
    $out = $this->template['table_open'];
    $out .= $this->newline;        

    // Add any caption here
    if($this->caption)
    {
        $out .= $this->newline;
        $out .= '<caption>' . $this->caption . '</caption>';
        $out .= $this->newline;
    }

    // Is there a table heading to display?
    if(count($this->heading) > 0)
    {
        $out .= $this->template['heading_row_start'];
        $out .= $this->newline;        
        foreach($this->heading as $heading_key => $heading)
        {
            $heading_key = is_object($table_data) ? $heading : $heading_key;
            
            //Only add non-combined headers (ie master headers or regular headers)
            if(!$this->_merge_column($heading_key))
            {
                $out .= $this->template['heading_cell_start'];
                $out .= $heading;
                $out .= $this->template['heading_cell_end'];
            }
        }

        $out .= $this->template['heading_row_end'];
        $out .= $this->newline;                
    }

    // Build the table rows
    if (count($this->rows) > 0)
    {
        $i = 1;
        
        foreach($this->rows as $row)
        {
            if(!is_array($row))break;
            
            // We use modulus to alternate the row colors
            $name = (fmod($i++, 2)) ? '' : 'alt_';
            
            $out .= $this->template['row_'.$name.'start'];
            $out .= $this->newline;        
            
            foreach($row as $cell_key => $cell)
            {
                //Use only non-combined cells (ie master cells, or regular cells)
                if(!$this->_merge_column($cell_key))
                {
                    $out .= $this->template['cell_'.$name.'start'];
                    
                    if($cell === "" || $cell === null)$out .= $this->empty_cells;
                    
                    $cell = $this->_format_cell($cell);
                    if(array_key_exists($cell_key, $this->merge_columns))
                    {
                        $cell .= $this->merged_spacer;
                        $cell .= $this->_format_cell($row[$this->merge_columns[$cell_key]]);
                    }
                    $out .= $cell;
                    $out .= $this->template['cell_'.$name.'end'];
                }
            }
            
            $out .= $this->template['row_'.$name.'end'];
            $out .= $this->newline;    
        }
    }
    $out .= $this->template['table_close'];
    return $out;
}

/**
 * Helper method to format a cell for things like dates etc.
 *
 * @access private
 * @param string
 * @return string
 **/
private function _format_cell($cell)
{
    return $cell;//Im not doing any formatting but this is where it would be done
}

/**
 * Determines if the specified column value should be
 * combined with another and thusly not rendered.
 *
 * @access private
 * @param string
 * @return boolean
 **/
private function _merge_column($column)
{
    //return if this column isn't a master column or a regular column (its a merged column)
    return (array_key_exists($column, $this->merge_columns) === FALSE &&
          !(array_search($column, $this->merge_columns) === FALSE)); 
}

?>

/* Location: ./system/application/libraries/MY_Table.php */ [/code]

This allows you to generate the table in many different ways. When no columns are specified to be combined then it just renders the same way as CI_Table.

To call: [code] $this->load->library('table'); $table_data = array( array('abc', 'def', 'ghi'), array('jkl', 'mno', 'pqr'), array('stu', 'vwx', 'yza') ); $table1 = $this->table->generate($table_data); $this->table->set_columns_to_merge(array(0=>1), '+'); $table2 = $this->table->generate($table_data);

echo $table1; echo $table2; [/code] Would produce: [code] abc | def | ghi jkl | mno | pqr stu | vwx | yza [/code] and [code] abc | ghi jkl+mno | pqr stu+vwx | yza [/code]

This will also work with a CI SQL query result using the field names. So you can combine columns like this: [code] $this->table->set_columns_to_merge(array('id'=>'name'), '#'); [/code] Would produce a table that looks like this: [code] id | job 1#bob | developer 2#joe | lawyer 3#sam | teacher [/code] Note that the merged column header does not get combined only the table cells do. The column header will always be the first merging columns' header.

Clone this wiki locally