After some research I found to great posts:
- jQuery DataTables and Symfony This post uses jQuery and Datatables to update a list. I took a look at the jQuery plugin Datatables and it looks great. But since I'm including actions in my tables and didn't know how to implement them on Datatables I went and look for something a bit more simple.
- Symfony Tips & Tricks IV: Generalized & Ajax Pagination This post extends the sfDoctrinePager to generate the pagination navigation. I'm unclear why to extend the sfDoctrinePager to do this, but since I'm new to Symfony I won't question the authors approach. What I did did was implement his pagination with jQuery but I included the sorting too.
- Symfony: How to render a partial from an action: What I was missing was a way to render the data in simple way without messing with JSON and building the tables with jQuery (wich is what Datatables does).
Creating an Ajax Pagination Control
Create a file named /myproject/apps/myapplication/templates/_ajax_pagination_control.php and copy the following code on it. Then save it.<div class="pagination">
<a href="#" onclick="loadPage(1);">
<?php echo image_tag('/images/first.png', array('alt' => __('First page', array(), 'sf_admin'), 'title' => __('First page', array(), 'sf_admin'))) ?>
</a>
<a href="#" onclick="loadPage(<?php echo $pager->getPreviousPage() ?>);">
<?php echo image_tag('/images/previous.png', array('alt' => __('Previous page', array(), 'sf_admin'), 'title' => __('Previous page', array(), 'sf_admin'))) ?>
</a>
<?php foreach ($pager->getLinks() as $page): ?>
<?php if ($page == $pager->getPage()): ?>
<?php echo $page ?>
<?php else: ?>
<a href="#" onclick="loadPage(<?php echo $page ?>);"><?php echo $page ?></a>
<?php endif; ?>
<?php endforeach; ?>
<a href="#" onclick="loadPage(<?php echo $pager->getNextPage() ?>);">
<?php echo image_tag('/images/next.png', array('alt' => __('Next page', array(), 'sf_admin'), 'title' => __('Next page', array(), 'sf_admin'))) ?>
</a>
<a href="#" onclick="loadPage(<?php echo $pager->getLastPage() ?>);">
<?php echo image_tag('/images/last.png', array('alt' => __('Last page', array(), 'sf_admin'), 'title' => __('Last page', array(), 'sf_admin'))) ?>
</a>
</div>
Editing the Action
Open your actions.php file and change it to look like this:
public function executeIndex(sfWebRequest $request) {On line 15 change RepairRequest for your object and on line 24 change the partials path to yours.
if ($request->getParameter('sort') && $this->isValidSortColumn(
$request->getParameter('sort'))) {
$this->setSort(array($request->getParameter('sort'),
$request->getParameter('sort_type')));
}
$items_x_page = sfConfig::get('app_max_items_x_page');
$this->pager = $this->getPager($request);
$this->sort = $this->getSort();
}
protected function getPager(sfWebRequest $request){
$items_x_page = sfConfig::get('app_max_items_x_page');
$pager = new sfDoctrinePager('RepairRequest', $items_x_page); // Table, items per page
$pager->setQuery($this->buildQuery());
$pager->setPage($request->getParameter('page', 1)); // actual page
$pager->init();
return $pager;
}
public function executeGetList(sfWebRequest $request) {
$pager = $this->getPager($request);
$sort = $this->getSort();
return $this->renderPartial('repairrequest/list',
array('pager' => $pager, 'sort' => $sort));
}
Creating the List Partial
Create /myproject/apps/myapplication/modules/mymodule/templates/_list.php file with a code that looks like the following. You will have to adjust for your project.
<?php use_helper('I18N') ?>This partial will be rendered by the ajax call to getList.
<div id="loading"></div>
<table class="datalist">
<thead>
<tr>
<th><input type="checkbox" id="masterCheck"name="master" value="bar" /> </th>
<th>
<?php include_partial('global/sortable_header', array('fieldname' => 'id',
'fieldlabel' => 'Id', 'routename' => '@repairrequest', 'sort' => $sort)) ?>
</th>
<th>
<?php include_partial('global/sortable_header', array('fieldname' => 'requestDate',
'fieldlabel' => 'Request Date', 'routename' => '@repairrequest', 'sort' => $sort)) ?>
</th>
<th>
<?php include_partial('global/sortable_header', array('fieldname' => 'location',
'fieldlabel' => 'Location', 'routename' => '@repairrequest', 'sort' => $sort)) ?>
</th>
<th><?php echo __('Description', array(), 'messages') ?></th>
<th>
<?php include_partial('global/sortable_header', array('fieldname' => 'rt.name',
'fieldlabel' => 'Repair Type', 'routename' => '@repairrequest', 'sort' => $sort)) ?>
</th>
<th>
<?php include_partial('global/sortable_header', array('fieldname' => 'repair_status_id',
'fieldlabel' => 'Repair Status', 'routename' => '@repairrequest', 'sort' => $sort)) ?>
</th>
<th>
<?php include_partial('global/sortable_header', array('fieldname' => 'real_state_id',
'fieldlabel' => 'Real State', 'routename' => '@repairrequest', 'sort' => $sort)) ?>
</th>
<th><?php echo __('Updated at', array(), 'messages') ?></th>
<th><?php echo __('Actions', array(), 'messages') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($pager->getResults() as $i => $repair_request): ?>
<tr>
<td><?php include_partial('global/list_td_batch_actions', array('obj' => $repair_request)) ?></td>
<td><a href="<?php echo url_for('repairrequest/show?id=' . $repair_request->getId()) ?>">
<?php echo $repair_request->getId() ?></a></td>
<td><?php echo format_date($repair_request->getRequestDate(),
sfConfig::get('app_string_date_format')) ?>
</td>
<td><?php echo $repair_request->getLocation() ?></td>
<td><?php echo $repair_request->getDescription() ?></td>
<td><?php echo $repair_request->getRepairType() ?></td>
<td><?php echo $repair_request->getRepairStatus() ?></td>
<td><?php echo $repair_request->getRealState() ?></td>
<td class="long_date"><?php echo format_date($repair_request->getUpdatedAt(),
sfConfig::get('app_string_datetime_format')) ?></td>
<td>
<?php include_partial('global/list_td_actions', array('module'
=> 'repairrequest', 'obj' => $repair_request)) ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
<tfoot>
<tr><td colspan="10">
<?php include_partial('global/page_numbers', array('pager' => $pager)) ?>
<?php include_partial('global/ajax_pagination_control', array('pager' => $pager, 'module' => 'repairrequest')) ?>
</td></tr>
</tfoot>
</table>
<script type="text/javascript">
$('input#masterCheck').click(function(){
var chks = $('td input[name^=ids]');
if($(this).is(':checked')){
chks.attr('checked', true)
}else{
chks.attr('checked', false)
}
}
);
$('tbody tr:even').addClass('even');
$('tbody tr:odd').addClass('odd');
</script>
Open your /myproject/apps/myapplication/modules/mymodule/templates/indexSuccess.php .
<?php use_helper('I18N') ?>
<h1>Repair requests List</h1>
<form action="<?php echo url_for('repairrequest/batch') ?>" method="post">
<div id="data">
<?php include_partial('list', array('pager' => $pager, 'sort' => $sort)) ?>
</div>
<a href="<?php echo url_for('repairrequest/new') ?>">New</a>
<?php include_partial('list_batch_actions', array()) ?>
</form>
<script type="text/javascript">
// as we have the <div id="data"> we'll completely reload it's contents
var container = jQuery("#data");
$('#loading').hide();
// note that you'll need a routing for the offers index to point to module: offers, action: index..
var url = "<?php echo url_for("repairrequest/getList"); ?>";
function loadPage(page)
{
$.ajax({
url: url+"?page="+page,
type: 'POST',
dataType: 'html',
timeout: 4000,
beforeSend: function(){
$('#loading').show();
},
complete: function(){
$('#loading').hide();
},
error: function(xhr, textStatus, errorThrown){
msg = "Error " + errorThrown;
alert(msg);
},
success: function(data){
container.html(data);
}
});
}
</script>
Editing the CSS
To get a gif to show while the data is uploading you'll need an animated gif. You can create one online athttp://www.ajaxload.info/.
open your main.css file and add the following code:
#loading{
background: url(../images/ajax-loader_2.gif) no-repeat center;
position: relative;
top: 50%;
left: 50%;
height: 40px;
width: 40px
}
Gracias Luis,
ResponderEliminarSoy nuevo en Symfony. Me sirvió muchísimo este post para un proyecto que recién empiezo.
Hasta pronto,
Héctor F. Spitia
Great tutorial Luis.
ResponderEliminarThank you for putting it up.
I am getting a 404 error on the load function. Any ideas why this could be happening?
-Mo