Over time, it has been extended and rewritten to interact with our CriteriaBuilder (read blog).
This week, I’ve been refactoring/cleaning the code to clearly separate the code for our Propel driven datagrid from the basic html grid whose data could come from anywhere.
Underlying code
Due to several questions about releasing this code, here is some insight in how the code is structured, at this moment. Perhaps it will be released in the future, perhaps even as a symfony plugin, but we’re still indecisive about that.So, we have an abstract grid class which contains all code needed to generate a basic html table. It has an array $columns, which holds grid_columns, and an $options array to manipulate its behaviour. One of them is the option â “pagable”, and if enabled the grid has to have a grid_pager set.
Grid_pager is an interface which defines what methods a pager (at least) should have and our grid_propel_pager implements that interface.
On __toString, the abstract function initfirstload is called. Its purpose is to set all columns and options, i.e. to define the grid. Then it calls display, which calls initdisplay. This function will do everything that has to be done before actually displaying the grid. The difference is that tostring is called once, and thus initfirstload too, while display & initdisplay are called multiple times through xajax.
The displayHeader function calls displayHeaderon each column. The displayRows method is abstract. For a very simple grid it could call displayContent on each column.A grid_column holds all data for showing an html column, like its header name, alignment, whether it’s shown, sortable, etc… It has the following display methods (among others): displayHeader & displayContent, which obviously return th and td strings.
Now that’s all pretty abstract !
Here’s how we use all of that in our grid_propel class, which uses grid_column_propels. The idea is that we could represent a table’s data fetched via Propel.Grid_propel extends the grid_paged class (containing the code for a grid to be paged via xajax), which extends the abstract grid class. Some display methods are overridden and the abstract displayRows method is implemented. It loops all objects we retrieve from the grid_propel_pager (which implements the grid_pager interface, remember). In the loop, displayContent is called on eachcolumn and the object is passed.
Grid_column_propel extends grid_column_method which extends grid_column. In grid_column_propel::displayContent, we use call_user_func_array to retrieve the content to be shown. It also has a guessGetter method which guesses the method based on the column’s peer constant name, so you don’t have to provide it!
And voila, we have a fully Propel driven html table, which is sorted and paged via xajax.
Put it to work!
If that’s Chinese to you, don’t worry because of the great principle of encapsulation:YOU DON’T HAVE TO UNDERSTAND IT!
Or to quote the textbookYou don’t have know how a car works to drive it!Simply define your object class and columns that need to be shown. That’s all! Grid_propel will do the work for you!
Here’s an example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class grid_users extends grid_propel {
public function __construct($name) {
parent::__construct($name,"_User");
}
public function init_firstload() {
$this->option_enable("sortable");
$gridcontent = page_minimal::get_grid_contentobject();
$bid = new grid_column_propel("id",_UserPeer::ID);
$bid->display = false;
$this->column_add_unique($bid);
$this->column_add(new grid_column_propel($gridcontent->getContent("Login"), _UserPeer::LOGIN, "", 40));
$this->column_add(new grid_column_propel($gridcontent->getContent("First Name"), _UserPeer::NAME_FIRST, "", 40));
$this->column_add(new grid_column_propel($gridcontent->getContent("Family Name"), _UserPeer::NAME_FAMILY, "", 40));
$this->column_add(new grid_column_propel($gridcontent->getContent("Email"), _UserPeer::EMAIL, "", 100));
$this->column_add(new grid_column_propel($gridcontent->getContent("Country"), _CountryPeer::COUNTRY, array("get_Country", "getCountryShort"), 25, "center"));
}
} |

You can also use your own methods (not propel-generated)!
This really blows the grid wide open. You can call any method for the grid’s object class. You can even pass an array of methods. Every method is called on the result for the last call. The last method should of course return a string.For example, adding
1 2 3 | $view = new grid_column_method("", "getLink", 10, "center"); $view->setArgs(array(false, true)); $this->column_add($view); |

1 | $view = new grid_column_propel("", "", "getLink", 10, "center"); |
Foreign key values
Our user grid also contains a special column, Country. It’s actually a foreign key for the _user table.1 | $this->column_add(new grid_column_propel($gridcontent->getContent("Country"), _CountryPeer::COUNTRY, array("get_Country", "getCountryShort"), 25, "center")); |
We also provide an alternative method array, otherwise the getter is guessed by grid_column_propel, which would result in the methodarray(->get_Country->getCountry).
Other descendants of grid_column
We have also created a special grid_column, grid_action, which almost does the same as the information image. But again, it groups code.Grid_action_url extends this class and its goal is to easy generate such images.
1 | $this->action_add(new grid_action_url("application_edit.jpg","","/userid/", "", 15)); |
1 | $this->action_add(new grid_action_js_delete("_User","Delete")); |
That’s all pretty neat, isn’t it? But, of course, that ain’t enough !
Last week I’ve added some functionality to export the datagrid to an excel workbook using the Spreadsheet_Excel_Writer class. Grid_column_propel accepts extra arguments1 | $excelwidth=null, $excelname=null, $exportmethod=null, $exportargs=null, $export=true")); |
You could also add columns (propel or method) to the grid which will only appear in the excel file, by simply disabling display for that column. Soon, I’ll add an extra argument $format, to control the layout in excel, column per column. And some constants to represent often used formatting.
All together, our user grid looks like this

If that still isn’t enough for you…
There’s also a class called grid_hook, which uses a grid_column_checkbox. Without going into details, this code1 | $this->addHook(new grid_hook(page_minimal::get_grid_contentobject()->getContent("edit"),"multiEdit")); |
No comments:
Post a Comment