[ExtJS] Расширяем нативную гриду юзеров

После статьи о расширении профиля юзера правильными дополнительными полями мне посыпались вопросы о расширении нативной таблицы со списком юзеров. Мы знаем, что практически любой стандартный компонент системы, работающий на ExtJS, можно расширить не затрагивая исходника. Главное
Сразу опишем задачу, которую реализуем в рамках статьи:
- Убрать слева каждой записи ненужный чекбокс,
- Добавить столбцы: Фото, Дата рождения, Страна, Город,
- Добавить возможность отфильтровать пользователей по стране,
- Заменить некрасивое поле поиска на симпатичное и компактное,
- Подсветить заблокированных красным цветом.
Почему не компонентом?
В виде компонента такое оформить было бы правильно, как я это делал в статье о Расширении компонента Collections, однако я не раз замечаю барьер у многих, при попытке запаковки какого-то функционала в пакет. Поэтому обойдемся более простым методом. А те, кому надо запаковать в пакет — разберутся без труда.
CSS
/assets/xusergrid/css/main.css
Стили комментировать не имеет смысла.JavaScript
/assets/xusergrid/js/xusergrid.js
Здесь происходит объявление и инициализация основного класса./assets/xusergrid/js/combo.js
Содержит поле поиска и поле выбора страны. Необходимо для фильтра./assets/xusergrid/js/extends/modx.grid.user.js
Основной файл, расширяющий таблицу пользователей.Я постарался указать комментарии в коде, чтобы он стал более понятным.
PHP
/assets/xusergrid/connector.php
Кастомный коннектор, ссылающийся на нашу папку процессоров./assets/xusergrid/processors/combo/getuserfield.class.php
Процессор, возвращающий в комбобокс, список используемых значений любого поля юзера./assets/xusergrid/processors/security/user/getlist.class.php
Процессор, возвращающий список пользователей. Расширяет стандартный класс modUserGetListProcessor, добавляя в него:— фильтрацию по стране,
— дополнительные поля в выборку,
— обработку сырых данных даты рождения, страны.
/assets/xusergrid/processors/security/user/updatefromgrid.class.php
Процессор, обновляющий данные юзера при «быстром» редактировании прямо из таблицы. Удаляется ключ country для того, чтобы не перезаписывать в таблицу обработанное (переведенное) значение.Остальные процессоры необходимы, потому что в стандартных методах объекта MODx.grid.User они вызываются непосредственно через коннектор, прописанный в свойстве основного объекта гриды. А т.к. мы заменили стандартный коннектор на свой, то и процессоры должны продублировать.
Это также можно решить, переписав немного методы activateSelected, deactivateSelected, removeSelected, removeUser и duplicateUser, а точнее, заменив this.config.url на MODx.config.connector_url. Но я считаю, что лучше расширить процессоры, к которым обращается JS, не трогая «ни грамма» исходников при этом.
/assets/xusergrid/processors/security/user/activatemultiple.class.php
/assets/xusergrid/processors/security/user/deactivatemultiple.class.php
/assets/xusergrid/processors/security/user/delete.class.php
/assets/xusergrid/processors/security/user/duplicate.class.php
/assets/xusergrid/processors/security/user/removemultiple.class.php
Плагин
Пожалуй, это самое основное, ибо без плагина на событие OnManagerPageBeforeRender про наш код MODX даже и не узнает.
$sp = &$scriptProperties;
/** @var modManagerController $controller */
$controller = $sp['controller'];
switch ($modx->event->name) {
case "OnManagerPageBeforeRender":
if (is_object($controller)) {
$config = array(
'connector_url' => $modx->getOption('assets_url') . 'xusergrid/connector.php',
);
$action = $controller->scriptProperties['a'];
if ($action == 'security/user') {
$controller->addCss($modx->getOption('assets_url') . 'xusergrid/css/main.css');
$controller->addJavascript($modx->getOption('assets_url') . 'xusergrid/js/xusergrid.js');
$controller->addHtml("<script type='text/javascript'>
xUserGrid['config'] = {$modx->toJSON($config)};
</script>");
$controller->addLastJavascript($modx->getOption('assets_url') . 'xusergrid/js/combo.js');
$controller->addLastJavascript($modx->getOption('assets_url') . 'xusergrid/js/extends/modx.grid.user.js');
}
}
break;
}Рассмотрим подробнее
Вот здесь мы расширяем наш объект xUserGrid.grid.modxUserExt, добавляя в него методы и свойства из зарегистрированного компонента modx-grid-user, который хранится в Ext.ComponentMgr.types['modx-grid-user'], параллельно добавляя новые методы (там же можно заменить и существующие). Мы можем расширять наш объект и стандартным объектом гриды юзеров MODx.grid.User, но в этом случае, если до нашего кода уже внедряются какие-то изменения в гриду, то они будут утрачены.
А здесь мы регистрируем xUserGrid.grid.modxUserExt в качестве компонента modx-grid-user, фактически переопределяя зарегистрированный ранее компонент на это имя в коде системы.
Для того и используется метод addLastJavascript в плагине, дабы быть уверенным, что подключение наших файлов будет уже после подключения системного modx.grid.user.js.
В итоге
Получаем кастомизированную таблицу пользователей, без внедрения своего кода в исходники системы. Таким образом, мы сохраняем возможность обновления MODX на новые версии, всем будущим поколениям.
P.S.
Благодарность Николаю Ланецу за подсказку о более правильном расширении, с использованием зарегистрированного компонента, хранящегося в Ext.ComponentMgr.types['modx-grid-user'].
Комментарии: 15
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
а то я уже в плагин джаваскрипта насовал. Грид расширил, но с доп. фильтрами так и не разобрался. Так что статья кстати
А здесь мы регистрируем xUserGrid.grid.modxUserExt в качестве компонента modx-grid-user, фактически переопределяя зарегистрированный ранее компонент на это имя в коде системы.
Для того и используется метод addLastJavascript в плагине, дабы быть уверенным, что подключение наших файлов будет уже после подключения системного modx.grid.user.js.
Fi1osofFi1osofFi1osofВот такой с таким подходом одновременно на странице уживаются и userKarma, и switchUser.
Попробуй своим способом дописать еще один чуть измененный плагин. Смогут они вместе сосуществовать на одной странице?
Fi1osofкак бы так грамотно на странице юзера вывести превью его аватарки? по типу image tv