ExtJs для новичков. Админка загрузилась. ч.1

В прошлой статье мы попытались понять как формируется интерфейс админки на ExtJs. Теперь давайте попробуем разобраться, что можно сделать интерфейсом, который нам нарисовал ExtJs.
В ExtJs за каждым элементом интерфейса (панель, окно, таблица, кнопка, элемент формы) стоит специальный объект, называемый компонентом. Он отвечает за управление элементом интерфейса — создание, отображение, скрытие, удаление. В админке MODX все элементы «являются» компонентами ExtJs, за исключением верхнего меню. Разницу можно увидеть, если заглянуть в исходный код страницы — у меню простая и привычная HTML структура (ul > li > a), а если глянем на элемент, созданный ExtJs, то увидим, что он обернут дополнительными тегами. Например, вот код кнопки тулбара дерева ресурсов
<span unselectable="on" class="x-btn x-btn-small x-btn-icon-small-left tree-new-static-resource x-btn-noicon" id="ext-comp-1062" style="">
    <em class="">
         <button type="button" id="ext-gen139" class=" x-btn-text" style=""> </button>
    </em>
</span>

Видно, что достучаться до этой кнопки через обычный javascript будет не просто, в отличие от того же главного меню. Но нас это волновать не должно. Ведь есть ExtJs и в нем предусмотрены все необходимые методы. Давайте попробуем познакомиться поближе с некоторыми.

Для примера откроем страницу любого ресурса и посмотрим на исходный её исходный код.

У всех важных элементов есть id, по которому обычно можно понять, к какому классу ExtJs принадлежит данный элемент (panel, tabpanel,tree...). А как нам изменить HTML элемент DOM с помощью ExtJs? Как раз для этого есть метод Ext.getCmp(id), где id — это значение аттрибута id элемента DOM. С помощью этого метода мы получаем объект ExtJs, отвечающий за указанный элемент, который хранится в памяти.

Для своих манипуляций с элементами админки нам необходимо создать js файл и подключить его в плагине на событие «OnManagerPageBeforeRender»
switch ($modx->event->name) {
    case 'OnManagerPageBeforeRender':
        $modx->controller->addJavascript('Url_to_file/myfile.js');
    break;
}

Упражнение


Подключаем свой обработчик события 'click', который при клике на ветку дерева будет выполнять определенный код. Подключение будет происходить, когда DOM уже построен. Для этого есть специальная функция Ext.onReady(), которая как раз и запускается, когда процесс построения DOM закончен — страница загружена и отрендерена. В jQuery эту роль выполняет $(document).ready().
Вот так будет выглядеть наш js файл.
Ext.onReady(function () {
    // Получили объект дерева ресурсов
    var tree = Ext.getCmp('modx-tree-resource');
    // Подключили свой обработчик события
    tree.on('click',function(node,e){alert(node.text);},tree);
});
А можем, например, скрыть его
tree.hide();
Также легко добавить свою кнопку на панель инструментов.
// Получаем объект компонента Ext.Toolbar, указывая его id (подглядели в коде страницы)
var tbar = Ext.getCmp('modx-resource-tree-tbar');
// Добавили ему кнопку (не в HTML код, а объекту, хранящемуся в памяти)
tbar.addButton({text:'My button'});
// А теперь заставляем объект перерисовать панель, чтобы кнопка отобразилась на странице
tbar.doLayout();

Вот так достаточно просто можно выполнить любую манипуляцию с элементом, созданным ExtJs.
Какие методы доступны для каждого класса ExtJs можно увидеть в официальной документации.

Если это интересно, пишите, что еще бы вы хотели узнать. Попытаемся разобраться вместе.
Сергей Шлоков
02 ноября 2015, 07:32
modx.pro
23
4 419
+8
Поблагодарить автора Отправить деньги

Комментарии: 11

Павел Гвоздь
02 ноября 2015, 19:06
0
Это интересно! Я однажды писал компонент, в котором есть синхронизация с одной базой товаров (около 5-7к шт). Товары выгружаются, привязываются в базе к определённому item созданному при выгрузке. А вот когда мы щёлкаем синхронизацию — открывается модальное окно, в котором указывается определённая информация для синхронизации (шаблон товаров, разделов, в какой контекст выгружать, на какое число умножить цену товаров, на какое число разделить цену). Так вот когда мы нажимаем «синхронизировать» — запускается процесс синхронизации. Сразу я столкнулся с проблемой таймаута php скриптов. Решил её постоянной отсылкой результатов скрипта обратно в админку, а с админки, если нет success=true — обратно в скрипт, и так по кругу, пока не будут выполнены определённые условия. Единственное, мне не удалось сделать так, чтобы после первой такой итерации не пропадало модальное окно. Всегда было интересно, что можно сделать в этой ситуации, чтобы модальное окно оставалось на месте до тех пор, пока не закончится синхронизация. Так к чему я это всё тут пишу: если будет возможность объяснить это или просто посмотреть код и попытаться объяснить, как это сделать — отпиши, пожалуйста, я бы выложил на гитхаб и показал, где какой момент находится.

А статьи очень полезные. Зря опускаешь руки. Не сейчас, так в будущем люди оценят!
    Сергей Шлоков
    02 ноября 2015, 23:31
    0
    Выкладывай, гляну. Если смогу, помогу. Окно не может само закрываться, где-то указан код или кнопка «Синхронизировать» закрывает.
    А по поводу тайаута Василий тут где-то уже писал про именно такое решение — порциями туда-сюда гонять. А диалоге отображать — синхронизирована 1 тысяча товаров, 2 тысячи товаров, 3 тысячи товаров…
    Николай Загумённов
    08 ноября 2015, 19:33
    +1
    Да, спасибо за статьи. Чуток соображать начинаю =)
      Tanya
      07 января 2016, 19:32
      0
      Здравствуйте, Сергей! modx изучаю недавно, поняла, что если что то хочется изменить в админке, то надо начинать изучение ExtJs, и вот нашла вашу хорошую статью для новичков. Возникла потребность по событию в плагине изменять какое то поле и результаты изменения видеть сразу же, а не после refresh страницы. Думала такой способ должен сработать:
      switch ($modx->event->name) {
          case 'OnDocFormSave':
          $resource = $modx->getObject('modResource', $id);
          $resource->set('longtitle', 'копируем заголовок');    
          $resource->save();
          $modx->event->output("<script type=\"text/javascript\">Ext.getCmp('modx-resource-longtitle').refresh();</script>");
           break;
      }
      но у меня ничего не выходит в итоге. Неужели из плагина не выполнить мою задачу? Или я неверно делаю? Подскажите, пожалуйста путь решения.
        Сергей Шлоков
        08 января 2016, 09:23
        0
        ExtJs и плагины отвечают за разное. ExtJs — это javascript, работающий на клиенте (компьютере пользователя). С его помощью можно манипулировать DOM. А плагины — это блоки php-кода, работающие на сервере, к HTML странице никакого отношения не имеют.
        Не понятно, какую задачу вы пытаетесь решить.
          Tanya
          08 января 2016, 11:36
          0
          дак я и хочу запустить javascript у клиента, но вызвать это действие по событию в плагине(например при сохранении ресурса). Задача такая: заставить обновляться поля или тв-шки, без перезагрузок страницы. Нажал кнопку сохранить, (в плагине на OnDocFormSave поменяли значение в поле(тв-шке), оно сохранилось и обновилось поле для пользователя сразу, а не только после F5.
            Іван Клімчук
            08 января 2016, 16:50
            0
            Так они и так же без перезагрузки страницы сохраняются, за исключением моментов, когда создается полностью новый ресурс. В таком случае сохраненного ресурса еще нет, потому и требуется перезагрузка страницы. Так же перезагрузка случается, если сменить шаблон, так как нужно загрузить новые TV, привязанные к новому шаблону.
            Опишите, что вам нужно сделать, а не как вы хотите и собираетесь сделать. Т.е. саму прикладную задачу или проблему. Возможно уже есть решение, но мы пока не поняли до конца суть задачи.
              Сергей Шлоков
              08 января 2016, 17:31
              0
              Я так понял, при сохранении ресурса в плагине меняются какие-то поля ресурса и эти изменившиеся поля нужно отрисовать в диалоге не обновляя его по F5.
              Для новичка MODX задача сложноватая — надо ловить событие ExtJs на обновление, посылать запрос на процессор, который должен вернуть нужные данные, и вставить их в форму.
                Іван Клімчук
                08 января 2016, 17:45
                0
                В таком случае да, одного плагина будет недостаточно. Нужно инджектить в страницу админки ExtJS плагин, который будет слушать события на кнопке save и или даже следить за отправкой запроса и получением ответа и после этого делать какой-то рефреш полей. Задачка интересная, но слегка бесполезная, мне кажется.
                  Сергей Шлоков
                  08 января 2016, 18:03
                  0
                  Задачка интересная, но слегка бесполезная, мне кажется.
                  Согласен, коллега :)
                    Tanya
                    09 января 2016, 12:04
                    0
                    ну почему бесполезная? Есть например такая задача: имею таблицу с полями(да хоть просто набор тв-шек), одно и них некий СТАТУС(имеет значение 0/1). Пользователь что то меняет в таблице и нажимает кнопку, пусть будет хотя бы «Сохранить». Вызываем плагин/сниппет, это поле СТАТУС в зависимости от др.показателей меняется. Мы сохранили изменения в бд и хотим сразу же увидеть изменённое значение этого поля. Для наглядности, что в данной строке таблицы СТАТУС изменился, значит всё хорошо. А пока что, надо F5 нажимать, чтобы увидеть изменения.
                    P.S. но в любом случае я уже поняла, что для меня это невыполнимая задача… по крайней мере пока.
          Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
          11