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) {
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));
}On line 15 change RepairRequest for your object and on line 24 change the partials path to yours.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') ?>
<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>This partial will be rendered by the ajax call to getList.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
}
