CodeIgniter HTML Table Extension - rakeshraushan/CodeIgniter-1 GitHub Wiki

Category:Contributions::Libraries::Table

UPDATED: 0.2 Added the ability to hide a column and the ability to selectively format a column.

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.

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

class MY_Table extends CI_Table
{
    var $hide_columns  = array();
    var $format_columns = array();
    var $merge_columns = array();
    var $merged_delimiter = ' ';
        
    /**
     * 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_delimiter = ' ')
    {
        if(!is_array($merge_columns))return FALSE;
        $this->merge_columns = $merge_columns;
        
        if(is_null($merged_delimiter))$merged_delimiter = ' ';
        $this->merged_spacer = $merged_delimiter;
    }
    
    /**
     * Set the columns to hide
     *
     * @access public
     * @param array
     * @return void
     **/
    function set_columns_to_hide($hide_columns)
    {
        if(!is_array($hide_columns))return FALSE;
        $this->hide_columns = $hide_columns;
    }
    
    /**
     * Set the columns to format
     *
     * @access public
     * @param array with keys being the column names and values being the format function names
     * @return void
     **/    
    function set_columns_to_format($format_columns)
    {
        if(!is_array($format_columns))return FALSE;
        $this->format_columns = $format_columns;
    }
    
    /**
     * Generate the table format special cells (Enumerations, Dates).
     * 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)
    {
        // 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 && !$this->auto_heading);
                $this->_set_from_array($table_data, $set_heading);
            }
        }
        
        // 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) &&
                   !$this->_hide_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) &&
                       !$this->_hide_column($cell_key))
                    {
                        $out .= $this->template['cell_'.$name.'start'];
                        
                        if($cell === "" || $cell === null)$out .= $this->empty_cells;
                        
                        $cell = $this->_format_cell($cell_key, $cell);
                        if(array_key_exists($cell_key, $this->merge_columns))
                        {
                            $cell .= $this->merged_delimiter;
                            $cell .= $this->_format_cell($this->merge_columns[$cell_key], $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 using the specified format_columns array
     *
     * @access private
     * @param string
     * @return string
     **/
    private function _format_cell($cell_key, $cell)
    {
        if(array_key_exists($cell_key, $this->format_columns) &&
       is_callable($this->format_columns[$cell_key]))
        {
            $cell = $this->format_columns[$cell_key]($cell);    
        }
        return $cell;
    }
    
    /**
     * 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) &&
              in_array($column, $this->merge_columns); 
    }
    
    /**
     * Determines if the specified column value should be hidden
     *
     * @access private
     * @param string
     * @return boolean
     **/
    private function _hide_column($column)
    {
        return in_array($column, $this->hide_columns);
    }
}
?&gt;

/* Location: ./system/application/libraries/MY_Table.php */ 

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:

$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;

Would produce:

abc | def | ghi
jkl | mno | pqr
stu | vwx | yza

and

abc     | ghi
jkl+mno | pqr
stu+vwx | yza

This will also work with a CI SQL query result using the field names. So you can combine columns like this:

$this->table->set_columns_to_merge(array('id'=>'name'), '#');

Would produce a table that looks like this:

id    | job       | date
1#bob | developer | 2009-11-12
2#joe | lawyer    | 2009-10-31
3#sam | teacher   | 2009-09-15

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.

To hide a column add an array to the set_columns_to_hide method passing an array with the name of the column(s) we wish to hide:

$this->table->set_columns_to_hide(array('job'));

Using the previous example would produce a table that looks like this:

id    | date
1#bob | 2009-11-12
2#joe | 2009-10-31
3#sam | 2009-09-15

If you would like to format a column you must first create a function that accepts the value of the table cell you wish to change. Make sure the function always returns a value. If no operation was done on the value then you will most likely want to return it.

This function will reformat a date value using codeigniters mdate function. For the sake of simplicity lets assume I have already loaded the date helper.

function formatDate($value)
{
    $newValue = mdate('%m/%d/%Y', mysql_to_unix($value));
    if($newValue)$value = $newValue;
    return $value;
}

Now, still using the example above we would use the set_columns_to_format method passing an array with the name of the column as the key and the name of the format function as the value:

$this->table->set_columns_to_format(array('date' => 'formatDate'));

Which would produce:

id    | date
1#bob | 11/12/2009
2#joe | 10/31/2009
3#sam | 09/15/2009

Note formatting only works on individual columns.We could not combine the name and date columns then use a single formatting function to change them both. We would need two formatting functions one that changed the name and one that changed the date then merge them.

⚠️ **GitHub.com Fallback** ⚠️