Bonjour !
Je viens de finir de coder un tableau paginé avec cakePHP et en Ajax (Ajax pagination). Aucuns problèmes de mise en œuvre grâce au cookbook, cela fonctionne très bien (chargement de page en ajax, gif de loading, etc.).
Seulement voilà, toutes les fonctions jQuery interne au tableau ne fonctionne plus dès que je change de page. Je poste des images pour montrer le problème :
1ère page :
Les infobulles(edit, delete), modal de confirmation et autres s'affichent sans problème.
Sur une autre page ou en revenant sur la 1ère via la pagination Ajax
Toutes les fonctions jQuery ne fonctionne plus (infobulles, modal de confirmation,...).
J'ai placé l'appel des fichiers JS en haut page (dans mon layout évidemment) mais ça ne change rien.
Voici du code si vous voulez :
Controller (actions index et edit par exemple)
class LocalitesController extends AppController {
public $components = array('RequestHandler');
public $helpers = array('Js');//Les autres helpers sont dans l'AppController
public function index() {
$this->Localite->recursive = 0;
$this->paginate = array('Localite' => array(
'order' => array('cp' => 'asc')
));
$this->set('localites', $this->paginate('Localite'));
}
public function edit($id = null) {
$this->Localite->id = $id;
if (!$this->Localite->exists()) {
throw new NotFoundException(__('Localité invalide'));
}
if ($this->request->is('post') || $this->request->is('put')) {
if ($this->Localite->save($this->request->data)) {
$this->Session->setFlash('Modification réussie','notif');
$this->redirect(array('action' => 'index','page' => $this->request'named']'page']));
} else {
$this->Session->setFlash('Impossible de modifier la localité',
'notif',array('type' => 'error'));
}
} else {
$this->request->data = $this->Localite->read(null, $id);
}
}
}
View (index vu que la pagination ajax se trouve dedans)
<?php
/* Indiquer l'utilisation d'une pagination ajax */
$this->Paginator->options(array(
'update' => '#content-localites',
'evalScripts' => true,
'before' => $this->Js->get('#busy-indicator')->effect('fadeIn', array('buffer' => false)),
'complete' => $this->Js->get('#busy-indicator')->effect('fadeOut', array('buffer' => false)),
));
?>
<div id="content-localites">
<div class="row-fluid">
<div class="span9">
<?php if($hasPages) echo $this->element('paginator'); ?>
<table class="table table-striped">
<thead>
<th><?php echo $this->Paginator->sort('cp','Code postal'); ?></th>
//écriture des autres <th>
</thead>
<tbody data-provides="rowlink">
<?php foreach ($localites as $localite): ?>
<tr class="rowlink">
//<td> avec des appel jQuery qui pose problème
<td class="nolink" style="text-align: right;">
<?php echo $this->Html->link(
__('<i class="icon-edit"></i>'),
array(
'action' => 'edit',
$localite'Localite']'id'],
'page' => $this->Paginator->current()
),
array(
'escape' => false,
'class' =>'btn btn-mini btn-edit',
'rel' => 'tooltip',//jQuery pour infobulle par exemple
'data-original-title' => 'Editer'
));
?>
<?php echo $this->Html->link(
__('<i class="icon-trash icon-white"></i>'),
array(
'action'=> 'delete',
$localite'Localite']'id'],
'page' => $this->Paginator->current()
),
array(
'escape' => false,
'class' =>'btn btn-mini btn-delete',
'rel' => 'tooltip',
'data-original-title' => 'Supprimer',
'data-title'=>'Confirmez la suppression',
'data-confirm'=>'Voulez-vous vraiment supprimer de cette localité ?',
'data-ok'=>'Supprimer',
'data-cancel'=>'Annuler'
));
?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php if($hasPages) echo $this->element('paginator'); ?>
</div>
</div>
</div>
jquery.functions (mes fonctions jQuery)
$(document).ready(function(){
//les fonctions jQuery qui ne sont pas appelées quand je change de page par pagination Ajax
//infobulles
$("[rel=tooltip]").tooltip({
placement: "bottom"
});
//modal de confirmation
$('a[data-confirm]').click(function() {
var href = $(this).attr('href');
if (!$('#dataConfirmModal').length) {
$('body').append('...');//la construction de la modal
}
$('#dataConfirmModal').find('.label-title').text($(this).attr('data-title'));
$('#dataConfirmModal').find('.modal-body').text($(this).attr('data-confirm'));
$('#dataConfirmModal').find('.modal-cancel').text($(this).attr('data-cancel'));
$('#dataConfirmModal').find('.btn-delete').text($(this).attr('data-ok'));
$('#dataConfirmOK').attr('href', href);
$('#dataConfirmModal').modal({show:true});
return false;
});
});
Layout (default)
<!DOCTYPE html>
<html xml:lang="fr" lang="fr">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title><?php echo Configure::read('App.name').' :: '.$title_for_layout; ?></title>
<!-- css -->
<?php echo $this->Html->css(array(
'bootstrap.min',
'bootstrap-responsive.min',
'bootstrap-rowlink.min',
'jquery.treeview',
'chosen/chosen',
'style',
'responsive'
));
?>
<?php echo $this->Html->script('jquery-1.8.2.min'); ?>
</head>
<body>
<div id="wrap">
<?php echo $this->Session->flash(); ?>
<!-- Menus -->
<?php echo $this->element('menu'); ?>
<!-- Contenu -->
<?php if($this->fetch('sidebar')) echo $this->fetch('sidebar'); ?>
<div class="container-fluid">
<?php echo $this->fetch('content'); ?>
</div>
<?php echo $this->Html->image('indicator.gif', array('id' => 'busy-indicator')); ?>
<div id="push"></div>
</div>
<!-- Footer -->
<?php echo $this->element('footer'); ?>
<!-- JS -->
<?php echo $this->Html->script('bootstrap.min'); ?>
<?php echo $this->Html->script('bootstrap-rowlink.min'); ?>
<?php echo $this->Html->script('jquery.cookie'); ?>
<?php echo $this->Html->script('jquery.treeview'); ?>
<?php echo $this->Html->script('chosen.jquery.min'); ?>
<?php echo $this->Html->script('jquery.functions'); ?>
</body>
</html>
Comme je le disais plus haut, la pagination Ajax de cakePHP fonctione seulement si jquery est appelé en haut de page (avant le content). J'ai placé les autres appels JS en haut de page, mais ça ne change rien.
J'espère que vous pourrez m'apporter des éclaircissements à ce bug (le problème est certainement entre le clavier et la chaise^^).
MERCI
C'est un problème de JS. Quand tu changes de page rappelle ta function tooltip.
ex:
$('.page').click(function() {
$("[rel=tooltip]").tooltip({
placement: "bottom"
});
});
remplace .page pas la class de tes liens de page. Si ça marche toujours pas peut-être mettre un délais.
Merci Hotgeart !
C'est en effet un problème de DOM entre Ajax et jQuery (donc cakePHP n'a rien avoir là-dedans).
Exemple :
$('a[data-confirm]').click(function() {
//code jQuery de modal de cofirmation
});
Aucun event handler n'y est attaché -> Au changement de page Ajax -> cela ne fonctionne plus
Il faut utiliser on() pour avoir un handler
$('body').on('click','a[data-confirm]',function() {
//code jQuery de modal de cofirmation
});
Et là ça fonctionne parfaitement.
NB : depuis la version 1.9 .live() et .delegate() ont été supprimés au profit de .on() apparru à partir de la version 1.7 !
Plus d'infos sur .on() ici.
Merci encore et bonne journée à tous.