Давайте, добавим на страницу нашего дополнения объект типа GridPanel (xtype: grid).
У таблицы обязательными параметрами являются columns — список колонок и store — собственно список данных, которые нужно отобразить в таблице.
ExtJS Store
Параметр store есть у многих объектов в ExtJS. Обычно, если нужно отобразить какой-то список, используется параметр store. Это может быть как таблица, так и выпадающий список элементов (как в админке MODX выпадает список шаблонов при редактировании ресурса). Ещё есть, например ListView (xtype: listview), который просто выводит список элементов без возможности редактировать.
Из-за того, что таких типов несколько (а мы можем ещё и свои собственные типы создавать), store — это не просто массив, а тоже объект со своими свойствами. В ExtJS для store есть несколько типов объектов:
И не забывайте, что вы можете создавать свои типы объектов на основе существующих или вообще с нуля. Но для простой таблички нам хватит того, что уже есть. Возьмём, к примеру, ArrayStore (xtype: arraystore). В нём нужно в первую очередь перечислить список полей, которые содержатся в массиве, и, собственно, массив данных:
// ... }, { xtype: 'grid', columns: [ // Перечисляем список столбцов {dataIndex: 'id'}, {dataIndex: 'name'} ], store: new Ext.data.ArrayStore({ // Объект ArrayStore fields: ['id','name'], // Поля, доступные в массиве данных data: [ // Собственно, массив данных ([id, name]) [1, 'Pencil'], [2, 'Umbrella'], [3, 'Ball'], ] }) } // ...
Получившийся табличкой не очень удобно пользоваться =))
Это потому что мы не указали таблице высоту. Можно воспользоваться параметром height и указать высоту таблицы в пикселях, но лучше давайте скажем ExtJS, чтобы он подстроил высоту таблички под имеющиеся в ней данные:
autoHeight: true,
Уже лучше, но теперь хочется растянуть табличку ещё и по ширине. Для управлением внешним видом таблички есть параметр viewConfig
viewConfig: { forceFit: true }
Данные в таблицах бывают разные и ширина столбцов не должна быть одинаковой — ведь в каком-то столбце могут быть только числа, а в каком-то может быть длинный текст. У колонок в ExtJS можно задать ширину в пикселях. А если указан параметр forceFit, то ширина колонок будет пропорциональна числу, указанному в параметре width.
Поэтому, возьмём общую условную ширину таблицы за 1000 пикселей и укажем ширину столбцов, соответствующую такой таблице. А уже ExtJS растянет её на всю ширину экрана самостоятельно. Я сделаю пропорцию столбцов 33% — 67%. А ещё, давайте укажем названия столбцов:
// ... }, { xtype: 'grid', columns: [ // Добавляем ширину и заголовок столбца {dataIndex: 'id', width: 330, header: 'ID'}, {dataIndex: 'name', width: 670, header: 'Name'} ], autoHeight: true, // Высота таблицы вычисляется автоматически viewConfig: { forceFit: true, // Растягиваем таблицу на всю ширину scrollOffset: 0 // Убираем вертикальный скролл (у нас же автовысота) }, store: new Ext.data.ArrayStore({ fields: ['id','name'], data: [ [1, 'Pencil'], [2, 'Umbrella'], [3, 'Ball'], ] }) } // ...
У MODX есть свой объект таблицы с прописанными свойствами, методами и оформлением — MODx.grid.Grid попробуем создать свою табличку на основе этой заготовки.
Сначала опишем свойства нашего объекта в конце файла (там, где заканчивается Things.panel.Home). В объекте Things у нас уже есть вложенный объект gird, вот внутри него и создадим нашу табличку:
// ... }, { // Убираем все свойства в описание объекта xtype: 'things-grid-names' // Оставляем только xtype, заменив его на наш собственный } // ... // Внутри Things есть grid. Вот внутри него и создаём свой объект Things.grid.Names = function (config) { // Придумываем название, например, «Names» config = config || {}; Ext.apply(config, { // Сюда перемещаем все свойства нашей таблички columns: [ {dataIndex: 'id', width: 330, header: 'ID'}, {dataIndex: 'name', width: 670, header: 'Name'} ], autoHeight: true, viewConfig: { forceFit: true, scrollOffset: 0 }, store: new Ext.data.ArrayStore({ fields: ['id','name'], data: [ [1, 'Pencil'], [2, 'Umbrella'], [3, 'Ball'], ] }) }); Things.grid.Names.superclass.constructor.call(this, config); // Магия } Ext.extend(Things.grid.Names, Ext.grid.GridPanel); // Наша табличка расширяет GridPanel Ext.reg('things-grid-names', Things.grid.Names); // Регистрируем новый xtype
Мы можем зарегистрировать любой xtype, например, 'my-super-puper-table'. Но чтобы потом не запутаться в своих xtype, лучше в их названиях отображать структуру объектов.
Теперь попробуем изменить объект, который будет расширять наша табличка:
// ... Ext.extend(Things.grid.Names, MODx.grid.Grid); // ...
Объект MODx.grid.Grid подразумевает, что store не прописывается в файле ввиде массива, а запрашивает данные у сервера. Поэтому нужно указать адрес нашего коннектора и action, который будет запрашиваться, а также сюда перенесём список полей:
// ... url: Things.config.connector_url, action: 'mgr/thing/getlist', fields: ['id','name'] // ...
Свойство store удаляем — оно нам больше не нужно.
Чтобы вместо надписи Request completed появился список записей, меняем код процессора:
<?php class ThingsGetListProcessor extends modProcessor { public function process() { return json_encode(array( 'success' => true, 'total' => 3, 'results' => array( array('id' => 1, 'name' => 'Pencil'), array('id' => 2, 'name' => 'Umbrella'), array('id' => 3, 'name' => 'Ball') ) )); } } return "ThingsGetListProcessor";
Если в таблице предполагается большое количество записей, принято не выводить их все, а реализовать пагинацию. Нам для этого делать ничего не надо — пагинацией пусть занимается ExtJS. Просто добавим параметр paging
// ... paging: true, pageSize: 1, // количество записей на странице // ...
Осталось научить процессор работать с параметрами start и limit:
<?php class ThingsGetListProcessor extends modProcessor { public function process() { $array = array(); switch ($this->getProperty('start')) { case 0: $array[] = array('id' => 1, 'name' => 'Pencil'); break; case 1: $array[] = array('id' => 2, 'name' => 'Umbrella'); break; case 2: $array[] = array('id' => 3, 'name' => 'Ball'); break; default: break; } return json_encode(array( 'success' => true, 'total' => 3, 'results' => $array )); } } return "ThingsGetListProcessor";
Конечно, данные в процессоре нужно получать из базы данных, а параметры start и limit передавать в запрос. Для этого в MODX тоже есть свои заготовки. Мы рассмотрим их в следующей части.
Не могли бы вы в конце писать итоговое, что получилось.
А то всё было понятно, и даже очень(в разы лучше, чем у Безумкина), но вот после этих сокращений…
понять что и где происходит дальше становится тяжко(мне, как новичку).
Благодарю.
Илья, не подскажешь как можно менять заголовки у таблиц в ExtJS? Т.е. мне нужно, чтобы columns и fields менялись при пагинации, например! Ну скажем по принципу календаря, я хочу выводить даты в виде заголовков. Ну или например, если я из процессора помимо results передам еще и headers, как их можно вытащить из интерфейса ExtJS и подставить в columns и fields?
Например, отсюда:
Написал пример на codepen. Там закомментированный код именно это и делает!