jqGridPHP - таблицы на ajax без головной боли

~WR~

Новичок
Думаю, это та самая известная проблема с mysql и utf-8.

В /examples/index.php

Найти:
PHP:
$jq_loader->set('pdo_pass', $_CONFIG['pdo_pass']);
Добавить после:
PHP:
$jq_loader->set('pdo_options', array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));

Если используется не PDO, то нужно выполнить запрос
PHP:
SET NAMES utf8
- сразу после соединения с БД.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Если используется не PDO, то нужно выполнить запрос
PHP:
SET NAMES utf8
- сразу после соединения с БД.
Не нужно — лучше пользоваться http://php.net/manual/ru/function.mysql-set-charset.php или http://www.php.net/manual/ru/mysqli.set-charset.php (да, кстати, именно этот комментарий в свое время принес мне -80 в карму на хабре :) )
 

~WR~

Новичок
Согласен. Но, кажется, mysql_set_charset не на всех версиях доступен. Мне кто-то жаловался на undefined function.
Если есть, то лучше им конечно.
 

mamboz

Новичок
Как насчет реализации схемы Grid as Subgrid? А то я что то никак не могу понять.... Если Вас не затруднит сделайте пример на своем сайте
 

~WR~

Новичок
Без проблем. Показал одну из возможных реализаций:
http://jqgrid-php.net/examples/?render=jqMiscSubgrid

Создается два класса: один на основную таблицу и один - на subgrid.
При разворачивании идет вызов операции, в которой обращаемся к методу render класса subgrid'а. Получаем голый javascript, который выполняется в $.getScript и показывает новый subgrid.

Единственное - для subgrid пока что нужно вручную создавать базовую разметку (один <table> и один <div>) и подавлять её автоматическое создание перегрузкой метода renderHtml. Это занимает по три строчки.

Спрашивайте, если что-то непонятно ^__^

------------

Перед тем, как делать у себя, обновите базовый jqGrid.php на последнюю версию. Другие файлы не изменились.
https://raw.github.com/wildraid/jqGridPHP/master/php/jqGrid.php
 

mamboz

Новичок
Без проблем. Показал одну из возможных реализаций:
http://jqgrid-php.net/examples/?render=jqMiscSubgrid

Создается два класса: один на основную таблицу и один - на subgrid.
При разворачивании идет вызов операции, в которой обращаемся к методу render класса subgrid'а. Получаем голый javascript, который выполняется в $.getScript и показывает новый subgrid.

Единственное - для subgrid пока что нужно вручную создавать базовую разметку (один <table> и один <div>) и подавлять её автоматическое создание перегрузкой метода renderHtml. Это занимает по три строчки.

Спрашивайте, если что-то непонятно ^__^

------------

Перед тем, как делать у себя, обновите базовый jqGrid.php на последнюю версию. Другие файлы не изменились.
https://raw.github.com/wildraid/jqGridPHP/master/php/jqGrid.php
Огромное спасибо за оперативность!!!
В принципе я так и делал, вот только не доконца доделал.... ума не хватило ))))
Еще раз спасибо.
Ушел рулить дальше )))
 

mamboz

Новичок
Доброго времени суток.
У меня появилось еще пару вопросов.
1) Я никак не могу вставить в футтер строку текст типа "ВСЕГО"
2) Возможно ли в хедере тест переносить на следующую строку, а то заголовок довольно большой и в одной строке ничего не понятно, а делать столбец шире нет смысла
 

~WR~

Новичок
1) Я никак не могу вставить в футтер строку текст типа "ВСЕГО"
Способ 1
Поставить опцию
PHP:
footerrow: true,
В gridComplete добавить вызов:
PHP:
$(this).jqGrid('extFooterAgg');
В класс таблицы добавить:
PHP:
protected function getDataUser($userdata)
{
    $userdata = parent::getDataUser($userdata);
    $userdata['agg']['my_column'] = 'Всего:';

    return $userdata;
}
Где my_column - название колонки, в которую вставить текст.

Способ 2
Посмотреть id контейнера и написать в gridComplete простейший jQuery вызов типа:
PHP:
$('#my_footer_col').text('Всего:');
Таким образом можно менять вообще что хочешь.

2) Возможно ли в хедере тест переносить на следующую строку, а то заголовок довольно большой и в одной строке ничего не понятно, а делать столбец шире нет смысла
Да, только там должен быть HTML. Перевод строк будет не \n, а <br>. Можно туда лепить свои кнопки и другие input'ы.
 

~WR~

Новичок
Если вопрос был о том, как вообще посчитать и вывести "Итого", то выполняем первые два действия из Способа 1.
А потом добавляем к опциям нужных колонок параметр 'db_agg'.

Пример здесь:
http://jqgrid-php.net/examples/?render=jqCols

Все aggregate функции выполняются в одном запросе с подсчетом общего количества записей, поэтому влияние на производительность минимальное.
В db_agg можно писать не только стандартные (sum, count, min, max, avg), но и свои более сложные выражения. Например:
PHP:
'db_agg' => 'min(price) / count(id) * 100',
 

mamboz

Новичок
Да, только там должен быть HTML. Перевод строк будет не \n, а <br>. Можно туда лепить свои кнопки и другие input'ы.
Сори только я не совсем понял.....
Я пробую делать так
PHP:
'ras_sum'     =>array('label' => 'Взаимный </br> расчет',
								'width'	=> 25,
                                                                ..........................
выводит только слово "Взаимный". если поставить \n так его тоже выводит в заголовок )) Возможно я что то напутал...
Если Вас не затруднить напишите пару примерчиков.....
Заранее благодарен.
 

~WR~

Новичок
Ах, если речь о названиях колонок, то там специально сделано одной строкой.
Можно изменить высоту элементов внутри заголовка (там несколько вложенных), но можно нарваться на проблемы при манипуляциях с колонками.

Из относительно простых способов, можете попробовать поиграться их штатной группировкой колонок:
http://trirand.com/blog/jqgrid/jqgrid.html
В самом низу - примеры на Frozen Columns, Group Header.

Хотя, по-моему, тоже через top сделали.
Рекомендую все же сокращать название, использовать атрибут title или всплывающие tooltip.
 

dl_pv

Новичок
я не спец в PHP, но пришлось сделать пробу решить задачу вывода ассортимента товара на веб-страницу. Используя только jqGrid, я смог вывести список товара, настроил тулбар для поиска. Но осталась еще задача дать возможность клиенту делать набросок заказа на странице. Первое, что приходит в голову - это сделать еще одну таблицу ниже основной и по двойному клику из верхней таблицы копировать строку в нижнюю. Потом из нижней таблицы сделать экспорт в эксель. Вопрос - умеет ли gqGrid делать Drag&Drop между таблицами, или не стоит такие навороты делать? Может посоветуете, как проще всего сделать заполнение заказа?
 

~WR~

Новичок
Всё он умеет. Чего не умеет - легко научить. :)

Здесь документация по Drag&Drop (от середины страницы):
http://www.trirand.com/jqgridwiki/doku.php?id=wiki:jquery_ui_methods

Здесь пример:
http://trirand.com/blog/jqgrid/jqgrid.html
-> New in version 3.6 -> Drag and Drop Rows

Но я бы сделал как-нибудь попроще. Например, добавить галки (multiselect) и кнопку "Добавить в заказ".
При нажатии на кнопку отправляем на сервер id выбранных товаров ($(this).jqGrid('getGridParam', 'selarrrow')).

Если успешно добавилось - в callback'е делаем .trigger('reloadGrid') для нижнего грида. Он обновляется, и мы видим товары уже в заказе.
 

dl_pv

Новичок
еще вопрос
в таблице есть Search Toolbar, то есть над каждой колонкой можно вводить слово для поиска. Но мне мало одного слова для быстрого перехода на нужную позицию товара. Хотелось бы например в поле Наименование товара вводить несколько слов ("втулка рычага") и дальше строка разбиралась бы на слова (разделитель - пробел) и по Like шел бы поиск. Такое реально сделать?
 

~WR~

Новичок
Без проблем. В классе грида перегружаем стандартный оператор поиска LIKE, либо делаем свой.

Примерно так:
PHP:
protected function searchOpLike($c, $val)
{
    $parts = array();
    $words = array_filter(explode(' ', $val));

    foreach($words as $w)
    {
        $parts[] = parent::searchOpLike($c, $w);
    }

    return '(' . implode(' OR ', $parts) . ')';
}
Будет искать записи, в которых совпадает любое из введенных слов.

Чтобы сделать свой оператор поиска, в свойствах колонки указываем его название в свойстве search_op:
PHP:
'search_op' => 'like_words',
Соответственно, функция должна называться searchOpLikeWords. Её код абсолютно тот же самый.
Документация здесь: http://jqgrid-php.net/doku.php?id=wiki:search

Если нужно, чтобы искало все слова, но в любом порядке - меняем OR на AND.
 

fandm

Новичок
Всем привет!

1. Большое спасибо автору(ам) jqGridPHP, отличная вещь, очень помогает в работе. Дай Бог тебе(вам) здоровья! ;)
2. Отточил работу с Oracle, т.е. добавил jqGrid_DB_Oracle в подпапку DB. Добавил простую обёртку для LIMIT OFFSET, т.е. в своих запросах можно смело использовать этот синтаксис - он будет корректно преобразован в постраничный запрос by Oracle. Сделал это в рамках перевода DLE под Oracle.
3. Спасибо за идею с Date Range Picker, даже не знал о таком плагине, чудная вещь. Правда я, по-началу, сделал фильтр по полям с датой через LIKE - для этого добавил в colModel ещё один параметр "filter", куда прописываю преобразование даты в строку. В searchOpLike я беру не $c['db'], а $c['filter']. При этом сортировка работает как по полю типа "дата". Для поиска по одиночной дате - прикольно, но промежуток дат, безусловно, лучше реализовать через Date Range Picker.
4. Набрёл на днях на вот эту статью http://freehabr.ru/blog/1111.html, немного доработал и получился класс, превращающий TDBGrid by Delphi в многомерный массив, а уже из него получаем colModel by jqGrid. Можно было и напрямую сделать получение colModel, но код проекта не очень хотелось переписывать. :) В случае ведения основного проекта на Delphi, просто незаменимая вещь для параллельного ведения Web-клона. Мало ли, может кому-то пригодится.
5. Заметил, что реализация GroupHeader некорректно работает на версиях jqGrid 4.2.0 и 4.3.1. После updateGroupHeader шапка таблицы многократно повторяется по вертикали. С версией jqGrid 4.1.2 (тем, что использован здесь http://jqgrid-php.net/examples/?render=jqMiscGroupHeaderEx) всё работает корректно. Поэтому пока оставил версию 4.1.2, но в будущем придётся всё равно разобраться в чём дело, т.к. такой способ группировки мне значительно больше подходит, чем родной от trirand, т.к. не всегда столбцы, которые необходимо объединить общей шапкой, расположены рядом, а новые версии jqGrid тоже использовать хочется.
6. Может быть кто-нибудь знает, как можно приспособить jqGrid, чтобы он стал чем-то вроде VerticalGrid, когда столбцы разворачиваются в строки, а названия столбцов располагаются в крайнем левом столбце? Ну, что-то наподобие DevExpress TdxInspector или TcxVerticalGrid? Типа такого http://www.devexpress.com/Products/VCL/ExVerticalGrid/ Или, может, кто-нибудь подскажет как проще всего можно в своём диалоге на основе jQuery UI Dialog вывести данные из jqGrid в виде формы так, как это делает стандартный метод viewGridRow? Просто в моём случае диалог весьма сложен по структуре, с Tab-ами и вложенными jqGrid-ами.
 

~WR~

Новичок
2. Отточил работу с Oracle, т.е. добавил jqGrid_DB_Oracle в подпапку DB. Добавил простую обёртку для LIMIT OFFSET, т.е. в своих запросах можно смело использовать этот синтаксис - он будет корректно преобразован в постраничный запрос by Oracle. Сделал это в рамках перевода DLE под Oracle.
Здорово. Поделитесь кодом - добавлю в репозитарий. Если есть аккаунт на гитхабе - можно прямо pull request'ом.

3. Спасибо за идею с Date Range Picker,
Да, Like'ом, конечно, не стоит искать даты. Т.к. у каждой СУБД есть свои функции для работы с датами - фильтра по датам нет в базовом классе.
Предполагается, что люди сами напишут обертку, как именно они хотят искать. Благо, это несложно.

5. Заметил, что реализация GroupHeader некорректно работает на версиях jqGrid 4.2.0 и 4.3.1.
Думаю, они что-то изменили в верстке header'ов, поэтому старый selector на удаление перестал работать. Посмотрю.
Вообще, не очень понятно, почему tony в окончательном варианте взял именно код Олега, а не мой. Там куча очевидных проблем. Но хозяин-барин конечно.

6. Может быть кто-нибудь знает, как можно приспособить jqGrid, чтобы он стал чем-то вроде VerticalGrid, когда столбцы разворачиваются в строки, а названия столбцов располагаются в крайнем левом столбце?
Не, это невозможно. :)

По тому, как проще сделать... По идее, с jQuery UI уже проще некуда.
Только лучше не динамически формировать html, т.к. это тяжело потом поддерживать, а просто делать ajax-запрос на сервер. Он отдаст html с содержимым диалога и уже с заполненными данными. И хоть табы там будут, хоть sub-grid'ы. Всё то же самое, как для обычной странички.
 

fandm

Новичок
Здорово. Поделитесь кодом - добавлю в репозитарий. Если есть аккаунт на гитхабе - можно прямо pull request'ом.
Написал в переписку. :)

Думаю, они что-то изменили в верстке header'ов, поэтому старый selector на удаление перестал работать. Посмотрю.
Вообще, не очень понятно, почему tony в окончательном варианте взял именно код Олега, а не мой. Там куча очевидных проблем. Но хозяин-барин конечно.
Было бы чудно, спасибо большое. :) Мне тоже не понятно, т.к. Ваш способ гораздо более универсальный и более подходящий для формирования динамических header-группировок на серверной стороне.

Не, это невозможно. :)
По тому, как проще сделать... По идее, с jQuery UI уже проще некуда.
Только лучше не динамически формировать html, т.к. это тяжело потом поддерживать, а просто делать ajax-запрос на сервер. Он отдаст html с содержимым диалога и уже с заполненными данными. И хоть табы там будут, хоть sub-grid'ы. Всё то же самое, как для обычной странички.
Я, наверное, не совсем понятно всё объяснил. :) Я и сделал с помощью jQuery UI, использую jQuery UI Dialog и jQuery UI Tabs и jQuery UI Button и в Tab-ы успешно встраиваю jqGrid-ы и с модальностью многочисленных дочерних диалогов разобрался, всё отлично работает, но... Единственное, что осталось сделать, это отобразить данные из основного jqGrid (из которого вызывается сей сложный диалог) в одном из Tab-ов. Ок, я вот выложил скриншот, чтобы было понятнее.
Вот в закладке (1) я сейчас подготавливаю заранее форму и загружаю туда данные с помощью GridToForm. Так вот, хотелось бы отказаться от необходимости подготавливать заранее форму, а чтобы она строилась динамически так же, как это делается по viewGridRow и чтобы использовались стандартные настройки из colModel: editable, editoptions, editrules и т.д. Может надо просто перегрузить метод viewGridRow и дело - в шляпе? :)
 

~WR~

Новичок
Боюсь, что единственный метод - реализовать поддержку настроек из colModel самостоятельно конкретно для своей формы.

Что касается Oracle. Видимо, немного изменю структуру функций, отвечающих за постраничный вывод.
Чтобы была штатная реализация не только LIMIT & OFFSET, но и через window-функцию. Все же многие СУБД этого требуют.

Preg_replace в запрос - это несерьезно. :)
 
Сверху