Welcome Guest, Not a member yet? Register   Sign In
Html table plugin
#1

[eluser]xwero[/eluser]
Yesterday my attention was drawn to the html table class and because it got stuck in my head i created the html table plugin.

It does everything the html table class does except for adding a database object as table content.

The benefits are :
- no markup in the controller
- more in control of the output
- multiple header rows

Code:
<?php
function table($view_path,$body,$header= array(),$footer = array(),$columns=0)
{
    if( ! is_array($body))
    {
        return '';
    }
    // return $header and $footer parameters to default state in case a
    // developer used a string when calling the function
    if( ! is_array($header)){ $header = array(); }

    if( ! is_array($footer)){ $footer = array(); }
    // if the header and footer parameters are a single array a two dimensional
    // array is created
    if( count($header) > 0 && ! is_array($header[0])) { $header = array($header); }

    if( count($footer) > 0 && ! is_array($footer[0])) { $footer = array($footer); }
    // create columns from single array
    if(is_numeric($columns) && $columns > 0)
    {
        $body = array_chunk($body,$columns);
    }

    if(! is_array($body[0])) { $body = array($body); }

    ob_start();
    include($view_path);
    return ob_get_clean();
}
Put this code in a file named table_pi.php. To get the view path easy you can add the following function to the plugin file or another helper that you know is loaded.
Code:
function view_path($view)
{
  $CI =& get_instance(); // You can add file_exists check after this line
  return $CI->load->_ci_view_path.$view.EXT;
}
And it's good to go. Some usage examples
Code:
/* break array up into multiple columns */
$body = array('one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve');

echo table(view_path('table/columns'),$body,'','',3);
// table/columns.php
<table>&lt;?php foreach($body as $row): ?&gt;
<tr>&lt;?php foreach($row as $cell): ?&gt;
<td>&lt;?php echo $cell ?&gt;</td>&lt;?php endforeach ?&gt;
</tr>&lt;?php endforeach ?&gt;
</table>

/* header, footer, body */
$header = array(array(1,2,3),array('multiple','rows','possible'));

$body = array(array(4,5,6),array(7,8,9));

$footer = array('no','wrapper array','needed');

echo table(view_path('table/hbf'),$body,$header,$footer);
// table/hbf.php
<table>
<thead>&lt;?php foreach($header as $row): ?&gt;
<tr>&lt;?php foreach($row as $cell): ?&gt;
<th>&lt;?php echo $cell ?&gt;</th>&lt;?php endforeach ?&gt;
</tr>&lt;?php endforeach ?&gt;
</thead>
<tbody>&lt;?php foreach($body as $row): ?&gt;
<tr>&lt;?php foreach($row as $cell): ?&gt;
<td>&lt;?php echo $cell ?&gt;</td>&lt;?php endforeach ?&gt;
</tr>&lt;?php endforeach ?&gt;
</tbody>
<tfoot>&lt;?php foreach($footer as $row): ?&gt;
<tr>&lt;?php foreach($row as $cell): ?&gt;
<td>&lt;?php echo $cell ?&gt;</td>&lt;?php endforeach ?&gt;
</tr>&lt;?php endforeach ?&gt;
</tfoot>
</table>

Enjoy!

UPDATE 1 : If $header, $body or $footer are a single array it will be transformed to a two dimensional array

UPDATE 2 : based on sophistry's response i removed the nested loop and replaced the not empty check with a count higher than 0 check.
#2

[eluser]sophistry[/eluser]
hi xwero,

thanks for that.

here's a more readable way to get the "NBSP stuffed" columns. i'm a "library" coder so when i saw what you were doing in the while loop i thought "array_chunk, array_pad".

also, is_num() function made my output into a blank page, so i changed it to is_numeric().

Code:
function table($view_path,$body,$header= array(),$footer = array(),$columns=0)
    {
        if( ! is_array($body))
        {
            return '';
        }
        // return $header and $footer parameters to default state in case a
        // developer used a string when calling the function
        if( ! is_array($header)){ $header = array(); }
    
        if( ! is_array($footer)){ $footer = array(); }
        // create columns from single array
        if(is_numeric($columns) && $columns > 0)
        {
            $chunked = array_chunk($body,$col);
            $body = array_pad(array_pop($chunked),$col,'&nbsp;');
        }
        ob_start();
        include($view_path);
        return ob_get_clean();
    }
#3

[eluser]xwero[/eluser]
i stole the column part from the table class Smile I already changed the is_num mistake.
#4

[eluser]sophistry[/eluser]
hi xwero,

any reason why you took out the array_pad() that inserts the
Code:
&nbsp;
? you had a step like that in the original code you posted. with just array chunk you will end up with improperly closed/balanced tables: not enough TD tags will be generated.

EDIT: oops, i realized that the array_pad() as shown above won't work. it needs to have an array_push() or a squarebrackets array push after the pop and pad. does that make sense?

also, i rely on the "subscribe to this thread" option. But, if you update the original post the forum does not send an email. so, you made a bunch of changes and i just happened to look back onto this thread. otherwise i would never have seen that you made changes. just a heads up that when you edit posts it doesn't send out emails to thread subscribers.

cheers.
#5

[eluser]xwero[/eluser]
I took the array_pad out because why do you need to create cells for nothing?

This works for the array_pad
Code:
$body[count($body)-1] = array_pad(end($body),$columns,'&nbsp;');

I will keep it in mind about the updates but i don't think there will be other changes. The function is feature complete and developer friendly. Only when people find bugs or suggest really neat additions the function will be updated.
#6

[eluser]sophistry[/eluser]
of course there *is* a reason the NBSP stuffing code was in the CI class: browser rendering differences.

this link has a little bit about it. also, border-rendering problems come up when you don't have the proper number of TD tags to match your defined header columns. best opt to create a complete table and maybe make the NBSP a more obvious option? it has to be something because otherwise your tables will render strangely.

http://www.w3schools.com/html/html_tables.asp

cheers.
#7

[eluser]xwero[/eluser]
The link mentions empty cells not missing cells. I didn't find anything on rendering problems with missing cells.
Of course if the css styles the cells left and/or right border you have to pad the row. But I rather give developers the choice if they want to pad the last row or not. What if they want to pad it with another content than NBSP?
#8

[eluser]sophistry[/eluser]
use your own browser to test what happens when you don't emit a TD tag inside a table that is "expecting" one (i.e., no colspan attributes anywhere). what does your browser show? mine (safari 3 and 4, firefox) shows no border when there is no TD tag. so, it's unexpected behavior for a table rendering function to emit a table that has missing tags (regardless of what's in them).

two things:
1) missing TD tag inside a table - my browsers show no border on the cell even if you use CSS.
the developer/designer could try this CSS to make up for the lack of TD tags but it wouldn't work (not in firefox and not in safari) CSS cannot cure missing TD tags, but it does cure empty cells by giving them a border.
Code:
table { empty-cells:show; }

2) empty value inside TD tag - allow the developer to specify what to include in empty cells as an option. just put it in a class var like in the CI table class.

cheers.
#9

[eluser]xwero[/eluser]
You are right but I think the better question is when do you need to break up a single array to create a table? And do you show the cell borders in that situation?
The only time i show cell borders is when the table content is database like. If the content are rows of user/friendly content i use zebra stripes and padding to make it easier on the eyes. And i think many people do the same.

5 parameters is enough for a function, i don't like functions with too many parameters if they have different content types. Following is an example on how you can add custom content to empty cells by adding a class
Code:
$columns = 4;
$body = array('one', 'two', 'three', 'four', 'five');
// why hardcode the additional array items if you have a programming language        
if((count($body) % $columns) != 0)
{
   $array = array_pad($array,(ceil(count($body)/$columns)*$columns),'[EMPTY]');
}

echo table(view_path('table/columns'),$body,'','',$columns);
// table/columns.php
<table>&lt;?php foreach($body as $row): ?&gt;
<tr>&lt;?php $class = ''; foreach($row as $cell):
if($cell == '[EMPTY]'){ $class = ' class="emptyCell"'; $cell = '&nbsp;'; } ?&gt;
<td&lt;?php echo $class ?&gt;>&lt;?php echo $cell ?&gt;</td>&lt;?php endforeach ?&gt;
</tr>&lt;?php endforeach ?&gt;
</table>
#10

[eluser]sophistry[/eluser]
[quote author="xwero" date="1236952876"]You are right but I think the better question is when do you need to break up a single array to create a table? And do you show the cell borders in that situation? [/quote]

yes, i agree. i never rely on that feature of the table class except in calendar generation. my other table usage scenario is database display which of course has equal column numbers in every row.

sometimes it's easier to argue about tiny little distractions and opinions on syntax than it is to realize what you are arguing about!

thanks for the code submission and nice discussion, xwero.




Theme © iAndrew 2016 - Forum software by © MyBB