Smarty Forum Index Smarty
The discussions here are for Smarty, a template engine for the PHP programming language.
Dynamic Table Columns
Goto page 1, 2  Next
 
Post new topic   Reply to topic    Smarty Forum Index -> Tips and Tricks
View previous topic :: View next topic  
Author Message
boots
Administrator


Joined: 16 Apr 2003
Posts: 5613
Location: Toronto, Canada

PostPosted: Tue Nov 11, 2003 10:39 pm    Post subject: Dynamic Table Columns Reply with quote

messju posted this on the IRC channel. It is an update of Monte's tried and true solution but takes advantadge of 2.6's math features to be a bit cleaner:

Code:
{* $cols is the number of columns you want *}
<table border=1>
  {section name=tr loop=$data step=$cols}
  <tr>
    {section name=td start=$smarty.section.tr.index
loop=$smarty.section.tr.index+$cols}
    <td>{$data[td]|default:"& nbsp;"}</td>     
    {/section}
  </tr>
  {/section}
</table>


Thanks messju!

NOTE: "& nbsp;" above should have no space--but this forum doesn't like that
Back to top
View user's profile Send private message
thawes
Smarty n00b


Joined: 14 Nov 2003
Posts: 2

PostPosted: Sun Nov 16, 2003 10:59 am    Post subject: Better way for dynamic columns Reply with quote

I am an old hat with CGI programming, and a greenhorn with PHP. I am bit of a purist when it comes to template engines and the seperation of logic and presentation. I do not believe that any logic should ever be in the web page and that html should never be in the logic.

Here is the purist's approach, and I believe this is equally valid with Smarty 2.50 and 2.6:

The template would look as simple as this:

Code:

<table border="1">
<!-- {section name=myrow loop=$test} -->
  <tr valign="top">
    <!-- {section name=mycolumn loop=$test[myrow]} -->
      <td>
         <!-- {$test[myrow][mycolumn]} -->
      </td>
    <!-- {/section} -->
  </tr>
<!-- {/section} -->
</table>


The php code that calls this template would look something like this:

Code:

// Creates a two dimensional array using
// Pear::DB as an example

while ($row[$x] = $result->fetchRow())
  {
    $x++;
  }

$smarty->assign('test', $row);

// display it
$smarty->display('index.tpl');
Back to top
View user's profile Send private message
thawes
Smarty n00b


Joined: 14 Nov 2003
Posts: 2

PostPosted: Sun Nov 16, 2003 11:47 am    Post subject: Better dynamic columns Reply with quote

Let's say I need table headings for my columns. What to do?

If your data happens to be comming from an SQL database, you are in good shape. You create your table headings from your SQL call. Here's what it looks like:

Template file index.tpl
Code:

<table border="1">
  <tr valign="top" align="center">
  {section name=col loop=$headers}
      <th>{$headers[col]}</th>
  {/section}
  </tr>
  {section name=myrow loop=$test}
  <tr valign="top">
    {section name=mycolumn loop=$test[myrow]}
      <td>
         {$test[myrow][mycolumn]}
      </td>
    {/section}
  </tr>
  {/section}
</table>


OK, now for the calling PHP. I am using Pear::DB as my example.
PHP file index.php
[php:1:6a817c777e]
<?php
include_once("DB.php");

// create object
$smarty = new Smarty;

$dsn = "dbtype://username:password@hostname/dbname";
$db = DB::connect($dsn, true);
if (DB::isError($dsn))
die ($db->getMessage());

/*
* Here is the SQL statement we use to specify
* our table headings.
*/
$sql = "SELECT
first_name AS \"First name\",
last_name AS \"Last Name\",
company AS \"Company\",
address_1 AS \"Address 1\",
address_2 AS \"Address 2\",
city AS \"City\",
state AS \"State\",
zip_code AS \"Zip Code\",
tel_work AS \"Phone (Work)\",
tel_cell AS \"Cell\",
tel_fax AS \"FAX\",
email AS \"Email\",
url AS \"Website\"
FROM contacts
ORDER BY last_name";

$result = $db->query($sql);

if (DB::isError($result))
die ($result->getMessage());


// Initialize some new variables we will now use.
$head;
$hash;
$row;
$x = 0;

/*
* Important to create an associative array, as this will
* return the headers as we had specified in our SQL
* statement.
*/
$hash = $result->fetchRow(DB_FETCHMODE_ASSOC);
$head = array_keys($hash);
$row[$x] = array_values($hash);
$x++;

// Now we fetch the other rows from our query.
while ($hash = $result->fetchRow(DB_FETCHMODE_ASSOC))
{
$row[$x] = array_values($hash);
$x++;
}

// Create Smarty arrays.
$smarty->assign('headers', $head);
$smarty->assign('test', $row);

// display it
$smarty->display('index.tpl');
?>
[/php:1:6a817c777e]

The out put will look something like:
<table border="1">
<tr valign="top" align="center">
<th>First name</th>
<th>Last Name</th>
<th>Company</th>
<th>Address 1</th>
<th>Address 2</th>
<th>City</th>
<th>State</th>
<th>Zip Code</th>
<th>Phone (Work)</th>
<th>Cell</th>
<th>FAX</th>
<th>Email</th>
<th>Website</th>
</tr>
<tr valign="top">
... the rest of your data.


It were not for Smarty, I would not even consider PHP.
Back to top
View user's profile Send private message
webadept
Smarty Regular


Joined: 09 Mar 2004
Posts: 41

PostPosted: Tue Jul 27, 2004 12:04 pm    Post subject: Reply with quote

So if I'm working with displaying an array-of-arrays then I use the foreach with this .. correc?
Code:

{* $cols is the number of columns you want *}
<table border=1>
{foreach from=$data item=myd}
  {section name=tr loop=$myd step=$cols}
  <tr>
    {section name=td start=$smarty.section.tr.index loop=$smarty.section.tr.index+$cols}
    <td>{$myd[td]|default:"&"}</td>     
    {/section}
  </tr>
  {/section}
  {/foreach}
</table>



or is there a better way to do this (not that this doesn't appear to work just fine.

Embarassed I got thrown by the single level array thing, cause I use them so very little, I just assumed this worked on multi-dem arrays

php area
Code:



 $sql = 'SELECT * '
        . ' FROM zip'
        . ' LIMIT 20 ';
 // using mysql php for demo purpose in here //       
$r = mysql_execute($sql);
$i=0;
 while($mydat[$i] = mysql_fetch_array($r, MYSQL_NUM))
  {
     $i++;
  }
$smarty->assign("data", $mydat);
$smarty->assign("cols", 7);

$smarty->display("maketable.tpl");


webadept --out
Back to top
View user's profile Send private message
z0ink
Smarty n00b


Joined: 27 Jul 2004
Posts: 1

PostPosted: Tue Jul 27, 2004 8:32 pm    Post subject: Reply with quote

I'm new to smarty. I liked the idea of aliasing the column names and using that as the table headers, but it would have broken my assosciative system already in use. Here is how I have my headers setup to support changing the order of the data (ascending, descending):

php:
Code:

// get sort id (column) and order_id(asc/desc) -- stripped of error checking
$_GET['s'] = $sort_id;
$_GET['o'] = $order_id;

// create sort and order arrays -- these are used inside a sql query and below
$sort = array('product_id', 'name', 'price', 'description', 'stock');
$order = array('ASC', 'DESC');

// create header -- array(array([name] => 'product_id', [order] => 0), ...)
for($i = 0; $i < 5; $i++) {
  // look for the column i'm currently sorting by
  if($i == $sort_id) {
    $head[$i]['name'] = $sort[$i];
    // if the column i'm sorting is 0, ASC, then change DESC to the next option
    if($order_id == 0) {
      $head[$i]['order'] = 1;
    // if it's 1, DESC, the if will fail and it will become 0, ASC
    } else $head[$i]['order'] = 0;
  // assign a default of 0, ASC, for the items not being used to sort
  } else {
    $head[$i]['name'] = $sort[$i];
    $head[$i]['order'] = 0;
  }
}

$smarty->assign('head', $head);


tpl:
Code:

{assign var="i" value="0}
{section name=row loop=$head}
<th><a href="foobar.php?s={$i}&o={$head[row].order}">{$head[row].name}</a></th>
{assign var="i" value=$i+1}
{/section}


It needs some work and probably isn't the easiest to understand, but its a quick and dirty way of doing it. I don't know how effecient it is, but it's a start.
Back to top
View user's profile Send private message
iDİlE
Smarty Rookie


Joined: 18 Aug 2004
Posts: 9

PostPosted: Wed Aug 18, 2004 3:52 am    Post subject: Reply with quote

Hi,
boots your example was great!! Just one question. What if there is only one row returned from the database and your $cols is 2 per column?
At the moment it just returns a blank column, which would be fine except that it returns an image. so I get broken image link. Is there anyway to display remainders with a max number of columns X? .. If that made any sense at all Laughing


Thanks
Joe
Back to top
View user's profile Send private message
BenFromTokyo
Smarty Rookie


Joined: 15 Oct 2004
Posts: 12
Location: Japan

PostPosted: Fri Jan 07, 2005 5:41 am    Post subject: New plugin for advanced html tables Reply with quote

Hi everyone,
I have just posted a(noter) plugin for advanced html tables:
http://smarty.incutio.com/?page=SmartyPlugins:
Quote:

table_foreach - The beauty of foreach with the power of html_table... (smarty code inside each cell as with foreach / $item and $key available in each cell / possibility of html table from array of arrays or from array of objects / possibility of nested tables... )

I would be gratefull to get some review/comment/bug checks... Wink
Thanks,
_________________
Ben
Back to top
View user's profile Send private message
wham
Smarty n00b


Joined: 14 Apr 2005
Posts: 1

PostPosted: Thu Apr 14, 2005 10:21 am    Post subject: Memory Reply with quote

Hi, I am quite new with PHP and I don't understand how PHP works with memory. These dynamic tables in SMARTY look good, but what will happen if the assigned array to loop through is realy big, for example if i have a table with 1000 rows and 15 colums? PHP has to keep all the table data in memory, doesn't it? But when I do it without SMARTY I print each row immediately as i get it from database and PHP only puts it on an output buffer or sends it to the browser. Please can you explain it to me?
Back to top
View user's profile Send private message
messju
Administrator


Joined: 16 Apr 2003
Posts: 3335
Location: Oldenburg, Germany

PostPosted: Thu Apr 14, 2005 12:49 pm    Post subject: Reply with quote

@wham: yes, you'll have the full array in memory. but with 1000 rows and 15 columns i would be more concerned about the amout of the html-code that has to travel through the net to the user, than the consumed memory during creation of the page.
Back to top
View user's profile Send private message Send e-mail Visit poster's website
boranucleare
Smarty n00b


Joined: 16 Apr 2005
Posts: 3

PostPosted: Sun Apr 24, 2005 2:13 pm    Post subject: HtmlTableAdvPlugin - an 'advanced' version of html_table Reply with quote

Hi Al, let me say I'm not a coder, so it's difficult for me understand all you are talking about.
I would like to use the HtmlTableAdvPlugin in my 2.6 smarty.
So, I cp the correctfile in the smarty plugin directory, and I modified the .tpl
[b]this is my team.tpl code:[/b]
[code]{html_table_adv loop=$data}[[name]],Hello [[name]], you're from [[city]].{/html_table_adv}[/code]
[b]My index.php page is: [/b]
...
[code]if ($Viewpeople=='no') {
$data=new Smarty;
$data = array(array('name'=>'Marc', 'city'=>'Miami'),array('name'=>'Someone', 'city'=>'Somewhere'));
$data->display('team.tpl');
}[/code]
...

The problem is that I got this error in the browser...
Fatal error: Call to a member function on a non-object in ....../index.php on line 399
[b]Let me say I need to intagrate a db call such us (in the index.php):[/b]
[code] $vis=new Smarty;
$vis->assign ('ris',$db->get_results("SELECT * FROM team WHERE People='$People' ORDER BY name" ));
$vis->display('team.tpl');[/code]

[b]and a team.tpl like:[/b]
[code]<table width="100%" border="0" >
{foreach from=$ris item="riga2"}
<tr>
<td colspan='6' ><img src="immagini/{$riga2->imag}" ><br>
{$riga2->Model}<br>{$riga2->descrizione_en}</td>
</tr>
{$riga2->tab}
{/foreach}
</table>[/code]


Is there anybody that could kindly help me?

Thanks in advance
Back to top
View user's profile Send private message
boranucleare
Smarty n00b


Joined: 16 Apr 2005
Posts: 3

PostPosted: Wed Apr 27, 2005 2:46 pm    Post subject: Re: Dynamic Table Columns Reply with quote

[quote="boots"]messju posted this on the IRC channel. It is an update of [url=http://smarty.php.net/contribs/examples/dynamic_table_columns/table.tpl.txt][u]Monte's tried and true solution[/u][/url] but takes advantadge of 2.6's math features to be a bit cleaner:

[code]{* $cols is the number of columns you want *}
<table border=1>
{section name=tr loop=$data step=$cols}
<tr>
{section name=td start=$smarty.section.tr.index
loop=$smarty.section.tr.index+$cols}
<td>{$data[td]|default:"& nbsp;"}</td>
{/section}
</tr>
{/section}
</table>[/code]

Thanks messju!

NOTE: "& nbsp;" above should have no space--but this forum doesn't like that[/quote]


Hi all,
step by step I'm trying to use the below code to put in a table the db data.
So. I'm quite happy because now I can view a table with something inside....the problem is that I can only view a table with the word OBJECT inside... What a low profile coder I am.. Smile
please have a look on my code...
PHP:
$data=new Smarty;
$data->assign ('data',$db->get_results("SELECT * FROM team ORDER BY name" ));
$data->display('team.tpl');
TEAM.TPL:
{* $cols is the number of columns you want *}
<table border=5>
{section name=tr loop=$data step=2}
<tr>
{section name=td start=$smarty.section.tr.index
loop=$smarty.section.tr.index+2}
<td>{$data[td]|default:"&"}</td>
{/section}
</tr>
{/section}
</table>


and here is the output:

Object Object
Object Object
Object Object

Could you help me?
Thks
Back to top
View user's profile Send private message
sayian
Smarty Rookie


Joined: 20 Aug 2005
Posts: 26

PostPosted: Tue Mar 07, 2006 11:21 pm    Post subject: Reply with quote

Just to let everyone know, this solution does not work.

If you have 4 rows, and you set your cols to 6.

it will add 2 rows of "bad" data ie: nothing, blank, red x's for images. ect.

The only solution i found that works so far, is the original solution posted by Monte.

Cheers.
Back to top
View user's profile Send private message
latheesan
Smarty Rookie


Joined: 06 May 2006
Posts: 10

PostPosted: Sun Jul 02, 2006 12:27 am    Post subject: Reply with quote

I've just started to using smarty recently. This is how i created my dynamic tables

test.php
[php:1:5b68b56cb2]<?php

include("inc/libs/Smarty.class.php");
$smarty = new Smarty;
$smarty->template_dir = $config["theme"] . 'templates/';
$smarty->compile_dir = $config["theme"] . 'templates_compile/';

/* Build Data */
mysql_connect($host, $user, $pass) or trigger_error("SQL", E_USER_ERROR);
mysql_select_db($db) or trigger_error("SQL", E_USER_ERROR);
$query = "SELECT * FROM category ORDER BY name ASC";
$result = mysql_query($query) or trigger_error("SQL", E_USER_ERROR);
$num = mysql_num_rows($result);
mysql_close();
$i = 0;
while($i < $num)
{
$arr = mysql_fetch_array($result);
$name = $arr["name"];
$description = $arr["description"];
$t = $arr["total"];
if($t <= 1){ $total = $t . " Profile"; } else { $total = $t . " Profiles"; }
$data[] = $name . ' (' . $total . ')<br>' . $description;
$i++;
}

/* Asign & Display Template */
$smarty->assign('data',$data);
$smarty->display('test.tpl');

?>[/php:1:5b68b56cb2]

test.tpl
Code:
{html_table table_attr='border="0" cellspacing="0" cellpadding="10"' loop=$data cols=2}


Prints table nicely in two columns:


E.g. HTML Ouput:
Code:
<table border="0" cellspacing="0" cellpadding="10">
<tr>
      <td></td>
      <td></td>
<tr>
<tr>
      <td></td>
      <td></td>
<tr>
</table>
Back to top
View user's profile Send private message
GeXus
Smarty Rookie


Joined: 16 Aug 2006
Posts: 28

PostPosted: Sat Aug 26, 2006 3:10 pm    Post subject: Reply with quote

sayian wrote:
Just to let everyone know, this solution does not work.

If you have 4 rows, and you set your cols to 6.

it will add 2 rows of "bad" data ie: nothing, blank, red x's for images. ect.

The only solution i found that works so far, is the original solution posted by Monte.

Cheers.


Sayian, You have to add an if statment within the section.. and if $var = "" do nothing, else show all your mark up.
Back to top
View user's profile Send private message
phprocket
Smarty n00b


Joined: 10 Oct 2006
Posts: 4
Location: Arkansas, United States

PostPosted: Tue Oct 10, 2006 2:53 pm    Post subject: New Version Does Work :) Reply with quote

Hi GeXus, I disagree I have just spend a little time tring to get the orginal code to work, it appears to work correctly if you have a white background but since I put a border around my tables using css I noticed that the orginal code did not put the extra

Code:
<td>&nbsp:</td>


for some reason and I got this ugly black space,

I have done some testing.. and here is my results.

With the Orginal Code

1. If you set it to 3 cols and you have 6 results it looks great but if you have 5 you got problems..

2. if you set it to 6 cols and you have 5 results you got the black space problem. But if you set 6 cols and you have 12 results it looks great.

Here is the Orginal Code I modified for my use..

Code:

{* $cols is the number of columns you want *}
{assign var='cols' value=3}
<p align=center>
<table width="600" border="0" cellspacing="1" cellpadding="1" class="phprocket-table-background-border">
    <tr>
    {section name=numloop loop=$catmain}
        <td class="phprocket-table-alt1" align="left"><a href="?c={$catmain[numloop].main.catid}">{$catmain[numloop].main.catname}</a> ({$catmain[numloop].main.catcount})</td>
        {* see if we should go to the next row *}
        {if not ($smarty.section.numloop.rownum mod $cols)}
                {if not $smarty.section.numloop.last}
                        </tr><tr>
                {/if}
        {/if}
        {if $smarty.section.numloop.last}
                {* pad the cells not yet created *}
                {math equation = "n - a % n" n=$cols a=$data|@count assign="cells"}
                {if $cells ne $cols}
                {section name=pad loop=$cells}
                        <td class="phprocket-table-alt2" align=left>&nbsp;</tr>
                {/section}
                {/if}
                </tr>
        {/if}
    {/section}
</table>



Now the new code that boots provided did not work at first because instead of assigning the var I just put the number 3 every where $cols was thinking it would work.. and I passed it off as not working then I went back and then I tried to new orginal code but this time I assigned the var $cols and it worked great for me..

I have set it $cols to 1 with 10 results and it worked great.. I set it to 3 with 10 results and it worked great. I did modify it a bit also.. to fit my needs

In the orginal new code boots had it to where only one vars was checked and a default was place, I just put in a {if}{else}{/if} so I knew if I checked one value in the array the rest would be there, allowing me to pass more than one value to get the output that I was looking for.

Code:

{* $cols is the number of columns you want *}
{assign var='cols' value=3}
<table width="600" border="0" cellspacing="1" cellpadding="1" class="phprocket-table-background-border">
  {section name=tr loop=$catmain step=$cols}
  <tr>
    {section name=td start=$smarty.section.tr.index loop=$smarty.section.tr.index+$cols}
   {if $catmain[td].main.catname|default:false}
      <td class="phprocket-table-alt1" align="left"><a href="?c={$catmain[td].main.catid}">{$catmain[td].main.catname}</a> ({$catmain[td].main.catcount})</td>
   {else}
      <td class="phprocket-table-alt2" align=left>&nbsp;</td>
   {/if}   
    {/section}
  </tr>
  {/section}
</table>





So for Smarty Verion 2.6.14 the new code from boots helped me greatly and does work and it's much cleaner, I think that was the entire point. Now that's not to say the old version does not work also, maybe there was something I missed I am not sure.. I am just letting you know what took me 2 hours to find out.. Smile

Thanks.
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    Smarty Forum Index -> Tips and Tricks All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group
Protected by Anti-Spam ACP