Package home | Report new bug | New search | Development Roadmap Status: Open | Feedback | All | Closed Since Version 0.1.5

Request #8237 Can't use multiple grids on the same page
Submitted: 2006-07-18 12:44 UTC
From: alexkunin at gmail dot com Assigned: olivierg
Status: Closed Package: Structures_DataGrid_Renderer_Smarty (version CVS)
PHP Version: Irrelevant OS:
Roadmaps: (Not assigned)    
Subscription  


 [2006-07-18 12:44 UTC] alexkunin at gmail dot com (Alex Kunin)
Description: ------------ There is no possibility to render several grids within same Smarty template - their variables will overlap. Of course, we can create another instance of Smarty, render grid inside it, and then pass ready HTML code to main template, but this does not look right (actually, this looks like a workaround). Test script: --------------- Here is a patch that solves the problem: --- old\Smarty.php Tue Jul 18 15:11:37 2006 +++ Smarty.php Tue Jul 18 15:15:51 2006 @@ -180,17 +180,17 @@ $id = __CLASS__ . '::' . __FUNCTION__; return PEAR::raiseError("$id: no Smarty container loaded"); } - $this->_smarty->assign('currentPage', $this->_page); - $this->_smarty->assign('recordLimit', $this->_pageLimit); - $this->_smarty->assign('columnsNum', $this->_columnsNum); - $this->_smarty->assign('recordsNum', $this->_recordsNum); - $this->_smarty->assign('totalRecordsNum', $this->_totalRecordsNum); - $this->_smarty->assign('pagesNum', $this->_pagesNum); - $this->_smarty->assign('firstRecord', $this->_firstRecord); - $this->_smarty->assign('lastRecord', $this->_lastRecord); - $this->_smarty->assign('currentSort', $this->_currentSort); + $this->_smarty->assign($this->_requestPrefix . 'currentPage', $this->_page); + $this->_smarty->assign($this->_requestPrefix . 'recordLimit', $this->_pageLimit); + $this->_smarty->assign($this->_requestPrefix . 'columnsNum', $this->_columnsNum); + $this->_smarty->assign($this->_requestPrefix . 'recordsNum', $this->_recordsNum); + $this->_smarty->assign($this->_requestPrefix . 'totalRecordsNum', $this->_totalRecordsNum); + $this->_smarty->assign($this->_requestPrefix . 'pagesNum', $this->_pagesNum); + $this->_smarty->assign($this->_requestPrefix . 'firstRecord', $this->_firstRecord); + $this->_smarty->assign($this->_requestPrefix . 'lastRecord', $this->_lastRecord); + $this->_smarty->assign($this->_requestPrefix . 'currentSort', $this->_currentSort); - $this->_smarty->register_function('getPaging', + $this->_smarty->register_function($this->_requestPrefix . 'getPaging', array(&$this, '_smartyGetPaging')); } @@ -236,7 +236,7 @@ $prepared[$index]['label'] = $spec['label']; } - $this->_smarty->assign('columnSet', $prepared); + $this->_smarty->assign($this->_requestPrefix . 'columnSet', $prepared); } /** @@ -247,7 +247,7 @@ */ function buildBody() { - $this->_smarty->assign('recordSet', $this->_records); + $this->_smarty->assign($this->_requestPrefix . 'recordSet', $this->_records); } /** Bad news: 1. It breaks compatibiliy (however mostly theoretically since probably nobody was able to use nultiple grids before). 2. It works not so nice when grids are being generated dynamically, and Smarty code within template tries to enumerate and render several grids. And this is a real headache for me. Better way. We could pass array instead of prefixed variables: $this->_smarty->assign( $this->_requestPrefix, array( 'currentPage' => ..., 'recordLimit' => ..., ... ) ); Grid instantination (assuming requestPrefix is 'myGrid'): {include file=_typical_grid_template.html data=$myGrid} Now any variable can be accessed like this: $data.currentPage etc.

Comments

 [2006-07-29 13:13 UTC] olivierg at php dot net (Olivier Guilyardi)
Your patch and your idea to prefix Smarty variables is interesting. But please try to put links to patches instead of pasting them in here. See: http://www.phpfi.com > 2. It works not so nice when grids are being generated > dynamically, and Smarty code within template tries to > enumerate and render several grids. What's this? What's failing? > Better way. We could pass array instead of prefixed > variables. Yes, but that won't work with the getSmarty() function. We'll still need to prefix it.
 [2006-07-29 13:17 UTC] olivierg at php dot net (Olivier Guilyardi)
I meant: "it won't work with the getPaging()" function
 [2006-07-31 16:48 UTC] alexkunin at gmail dot com
> Your patch and your idea to prefix Smarty variables is > interesting. But please try to put links to patches > instead of pasting them in here. See: > http://www.phpfi.com OK, thank you for the info. I was just following the instructions. And patch was looking a bit more compact until wrapping was applied. > > 2. It works not so nice when grids are being generated > > dynamically, and Smarty code within template tries to > > enumerate and render several grids. > > What's this? What's failing? getPaging() function, as you've said. Also, let's look at the following scenario (actually implemented in my current project). There are page with few grids on them: * we have some page which shows two grids (e.g. it contains user account's info and shows list of sessions, list of groups - two grids) * and we have another page with one grid (e.g. it contains user group's info and shows list of users that belong to this group) * and we have other pages, with three or four grids I could create separate template for every page, but isn't that doubling of code? So, I'm creating one generic template which expects list of grids that will be displayed one by one. If I will pass grids as usual, then all variables will overwritten by the last grid. I can instantiate separate Smarty template for each grid, render it, and then pass array of strings (each string = complete HTML code for particular grid). I don't like this solution. I just want to do all my tasks within one Smarty instance. Also I can pass prefixed variables and list of grid prefixes. But how can I get particular variable value within the Smarty template? By constructing its name and {eval}'ing it. (Or maybe I just can't see easier way.) Looks like a workaround. Finally, I can pass something like this: $smarty->assign( 'grids', array( $firstGrid->getVariables(), $secondGrid->getVariables(), $thirdGrid->getVariables() ) ); And then {section var=i loop=grids} etc. - code is trivial (except that getPaging function). BTW, it looks like in this case I don't need anything Smarty specific - just a generic renderer which does not render anything, but only prepares all needed data as one compact hash-based structure. Maybe, something like Structures_DataGrid_Renderer_Array? > > Better way. We could pass array instead of prefixed > > variables. > > Yes, but that won't work with the getSmarty() > function. We'll still need to prefix it. Yes, exactly. And we again have to {eval}'uate composed function name. What about having one global associative array of 'grid_name' => &$ref pairs? Then we can pass exact grid name to static version of _smartyGetPaging. Sorry for the long post. Wasn't possible for me to express all this in a shorter manner.
 [2007-06-13 20:57 UTC] olivierg (Olivier Guilyardi)
It looks like one can directly access an object method from a smarty template: {$foo->bar()} That should help solving this issue.
 [2007-06-15 12:57 UTC] olivierg (Olivier Guilyardi)
Hi Alex, I think that I have implemented what you need (in CVS). Can you please tell me how it works for you? First, for simple support of multiple grids, there is the new varPrefix option. It's handy, but not enough for what you need. For more complex operations, such as the dynamic grids you use: - you can now retrieve the variables as an array with getOutput() - the variables now contain a new $datagrid reference - you can pass $datagrid to {getPaging} to display paging for an arbitrary datagrid. Example: $citygrid =& new Structures_DataGrid(10); $citygrid->setRequestPrefix('city_'); $citygrid->bind("SELECT * FROM City", $options); $countrygrid =& new Structures_DataGrid(10); $countrygrid->setRequestPrefix('country_'); $countrygrid->bind("SELECT * FROM Country", $options); $datagrids = array( $citygrid->getOutput('Smarty'), $countrygrid->getOutput('Smarty'), ); $smarty = new Smarty(); $citygrid->fill($smarty); // set up getPaging() $smarty->assign('grids', $datagrids); Then in your template: {section name=i loop=$grids} <p>Showing records {$grids[i].firstRecord} to {$grids[i].lastRecord} from {$grids[i].totalRecordsNum}, page {$grids[i].currentPage} of {$grids[i].pagesNum}</p> {getPaging datagrid=$grids[i].datagrid prevImg="<<<" nextImg=">>" separator=" | " delta="5"} [...] {/section}
 [2007-07-26 08:42 UTC] olivierg (Olivier Guilyardi)
Okay, no feedback. I believe this is fixed.
 [2008-01-23 15:52 UTC] eugenia96 (Eugenia CastaƱeda)
Hi my name is Eugenia. I have a problem with using datagrind with the last examples in this page. I implementing in the same way and the result is a pear_error that is: " Structures_DataGrid_Renderer_Smarty::init: no Smarty container loaded" any ideas : $smarty = & new smarty_connect(); $datagrid =& new Structures_DataGrid(); $datagrid->setRequestPrefix('clasi_semana'); $datagrid->bind($semanal); $renderer = $datagrid->setRenderer('Smarty'); $datagrids[0]=$datagrid->getOutput('Smarty'); $datagrid2 =& new Structures_DataGrid(); $datagrid2->setRequestPrefix('clasi_mensual'); $datagrid2->bind($mensual); $datagrids[1]=$datagrid2->getOutput('Smarty'); when i print_r(datagrids) i have that error.
 [2008-01-23 17:28 UTC] wiesemann (Mark Wiesemann)
Eugenia, please don't use the bug tracker for support questions. => http://pear.php.net/support/ (In your case the problem seems to be that you don't pass your smarty object instance to the renderer. Please refer to the documentation [*] for further details. If you have more questions, please use e.g. the pear-general mailing list.) [*] http://pear.php.net/manual/en/package.structures.structures-datagrid.structures-datagrid-renderer.smarty.php
 [2008-09-18 23:33 UTC] eugenia96 (Eugenia CastaƱeda)
i resolve my promble with this: $row1Style = "bgcolor=#dddddd align=left class=cell_b"; $row2Style = "bgcolor=#ffffff align=left class=cell_b"; $datagrid=& new Structures_DataGrid(); $datagrid->setRequestPrefix('status_'); $datagrid->bind($lable); $datagrid->setRenderer('HTMLTable'); $table=new HTML_Table('cellpadding=5 width=80% align=center border=0'); $datagrid->fill($table); $thead =& $table->getHeader(); $thead->setAttributes(array('align=center','class=cell_b')); $table->altRowAttributes(0,$row1Style,$row2Style); $table->updateColAttributes(0,"align=center"); $renderer =& $datagrid->getRenderer(); $renderer->setTableAttribute("class", "fruits"); $smarty->assign('lable', $table->toHtml()); $datagrid1=& new Structures_DataGrid(10); $datagrid1->setRequestPrefix('servicios_'); $datagrid1->bind($servicio_list); $datagrid1->setRenderer('HTMLTable'); $table1=new HTML_Table('cellpadding=5 walign=center border=0'); $datagrid1->fill($table1); $thead =& $table1->getHeader(); $thead->setAttributes(array('align=center','class=cell_b')); $table1->altRowAttributes(0,$row1Style,$row2Style); $table1->updateColAttributes(0,"align=center"); $renderer1 =& $datagrid1->getRenderer(); $renderer1->setTableAttribute("class", "fruits"); $pagingHtml = $renderer1->getPaging(); $smarty->assign('pagingHtml', $pagingHtml); $smarty->assign('servicios_grid', $table1->toHtml());