Пытаюсь заставить стандартный пагинатор/pager и сортировку работать по AJAX. Есть решение, но к сожалению оно ломает стандартный AJAX. Все по порядку.
Этот код делает выборку из базы
<?php
$query
= db_select('hive_gift', 'hg');
$query->fields('hg');
$query = $query->extend('TableSort')->orderByHeader($header)->extend('PagerDefault')->element($element)->limit(7);
$result = $query
->execute()
->fetchAllAssoc('gid', PDO::FETCH_ASSOC);
return $result;
?>
Как видно PagerDefault присутствует, даже объявлен element, т.к. таблицы две.
Далее создана обычная форма, добавлена таблица, сделаны вертикальные вкладки, все работает, но без AJAX. Выглядит так:
По умолчанию пейджер вообще AJAX не поддерживает и на одном из форумов нашел "решение": вручную находим ссылки и по клику привязываем AJAX запрос и подменяем область на странице. Код:
if(!page) page = '';
if(!sort) sort = '';
if(!order) order = '';
if(!table) return;
jQuery.ajax({
cache: false,
data: {page: page, sort: sort, order: order, table: table},
dataType: 'html',
error: function(request, status, error) {
alert(table + ' AJAX error ' + status);
},
success: function(data, status, request) {
jQuery('#' + table).html(jQuery(data).find('#' + table).html());
//jQuery('#gift-form').html(jQuery(data).find('#gift-form').html());
jQuery('#' + table + ' th a')
.add('#' + table + ' .pager-item a')
.add('#' + table + ' .pager-first a')
.add('#' + table + ' .pager-previous a')
.add('#' + table + ' .pager-next a')
.add('#' + table + ' .pager-last a')
.click(function(el) {
var url = jQuery.url(el.currentTarget.getAttribute('href'));
refreshTable(url.param('page'), url.param('sort'), url.param('order'), table);
return (false);
});
}
});
}
function initializeTable() {
jQuery(document).ready(function() {
refreshTable('','','','receiving-table-wrapper');
});
}
к форме присоединяем аттачем:
<?php
$form['#attached']['js'][] = drupal_get_path('module', 'hive_gift') . '/purl.js';
$form['#attached']['js'][] = drupal_get_path('module', 'hive_gift') . '/hive_gift.js';
$form['#attached']['js']['initializeTable();'] = array('type' => 'inline');
?>
purl - это URL parser для jQuery.
В итоге таблица полностью работает на AJAX. И пагинация и сортировка. Тут-то и начинаются проблемы.
Скрипт вызывает страницу, на которую указывают ссылки, в AJAX запросе. А на страничке пользователя меняется только один блок с id #receiving-table-wrapper. Но в таблице находятся еще кнопки, которые также должны работать по AJAX и перезагружать таблицу. Так вот, в начале страницы подключен скрипт с drupal.behaviors, с событиями кликов по кнопкам accept. И когда происходит замена в скрипте JS на строчке:
jQuery('#' + table).html(jQuery(data).find('#' + table).html());
по всей видимости нарушается связь между событиями click и теми элементами, которые есть на странице. Дело в том, что даже если будут одинаковые #id, drupal.behaviors не сработает больше, событие click открепится. А если перейти с помощью пейджера на другую страничку, в drupal.behaviors вообще будут отсутствовать данные о новых кнопках.
А визуально это выглядит так - после подключения скрипта не срабатывает AJAX у кнопок. Сами кнопки срабатывают, но перезагружат страницу.
У меня честно говоря нет даже мысли как это можно обойти стандартным способом. Есть два обходных пути:
1. Каким-то образом написать свой пагинатор и сортировку - долго и некрасиво, неважный вариант. Нужно будет все ссылки сделать AJAX и перенаправить на какой-нибудь коллбэк. Гемор, 100%.
2. Вручную дописать AJAX для кнопок/ссылок. В этом случае, для того, чтобы сделать действие accept в php и сделать запрос в БД, нужно будет перейти по какой-нибудь коллбэк-функции. В принципе сделать реально, но не тру, вручную AJAX писать в drupal не приветствуется, для этого есть API. А как это приспособить под API я не знаю.
P.S.: я достаточно много сложных вещей реализовал именно в стиле drupal, используя его средства, без каких-либо костылей. Drupal мощный, но здесь очевидный пробел. Если отказаться от AJAX, то после перехода по любому пагинатору (он есть и на первой и на второй вкладке) всегда открывается первая вкладка vertical tab, т.е. явный косяк. Довольно долго уже не могу победить это.
P.P.S.: Если вы осилите этот пост и поймете о чем он, я буду безмерно счастлив.
Вложение | Размер |
---|---|
snimok.png | 27.66 КБ |
Комментарии
Замени это на:
Drupal.behaviors.infiniteScrollAddClass={
attach: function (context, settings){
refreshTable('','','','receiving-table-wrapper');
}
};
}
Модуль включает все необходимое для ajax таблиц из коробки
модуль
https://github.com/player259/ajax_table
описание, примеры, обязательно к прочтению перед применением
http://engear.ru/projects/ajax-table
AJAX Table contains serious security vulnerabilities. Do not use this module....