{ xtype: 'button', text: 'Create thing', // Меняем надпись cls: 'primary-button', handler: function() { // После клика на кнопку MODx.load({ // будем загружать новый ExtJS-объект xtype: 'things-window-names', }); } }
У ExtJS есть такой объект, как окно

Но разработчики MODX адаптировали его к функционалу MODX, так что мы будем расширять объект MODx.Window:
// ... Things.window.Names = function (config) { config = config || {}; Ext.applyIf(config, { title: 'Create thing' }); Things.window.Names.superclass.constructor.call(this, config); // Магия }; Ext.extend(Things.window.Names, MODx.Window); // Расширяем MODX.Window Ext.reg('things-window-names', Things.window.Names); // Регистрируем новый xtype
Если сейчас кликнуть на кнопку, ничего внешне не произойдёт. Дело в том, что у окна есть разные методы и ExtJS «не знает», что с окном делать, пока мы ему об этом не скажем.
При клике на кнопку окно нам надо показать:
// ... handler: function() { MODx.load({ xtype: 'things-window-names', }).show(); // Сразу показываем окно пользователю } // ...
MODX предполагает, что обычно в окошках размещаются формы, которые пользователь должен заполнять, поэтому внутри MODX.Window уже создана форма и прописано свойство items. Нам нужно только указать список полей в свойстве fields. Каждое поле тоже должно быть объектом ExtJS. Посмотреть существующие типы полей можно опять в документации:

Мы будем использовать поля следующих типов:
- Ext.form.TextFieldView (xtype: textfield),
- Ext.form.TextAreaView (xtype: textarea),
- Ext.form.CheckboxView (xtype: checkbox)
// ... title: 'Create thing', fields: [{ xtype: 'textfield', // Текстовое поле name: 'name', fieldLabel: 'Name' }, { xtype: 'textarea', // Текстовая область name: 'description', fieldLabel: 'Description' }, { xtype: 'checkbox', // Чекбокс name: 'active', fieldLabel: 'Active' } ] // ...
Если мы сейчас нажмём в окне «Сохранить», то в консоли браузера можем увидеть, что запрос отправляется на /manager/?a=index&namespace=things, а нам надо передать запрос в процессор создания объектов. Указываем адрес коннектора и action:
// ... url: Things.config.connector_url, action: 'mgr/thing/create', // ...
Ну и создаём процессор create.class.php
<?php class ThingsNameCreateProcessor extends modObjectCreateProcessor { public $classKey = 'ThingsName'; // Класс объекта } return "ThingsNameCreateProcessor";
Теперь при сохранении данных в окне новый объект будет создан, но в таблице он сразу не появится. Если у вас до сих пор pageSize равен 1, то новой, четвёртой страницы сразу не появится, а если свойство pageSize удалить (тогда оно станет равным 20 по умолчанию), то новой строчки мы не увидим, пока не нажмём кнопку «Обновить».
Чтобы пользователя не вводить в заблуждение, после успешного сохранения данных нужно обновлять табличку. Разберёмся, как отдавать нужным объектам команды.
В ExtJS, так же, как и в jQuery наиболее удобным способом получить какой-то объект является его вызов по ID. Давайте, придумаем id для таблички:
// ... }, { xtype: 'things-grid-names', cls: 'container', id: 'my-fantastic-grid' } // ...
Теперь из любого места мы можем получить наш объект с помощью Ext.getCmp (так же, как мы получаем его с помощью $('#id')):
// ... { xtype: 'button', text: 'Create thing', cls: 'primary-button', handler: function() { MODx.load({ xtype: 'things-window-names', listeners: { success: { // При успешном сохранении fn: function () { // обновляем табличку Ext.getCmp('my-fantastic-grid').refresh(); } } } }).show(); } } // ...
Всё, вроде бы, хорошо. Но это только до того момента, пока вы не захотите использовать табличку в нескольких экземплярах. В таком случае для каждого экземпляра надо будет придумывать свой id и в них потом не запутаться.
Чтобы выйти из этой ситуации, обычно кнопку создания нового объекта «внедряют» в объект таблицы. Благодаря этому мы можем получить доступ к объекту таблицы с помощью ключевого слова this. Если интересно разобраться, можно почитать, например, в процессе написания тетриса. Но сейчас достаточно понять, что this позволяет обратиться к объекту, чтобы отдавать ему команды.
У таблицы для размещения кнопок и других инструментов управления есть верхняя и нижняя панель. В нижней панели уже размещается пагинация и кнопка обновления. Поэтому мы будем использовать верхнюю панель:
// ... action: 'mgr/thing/getlist', fields: ['id','name', 'description', 'active'], tbar: [{ // Указываем список объектов для размещения в верхней панели xtype: 'button', // Перемещаем сюда нашу кнопку text: 'Create thing', cls: 'primary-button', handler: function() { MODx.load({ xtype: 'things-window-names', listeners: { success: { fn: function () { this.refresh(); // Заменяем указание id на слово this }, scope: this // Передаём this дальше, чтобы он указывал // не на окно, а на таблицу } } }).show(); } } ] // ...
MODX xcheckbox
Сейчас вне зависимости от того, отметим ли мы чекбокс или нет, объект создаётся с полем active=true. Дело в том, что HTML-чекбокс передаёт значение в POST-параметре только если он отмечен. Нужно заставить ExtJS передавать процессору значение 0, если чекбокс не отмечен.
К счастью, за нас это сделали разработчики MODX — нам нужно только использовать другой xtype: xcheckbox.
Ну и можно немного украсить наше окошко:
// ... fields: [{ xtype: 'textfield', name: 'name', fieldLabel: 'Name', anchor: '100%' // Растянем ширину поля }, { xtype: 'textarea', name: 'description', fieldLabel: 'Description', anchor: '100%' // Растянем ширину поля }, { xtype: 'xcheckbox', // Меняем xtype name: 'active', fieldLabel: 'Active', boxLabel: 'Yes' // Добавим текст у флажка } ], // ...
Напоследок рассмотрим, как можно указать для формы значения по умолчанию. Пусть чекбокс будет по умолчанию отмечен.
Для этого перед тем, как показать окно пользователю, нужно установить нужные значения. Чтобы не нагромождать «змейку» из команд для окна, сохраним окно в переменную, например, w:
// ... tbar: [{ xtype: 'button', text: 'Create thing', cls: 'primary-button', handler: function() { var w = MODx.load({ // Сохраним объект окна в переменную xtype: 'things-window-names', listeners: { success: { fn: function () { this.refresh(); }, scope: this } } }); w.setValues({active: true}); // Устанавливаем нужные значения w.show(); // Показываем окно пользователю } } ] // ...
На этом механизм создания объектов можно считать реализованным. Дальше попробуем дать пользователю возможность наши объекты редактировать.
Пытаюсь заджоинить таблицу
Т.е. при выполнении в консоли (я про компонент Console), все отрабатывает корректно, но при попытки переноса данную конструкцию в процессор, к сожалению ничего не выходит.
В журнале ошибок девственно пусто!
Проблема была вот в чем:
Искал проблему в запросе а она оказалась в рендере «fields: ['id','name', 'tableone_id']» :)
Может кому пригодится, проверил ответ так:
Подскажи, пожалуйста, как используя несколько экземпляров таблицы передавать в них уникальный параметр?
Например, расписание на неделю. В семи вкладках по дням недели располагаем по экземпляру таблицы. Как в каждую из них передать номер дня недели и затем этот номер передать в процессоры?
Вот в блоке items хотелось бы подгрузить чекбоксы, со значениям со своей таблицы, а не те, что прописаны жестко в коде. Спасибо заранее)
Сортировка происходит, но только в пределах загруженной страницы, Илья подскажите пожалуйста, как сделать чтоб сортировалась полностью таблица
Если все предыдущие уроки усвоены, думаю, можно перейти к урокам Василия Наумкина: bezumkin.ru/training/course1/
Было бы здорово продолжить)) Осталось совсем немного)) На самом интересном остановились))