Часть 14 - добавляем сортировку и порядок списка
Для добавления сортировки и порядка списка сообщений нам понадобится выполнить следующие шаги:
- Внести изменения в таблицу
#__helloworld
. - Добавить поддержку в модель списка сообщений.
- Изменить представление списка сообщений.
- Внести изменения в шаблоны списка сообщений.
Изменяем SQL файлы
Для поддержки порядка отображения списка необходимо изменить структуру таблицы #__helloworld
и добавить поле ordering
. Это позволит нам использовать имеющиеся методы фреймворка Joomla и не писать свои собственные.
Вносим изменения в файл admin/sql/install.mysql.utf8.sql:
DROP TABLE IF EXISTS `#__helloworld`; CREATE TABLE `#__helloworld` ( `id` int(11) NOT NULL AUTO_INCREMENT, `asset_id` INT(10) NOT NULL DEFAULT '0', `greeting` varchar(25) NOT NULL, `catid` int(11) NOT NULL DEFAULT '0', `ordering` INT(11) NOT NULL DEFAULT '0', `params` TEXT NOT NULL DEFAULT '', PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8; INSERT INTO `#__helloworld` (`greeting`) VALUES ('Hello World!'), ('Good bye World!');
Не забудьте создать файл admin/sql/updates/mysql/0.0.14.sql для изменения структуры таблицы во время установки новой версии компонента:
ALTER TABLE `#__helloworld` ADD `ordering` INT(11) NOT NULL DEFAULT '0' AFTER `catid`;
Изменяем модель списка сообщений
Открываем файл admin/models/helloworlds.php и меняем код на следующий:
<?php // Запрет прямого доступа. defined('_JEXEC') or die; // Подключаем библиотеку modellist Joomla. jimport('joomla.application.component.modellist'); /** * Модель списка сообщений компонента HelloWorld. */ class HelloWorldModelHelloWorlds extends JModelList { /** * Конструктор. * * @param array $config Массив с конфигурационными параметрами. */ public function __construct($config = array()) { // Добавляем валидные поля для фильтров и сортировки. if (empty($config['filter_fields'])) { $config['filter_fields'] = array( 'id', 'id', 'greeting', 'greeting', 'ordering', 'ordering', ); } parent::__construct($config); } /** * Метод для построения SQL запроса для загрузки списка данных. * * @return string SQL запрос. */ protected function getListQuery() { // Создаем новый query объект. $db = JFactory::getDbo(); $query = $db->getQuery(true); // Выбераем поля. $query->select('id, greeting, ordering'); // Из таблицы helloworld. $query->from('#__helloworld'); // Добавляем сортировку. $orderCol = $this->state->get('list.ordering', 'id'); $orderDirn = $this->state->get('list.direction', 'desc'); $query->order($db->escape($orderCol . ' ' . $orderDirn)); return $query; } /** * Метод для авто-заполнения состояния модели. * * @param string $ordering Поле сортировки. * @param string $direction Направление сортировки (asc|desc). * * @return void */ protected function populateState($ordering = null, $direction = null) { parent::populateState('id', 'desc'); } }
Итак, в модели было выполнено следующее:
- Добавлен конструктор. В нем указаны валидные поля для фильтров и сортировки.
- Добавлен метод
populateState()
. Этот метод используется для автозаполнения состояния модели. В нем мы просто вызываем родительский метод с параметрами сортировки по умолчанию. Таким образом состояние модели будет заполнено двумя значениями:list.ordering
- поле, по которому будет выполнена сортировка. В нашем случае это полеid
;list.direction
- направление сортировки. У нас это направлениеdesc
.
- В метод
getListQuery()
добавлена сортировка. Мы обращаемся к состоянию модели, получаем параметры сортировки и применяем их в запросе. Также в выборку$query->select
добавлено полеordering
.
Изменяем представление списка сообщений
Так как в модели теперь есть необходимые для нас данные по сортировке и порядку отображения списка, нам необходимо получить состояние модели (содержащие эти данные) в представлении. Меняем код файла admin/views/helloworlds/view.html.php на:
<?php // Запрет прямого доступа. defined('_JEXEC') or die; // Подключаем библиотеку представления Joomla. jimport('joomla.application.component.view'); /** * HTML представление списка сообщений компонента HelloWorld. */ class HelloWorldViewHelloWorlds extends JViewLegacy { /** * Сообщения. * * @var array */ protected $items; /** * Постраничная навигация. * * @var object */ protected $pagination; /** * Состояние модели. * * @var object */ protected $state; /** * Доступы пользователя. * * @var object */ protected $canDo; /** * Отображаем список сообщений. * * @param string $tpl Имя файла шаблона. * * @return void * * @throws Exception */ public function display($tpl = null) { try { // Получаем данные из модели. $this->items = $this->get('Items'); // Получаем объект постраничной навигации. $this->pagination = $this->get('Pagination'); // Получаем объект состояния модели. $this->state = $this->get('State'); // Получаем доступы пользователя. $this->canDo = HelloWorldHelper::getActions(); // Устанавливаем панель инструментов. $this->addToolBar(); // Отображаем представление. parent::display($tpl); } catch (Exception $e) { throw new Exception($e->getMessage()); } } /** * Устанавливает панель инструментов. * * @return void */ protected function addToolBar() { JToolBarHelper::title(JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLDS'), 'helloworld'); if ($this->canDo->get('core.create')) { JToolBarHelper::addNew('helloworld.add'); } if ($this->canDo->get('core.edit')) { JToolBarHelper::editList('helloworld.edit'); } if ($this->canDo->get('core.delete')) { JToolBarHelper::divider(); JToolBarHelper::deleteList('', 'helloworlds.delete'); } if ($this->canDo->get('core.admin')) { JToolBarHelper::divider(); JToolBarHelper::preferences('com_helloworld'); } } }
Изменяем шаблоны списка сообщений
Сначала мы изменим главный шаблон admin/views/helloworlds/tmpl/default.php и добавим в него два скрытых поля:
<input type="hidden" name="filter_order" value="<?php echo $this->escape($this->state->get('list.ordering')); ?>" /> <input type="hidden" name="filter_order_Dir" value="<?php echo $this->escape($this->state->get('list.direction')); ?>" />
сразу после строки:
<input type="hidden" name="boxchecked" value="0" />
Далее изменим суб-шаблон заголовков списков admin/views/helloworlds/tmpl/default_head.php:
<?php // Запрет прямого доступа. defined('_JEXEC') or die; // Данные по сортировке. $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); ?> <tr> <th width="1%"> <input type="checkbox" name="checkall-toggle" value="" title="<?php echo JText::_('JGLOBAL_CHECK_ALL'); ?>" on-click="Joomla.checkAll(this)" </th> <th> <?php echo JHtml::_('grid.sort', 'COM_HELLOWORLD_HELLOWORLD_HEADING_GREETING', 'greeting', $listDirn, $listOrder); ?> </th> <th width="10%"> <?php echo JHtml::_('grid.sort', 'JGRID_HEADING_ORDERING', 'ordering', $listDirn, $listOrder); ?> <?php if ($listOrder == 'ordering') : ?> <?php echo JHtml::_('grid.order', $this->items, 'filesave.png', 'helloworlds.saveorder'); ?> <?php endif; ?> </th> <th width="1%"> <?php echo JHtml::_('grid.sort', 'COM_HELLOWORLD_HELLOWORLD_HEADING_ID', 'id', $listDirn, $listOrder); ?> </th> </tr>
Мы заменили статические заголовки на вызовы метода grid.sort класса JHtmlGrid, а также добавили еще один заголовок для порядка списка с помощью grid.order. Теперь при клике на заголовок grid.sort
выполнит вызов javascript функции tableOrdering
, которая "положит" имя колонки (на которую кликнули) и направление сортировки в скрытые поля (filter_order
и filter_order_Dir
соответственно), а также выполнит отправку формы. Далее новые данные попадут в модель, она выполнит новый запрос, изменив при этом порядок списка сообщений.
Следующие изменения мы вносим в суб-шаблон admin/views/helloworlds/tmpl/default_body.php:
<?php // Запрет прямого доступа. defined('_JEXEC') or die; // Данные по сортировке. $listDirn = $this->escape($this->state->get('list.direction')); $listOrder = $this->escape($this->state->get('list.ordering')); $saveOrder = $listOrder == 'ordering'; foreach ($this->items as $i => $item) : $canEdit = JFactory::getUser()->authorise('core.edit', 'com_helloworld.message.' . $item->id); ?> <tr> <td> <?php echo JHtml::_('grid.id', $i, $item->id); ?> </td> <td> <?php if ($canEdit) : ?> <a href="/<?php echo JRoute::_('index.php?option=com_helloworld&task=helloworld.edit&id=' . (int) $item->id); ?>"> <?php echo $item->greeting; ?> </a> <?php else: ?> <?php echo $item->greeting; ?> <?php endif; ?> </td> <td> <?php if ($saveOrder) : ?> <?php if ($listDirn == 'asc') : ?> <span><?php echo $this->pagination->orderUpIcon($i, true, 'helloworlds.orderup', 'JLIB_HTML_MOVE_UP', $saveOrder); ?></span> <span><?php echo $this->pagination->orderDownIcon($i, $this->pagination->total, true, 'helloworlds.orderdown', 'JLIB_HTML_MOVE_DOWN', $saveOrder); ?></span> <?php elseif ($listDirn == 'desc') : ?> <span><?php echo $this->pagination->orderUpIcon($i, true, 'helloworlds.orderdown', 'JLIB_HTML_MOVE_UP', $saveOrder); ?></span> <span><?php echo $this->pagination->orderDownIcon($i, $this->pagination->total, true, 'helloworlds.orderup', 'JLIB_HTML_MOVE_DOWN', $saveOrder); ?></span> <?php endif; ?> <?php endif; ?> <?php $disabled = $saveOrder ? '' : 'disabled="disabled"'; ?> <input type="text" name="order[]" size="5" value="<?php echo $item->ordering; ?>" <?php echo $disabled; ?> /> </td> <td> <?php echo $item->id; ?> </td> </tr> <?php endforeach; ?>
Здесь основное изменение относится к добавлению дополнительной колонки порядка сообщений. В ней мы выводим порядковый номер сообщения. Если мы находимся в режиме изменения порядка, то с помощью методов $this->pagination->orderUpIcon() и $this->pagination->orderDownIcon() дополнительно выводятся специальные стрелочки, которые помогают нам изменять порядок сообщений.
Ну и последнее. Так как у нас теперь не три колонки, а четыре, то сделаем небольшое изменение в суб-шаблоне admin/views/helloworlds/tmpl/default_foot.php - меняем <td colspan="3">
на <td colspan="4">
.
Собираем пакет установки компонента
Не забудьте поменять номер версии в файле helloworld.xml:
<version>0.0.14</version>
helloworld.xml
<?xml version="1.0" encoding="utf-8"?> <extension type="component" version="2.5.0" method="upgrade"> <name>COM_HELLOWORLD</name> <!-- Следующие элементы необязательны --> <creationDate>Июль 2012</creationDate> <author>Вася Пупкин</author> <authorEmail>Ваш e-mail</authorEmail> <authorUrl>Ваш сайт</authorUrl> <copyright>Информация о копирайте</copyright> <license>Информация о лицензии</license> <!-- Версия записывается в таблицу компонентов --> <version>0.0.14</version> <!-- Описание необязательно --> <description>COM_HELLOWORLD_DESCRIPTION</description> <!-- Запускается при установке/удалении/обновлении --> <scriptfile>script.php</scriptfile> <!-- Запускается при установке --> <install> <sql> <file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file> </sql> </install> <!-- Запускается при удалении --> <uninstall> <sql> <file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file> </sql> </uninstall> <!-- Запускается при обновлении --> <update> <schemas> <schemapath type="mysql">sql/updates/mysql</schemapath> </schemas> </update> <!-- Раздел основных файлов сайта --> <!-- Обратите внимание на значение аттрибута folder: Этот аттрибут описывает папку нашего пакета-установщика из которой должны копироваться файлы. Поэтому указанные в этом разделе файлы будут скопированы из папки /site/ нашего пакета-установщика в соответствующую папку установки. --> <files folder="site"> <filename>index.html</filename> <filename>controller.php</filename> <filename>helloworld.php</filename> <folder>language</folder> <folder>models</folder> <folder>views</folder> </files> <media destination="com_helloworld" folder="media"> <filename>index.html</filename> <folder>images</folder> </media> <!-- Администрирование --> <administration> <!-- Раздел Меню --> <menu img="../media/com_helloworld/images/hello-16x16.png">COM_HELLOWORLD_MENU</menu> <!-- Раздел основных файлов администрирования --> <!-- Обратите внимание на значение аттрибута folder: Этот аттрибут описывает папку нашего пакета-установщика из которой должны копироваться файлы. Поэтому указанные в этом разделе файлы будут скопированы из папки /admin/ нашего пакета-установщика в соответствующую папку установки. --> <files folder="admin"> <filename>index.html</filename> <filename>access.xml</filename> <filename>config.xml</filename> <filename>controller.php</filename> <filename>helloworld.php</filename> <folder>controllers</folder> <folder>helpers</folder> <folder>models</folder> <folder>sql</folder> <folder>tables</folder> <folder>views</folder> </files> <languages folder="admin"> <language tag="en-GB">language/en-GB/en-GB.com_helloworld.ini</language> <language tag="en-GB">language/en-GB/en-GB.com_helloworld.sys.ini</language> <language tag="ru-RU">language/ru-RU/ru-RU.com_helloworld.ini</language> <language tag="ru-RU">language/ru-RU/ru-RU.com_helloworld.sys.ini</language> </languages> </administration> <!-- Сервер обновлений --> <updateservers> <!-- Заметка: Не допускаются пробелы или переносы строк между тегам server --> <server type="extension" priority="1" name="Сайт обновлений компонента Hello World!">http://вашдомен.ru/update/helloworld-update.xml</server> </updateservers> </extension>
Содержимое директории с кодом:
helloworld.xml
script.php
site/index.html
site/helloworld.php
site/controller.php
site/language/index.html
site/language/en-GB/index.html
site/language/en-GB/en-GB.com_helloworld.ini
site/language/ru-RU/index.html
site/language/ru-RU/ru-RU.com_helloworld.ini
site/models/index.html
site/models/helloworld.php
site/views/index.html
site/views/helloworld/index.html
site/views/helloworld/view.html.php
site/views/helloworld/tmpl/index.html
site/views/helloworld/tmpl/default.xml
site/views/helloworld/tmpl/default.php
admin/index.html
admin/access.xml
admin/config.xml
admin/controller.php
admin/helloworld.php
admin/controllers/index.html
admin/controllers/helloworld.php
admin/controllers/helloworlds.php
admin/helpers/index.html
admin/helpers/helloworld.php
admin/language/index.html
admin/language/en-GB/index.html
admin/language/en-GB/en-GB.com_helloworld.ini
admin/language/en-GB/en-GB.com_helloworld.sys.ini
admin/language/ru-RU/index.html
admin/language/ru-RU/ru-RU.com_helloworld.ini
admin/language/ru-RU/ru-RU.com_helloworld.sys.ini
admin/models/index.html
admin/models/helloworld.php
admin/models/helloworlds.php
admin/models/fields/index.html
admin/models/fields/helloworld.php
admin/models/forms/index.html
admin/models/forms/helloworld.js
admin/models/forms/helloworld.xml
admin/models/rules/index.html
admin/models/rules/greeting.php
admin/sql/index.html
admin/sql/install.mysql.utf8.sql
admin/sql/uninstall.mysql.utf8.sql
admin/sql/updates/index.html
admin/sql/updates/mysql/index.html
admin/sql/updates/mysql/0.0.1.sql
admin/sql/updates/mysql/0.0.4.sql
admin/sql/updates/mysql/0.0.9.sql
admin/sql/updates/mysql/0.0.10.sql
admin/sql/updates/mysql/0.0.12.sql
admin/sql/updates/mysql/0.0.14.sql
admin/tables/index.html
admin/tables/helloworld.php
admin/views/index.html
admin/views/helloworld/index.html
admin/views/helloworld/view.html.php
admin/views/helloworld/submitbutton.js
admin/views/helloworld/tmpl/index.html
admin/views/helloworld/tmpl/edit.php
admin/views/helloworlds/index.html
admin/views/helloworlds/view.html.php
admin/views/helloworlds/tmpl/index.html
admin/views/helloworlds/tmpl/default.php
admin/views/helloworlds/tmpl/default_body.php
admin/views/helloworlds/tmpl/default_foot.php
admin/views/helloworlds/tmpl/default_head.php
language/index.html
language/en-GB/index.html
language/en-GB/en-GB.com_helloworld.sys.ini
language/ru-RU/index.html
language/ru-RU/ru-RU.com_helloworld.sys.ini
media/index.html
media/images/index.html
media/images/hello-16x16.png
media/images/hello-48x48.png
Запакуйте директорию в архивный файл (zip, tar, tar.gz, bz2) или скачайте его напрямую c GitHub. Далее установите его, используя менеджер расширений Joomla. Теперь у нас есть возможность сортировать список, а также изменять и сохранять порядок сообщений.
Код для этой части
Скачать com_helloworld часть 14
Актуальный код части 14 на GitHub