Проблема с AJAX pager/sort для таблицы + стандартный AJAX в форме

Главные вкладки

Аватар пользователя player259 player259 21 января 2013 в 21:35

Пытаюсь заставить стандартный пагинатор/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 запрос и подменяем область на странице. Код:

function refreshTable(page, sort, order, table) {
       
        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.png27.66 КБ

Комментарии

Аватар пользователя IscateL IscateL 25 апреля 2014 в 11:04

player259 wrote:

function initializeTable() {
jQuery(document).ready(function() {
refreshTable('','','','receiving-table-wrapper');
});
}

Замени это на:

function initializeTable() {
        Drupal.behaviors.infiniteScrollAddClass={
                attach: function (context, settings){
                        refreshTable('','','','receiving-table-wrapper');
                }
        };
}