Nothing special but some of you had problems putting it together. So, i decided to write simple tutorial describing how to use jquery Flexigrid with Symfony. I will use the same data as in the tutorial: Zend Framework + Doctrine + jQuery Grid . Eveything will be the same, except that we will use Symfony instead of Zend.
First we need to create new symfony project:
symfony generate:project someProjectName
or simply download sf_sandbox.
Next step is to create symfony app:
symfony generate:app frontend
Then we need one module, for example “grid”:
symfony generate:module frontend grid
Ok. So far, we have basic application structure. It’s time to set up database:
symfony configure:database “mysql:host=localhost;dbname=yourDb” user pass
As i said, we will use the same data as in the Zend + flexigrid example. So, paste the following schema into your schema.yml file:
propel:
country:
_attributes: { phpName: Country }
id:
name: varchar(50)
description: varchar(255)
I’m using propel, Doctrine schema you will find in post about Zend + Doctrine + jQuery grid.
Put some data into the fixtures.yml file:
Country:
Country_1:
name: 'Poland'
description: 'Description for Poland'
Country_2:
name: 'Germany'
description: 'Description for Germany'
Country_3:
name: 'Brazil'
description: 'Description for Brazil'
Country_4:
name: 'USA'
description: 'Description for USA'
Country_5:
name: 'Ireland'
description: 'Description for Ireland'
Country_6:
name: 'Canada'
description: 'Description for Canada'
Country_7:
name: 'India'
description: 'Description for India'
Country_8:
name: 'Italy'
description: 'Description for Italy'
Country_9:
name: 'Spain'
description: 'Description for Spain'
Country_10:
name: 'Portugal'
description: 'Description for Portugal'
Country_11:
name: 'Argentina'
description: 'Description for Argentina'
Country_12:
name: 'Estonia'
description: 'Description for Estonia'
Country_13:
name: 'Bulgaria'
description: 'Description for Bulgaria'
Country_14:
name: 'France'
description: 'Description for France'
Country_15:
name: 'Belgium'
description: 'Description for Belgium'
Country_16:
name: 'Austria'
description: 'Description for Austria'
Country_17:
name: 'Australia'
description: 'Description for Australia'
Country_18:
name: 'Japan'
description: 'Description for Japan'
Country_19:
name: 'Russia'
description: 'Description for Russia'
Country_20:
name: 'Slovakia'
description: 'Description for Slovakia'
Country_21:
name: 'Ireland'
description: 'Description for Ireland'
And now in the command prompt call:
symfony propel:build-sql
symfony propel:build-model
symfony propel:insert-sql
symfony propel:data-load
After that download jQuery flexigrid library and put it into web/js directory. Move css files from flexigrid/css/ to web/css/.
We need to configure view.yml:
default:
http_metas:
content-type: text/html
metas:
title: symfony + jQuery Flexigid
#description: symfony project
#keywords: symfony, project
#language: en
#robots: index, follow
stylesheets: [main.css, flexigrid/flexigrid.css]
javascripts: [flexigrid/lib/jquery/jquery.js, flexigrid/flexigrid.js]
has_layout: on
layout: layout
I also want to show you how simple and beautiful is DbFinderPlugin. First install plugin:
symfony plugin:install DbFinderPlugin
The DbFinder is a symfony plugin that provides an easy API for finding Model objects, whether the underlying ORM is Propel or Doctrine.
The idea behind this plugin is to write queries to retrieve model objects through an ORM, but fast. Inspired by Doctrine, Rails has_finder plugin and SQLAlchemy, DbFinder can be seen as “jQuery for symfony’s model layer”. It also aims at putting the things in the right order, meaning that writing a find() query will feel natural for those familiar with SQL. (from www.symfony-project.org)
Now we can start coding
Open grid/actions/actions.class.php and pass my code:
<?php
class gridActions extends sfActions
{
/**
* Executes index action
*
* @param sfRequest $request A request object
*/
public function executeIndex(sfWebRequest $request)
{
}
public function executeList(sfWebRequest $request)
{
# forward unless it is ajax request
$this->forward404Unless($request->isXmlHttpRequest());
# Pagination parameters
$currentPage = $request->getParameter('page', 1);
$resultsPerPage = $request->getParameter('rp', 10);
# Sort parameters
$orderBy = $request->getParameter('sortname', 'name');
$orderType = $request->getParameter('sortorder', 'ASC');
# Query parameters
$query = $request->getParameter('query', '');
$qtype = $request->getParameter('qtype', 'name');
# Creating DbFinder Pager
$pager = DbFinder::from('Country')
->where($qtype, 'LIKE', "%$query%")
->orderBy($orderBy, $orderType)
->paginate($currentPage, $resultsPerPage);
$elements = array();
# Get data from Pager
foreach($pager->getResults() as $item){
$elements[] = array(
'id' => $item->getId(),
'cell' => array_values($item->toArray())
);
}
echo json_encode(array(
'page' => $currentPage,
'total' => $pager->getNbResults(),
'rows' => $elements
));
# return action wihout renderig template
return sfView::NONE;
}
}
?>
Then simply open grid/templates/indexSuccess.php and paste:
<h1> Symfony + jQuery FlexiGrid </h1>
<table id="sfGrid"></table>
<!-- updated to work with IE -->
<script language="javascript" type="text/javascript">
$("#sfGrid").flexigrid
(
{
url: "<?php echo url_for('grid/list') ?>",
dataType: 'json',
colModel : [
{display: 'Id', name : 'id', width : 40, sortable : true, align: 'center'},
{display: 'Name', name : 'name', width : 100, sortable : true, align: 'left'},
{display: 'Description', name : 'description', width : 200, sortable : true, align: 'center'}
],
buttons : [
{name: 'Add', bclass: 'add', onpress : test},
{name: 'Delete', bclass: 'delete', onpress : test},
{separator: true}
],
searchitems : [
{display: 'Name', name : 'name'}
],
sortname: "name",
sortorder: "asc",
usepager: true,
title: 'List',
useRp: true,
rp: 10,
showTableToggleBtn: true,
width: 700,
height: 200
}
);
function test(com, grid){
$(".trSelected > td:first-child > div:first-child").each( function(index, element){
alert($(element).html());
}
);
}
</script>
To see result paste in the browser following url: http://localhost/someProjectName/web/grid.
Enyoj.
Polecam również przestudiowanie Zend Framework + jQuery. Zend posiada bardzo ciekawe rozwiązania dużo ułatwiające normalną pracę.
więcej
Hi!
This method does work with doctrine?Because i have a problem
Yes, it does. What kind of problem have you got?
I have a problem with url in indexSuccess.php = url: “”. So, i used a js file for the flexigrid and i call in my indexSuccess.php the flexigrid. With firebug, i have 1 problem : my post is forbidden “You don’t have permission to access /qualims2/web/< on this server “. I use Symfony 1.2, jquery and jquery ui, doctrine.
What kind of problem? Blank url? If you do not have permission to access your serwer, you need to change it. For more details write me a e-mail, so we can solve the problem.
Thanks for the nice tutorial, Kamil!
For me for me it works with slight changes -
in actions.class.php instead of
echo json_encode(xxx)
return sfView::NONE;
I use
$this->json_result = json_encode(xxx);
and in template just
echo $json_result
Additionaly you need to edit /apps/yourapp/modules/yourmodule/config/view.yml
yourtemplateSuccess:
has_layout: off
all:
has_layout: on
stylesheets: []
Yes, you are right. We can just simply call:
return json_encode(array(
‘page’ => $currentPage,
‘total’ => $pager->getNbResults(),
‘rows’ => $elements
));
Bu We don’t need to turn off the layout. Symfony will automatically do that for us.
Nice job on the tutorial!
I found one problem though. I’m not sure if anyone else has encountered it. When loading via /frontend_dev.php/grid I get a “Processing, please wait …” message. I’m using doctrine.
Hi.
I’m quite sure that you have some errors in your executeList Action, so your are not receiving the respone.
Hi, I get a “Processing, please wait …” message never end in my tmplate. I use Propel…
this my action:
# forward unless it is ajax request
$this->forward404Unless($request->isXmlHttpRequest());
//$this->getResponse()->setContentType(’application/json’);
# Pagination parameters
$currentPage = $request->getParameter(’page’, 1);
$resultsPerPage = $request->getParameter(’rp’, 10);
# Sort parameters
$orderBy = $request->getParameter(’sortname’, ‘nama_provinsi’);
$orderType = $request->getParameter(’sortorder’, ‘ASC’);
# Query parameters
$query = $request->getParameter(’query’, ”);
$qtype = $request->getParameter(’qtype’, ‘nama_provinsi’);
# Creating DbFinder Pager
$pager = DbFinder::from(’RProvinsi’)->
orderBy($orderBy, $orderType)->
paginate($currentPage, $resultsPerPage);
/* $c= new Criteria();
$c->add(RProvinsiPeer::NamaProvinsi,”%$query”,Criteria::LIKE);
($orderType==”ASC”)?$c->addAscendingOrderByColumn ($orderBy):$c->addDescendingOrderByColumn ($orderBy);
$c->setLimit($resultsPerPage);
$c->setOffset(($currentPage-1)*$resultsPerPage);
$pager=RProvinsiPeer::doSelect($c);*/
$elements = array();
# Get data from Pager
foreach($pager->getResults() as $item){
$elements[] = array(
‘id’ => $item->getKodeProvinsi(),
‘cell’ => array_values($item->toArray())
);
}
echo json_encode(array(
‘page’ => $currentPage,
‘total’ => $pager->getNbResults(),
‘rows’ => $elements
));
# return action wihout renderig template
return sfView::NONE;
Can You Fix this??
Poor English
Yes, i can fix it. Show me your response from server or just send me your code. I will do my best to help you.
Cheers.
In executeList action You must set up the response:
$this->getResponse()->setHttpHeader(’Content-Type’, ‘application/json; charset=utf-8′);
And modify:
echo json_encode(array(
‘page’ => $currentPage,
‘total’ => $pager->getNbResults(),
‘rows’ => $elements
));
return sfView::NONE;
with:
$resultado = json_encode(array(
‘page’ =>$currentPage,
‘total’ =>$pager->getNbResults(),
‘rows’ =>$elements
));
return $this->renderText(’(’.$resultado.’)');
return sfView::NONE;
We should set up the response but we don’t have to.
Best solution for me is:
$this->getResponse()->setHttpHeader(’Content-Type’, ‘application/json; charset=utf-8′);
return $this->renderText(json_encode(array(
‘page’ =>$currentPage,
‘total’ =>$pager->getNbResults(),
‘rows’ =>$elements
)));
Calling:
return sfView::NONE;
in this case is not necessary.
Hi.
I have found this tutorial very helpful.
Please mail me the example
C:\xampp\htdocs\sf_sandbox>symfony propel:build-sql
There are no tasks defined in the “propel” namespace.
C:\xampp\htdocs\sf_sandbox>
please advise
thank you
Which symfony version are you using? 1.4.X or 1.2.X ?
i have the same problem with symfony 1.4
i have enabled the plugin and configure my project to use propel but when i checked on the available commands, no commands for propel..
why is that?
If you create new project - the easiest way is to:
symfony generate:project xxx –orm=Propel
but i would strongly recommend Doctrine/
Cheers