Манипулирование ExtJs на лету через процессор

Оказалось проблема насущная:
Скинемся с миру по нитке решениями)
Например:
Создание textfield на лету при создание(редактирование) записи, т.е. При нажатии Добавить, всплывает окно в котором на лету созданные textfield, к примеру 3 штуки, а если это UPDATE то и их значение соответственно, помимо этого есть поля не созданные на лету.
При сохранение отправляется в процессор, в котором поля созданные на лету колбасятся в JSON и записыватся в 1 колонку БД.

Вроде ничего такого сложного, но встает проблема запроса получения массива полей на лету и передача его в вызов Всплывающего окна. Ajax запрос отрабатывает позже чем весь код, поэтому console.log(fieldsArr + ' — массив полей') не выводит массив или return не срабатывает.


Есть процессор, в нем получаю массив полей
foreach ($arr as $value) {

               $fields[] = array(
                    'xtype' => 'textfield',
                    'fieldLabel' => $value['code'],
                    'name' => $value['code'],
                    'id' => "config.id + '-".$value['code']."'",
                    'anchor' => "99%",
                    'allowBlank' => "false",
                    'value' => ''
                );
           }
	return $this->success('ok',$fields);


Обращаюсь к этому процессору и хочу вставить в функцию определения полей getFields:
Ext.extend(Trans.window.CreateItem, MODx.Window, {

    getFields: function (config) {
        var fieldsArr = '';
        MODx.Ajax.request({
            url: Trans.config.connectorUrl
            ,params: {
                action: "mgr/tr_data/get_fields",
                id_res: MODx.request.id,
                createAction: true
            } 
            ,listeners: {
                success: {fn: function(response) {
                    //console.log(response);
                    fieldsArr = response['object'];
                     console.log(fieldsArr+ 'success');
                }, scope: this}
            }
        });

        console.log(fieldsArr + ' - массив полей');
        return [{
            xtype: 'textfield',
            fieldLabel: _('trans_lang_name'),
            name: 'name',
            id: config.id + '-name',
            anchor: '99%',
            allowBlank: false,
        }, {
            xtype: 'textfield',
            fieldLabel: _('trans_lang_code'),
            name: 'code',
            id: config.id + '-code',
            allowBlank: false,
            anchor: '99%'
        }, {
            xtype: 'xcheckbox',
            boxLabel: _('trans_lang_active'),
            name: 'active',
            id: config.id + '-active',
            checked: true,
        }];
    },

    loadDropZones: function () {
    }

});
Ext.reg('trans-item-window-create', Trans.window.CreateItem);

Смотрел migx, там все в tpl файлах, т.е. весь js код.

Пока пришла только одна идея сделать по старому — это создать php файл в котором выводится весь js вызова окна и там уже подставляются поля, т.е. объединить весь код выше в php файл.

Кто как решает такие задачи?
Константин Ильин
04 октября 2016, 09:57
modx.pro
2
2 877
+1

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

Константин Ильин
07 октября 2016, 19:18
0
Ребят, никто не сталкивался с таким?
    Сергей Шлоков
    07 октября 2016, 19:50
    0
    Я делаю так.
      Константин Ильин
      07 октября 2016, 20:32
      0
      Понял, ты как и советовал мне Илья Уткин, в ответе создаешь новые элементы.
      Ух, буду разбираться в ExtJs
      Как сделаю отпишу здесь, вдруг кому пригодиться)
      Спасибо Сергей, как всегда выручаешь!
      Константин Ильин
      16 ноября 2016, 19:55
      2
      +2
      Чтож, уже ноябрь, но лучше поздно чем никогда)

      Спасибо Сергей Шлокову, он на пальцах мне обьяснил что так как я хотел сделать выше — нельзя.
      Последовательность такая:
      1. Нажимается кнопка.
      2. В функции кнопки вызывается ajax запрос к процессору который выдает поля.
      3. Только когда ajax выполнился вызывается окно. В вызов окна сразу подсовываются готовые поля, сформированные из ответа ajax.

      Код функции процессора — process ()
      public function process()
          {
              /*некий код*/
      	$fields = '';
              // Существует какая то некая таблица в которой 1 строка это поле
              $table = $this->modx->getTableName('FieldsItems');
              $query = $this->modx->query("SELECT * FROM ".$table." WHERE active = 1");
      	
              if (!is_object($query)) {
                 
                 return $this->failure($this->modx->lexicon('fl_data_err_get_field'));
      
              }else{
      
                 $arr = $query->fetchAll(PDO::FETCH_ASSOC);
      
                 foreach ($arr as $value) {
      
                     $fields[] = array(
                          'xtype' => 'textarea',
                          'fieldLabel' => $value['name'],
                          'name' => "fl-".$value['code'],
                          'id' => 'ext-gen-fl-'.$value['code'],
                          'anchor' => "99%",
                          'allowBlank' => "false",
                          'value' => $fieldsValues[$value['code']] 
                      );
                 }
      
              }
              return $this->success('',$fields); // Возвращаем массив полей
          }

      Как это в EXT.JS. Тут два запроса ajax, первый получает поля, второй к процессору get который выдает данные об объекте.
      MODx.Ajax.request({
                  url: Fl.config.connectorUrl
                  ,params: {
                      action: "mgr/data/get_fields", // Тот самый процессор который выдает поля
                      id_res: MODx.request.id,
                  }
                  ,listeners: {
                      success: {fn: function(res) {
                          
                          var fieldsArr = res['object']; // Ответ от процессора с полями, он возвращает массив с данными полей
                          fieldsArr = fieldsArr || {}; 
                          MODx.Ajax.request({
                              url: this.config.url,
                              params: {
                                  action: 'mgr/data/get',
                                  id: MODx.request.id,
                              },
                              listeners: {
                                  success: {
                                      fn: function ( r ) { 
                                         
                                          var w = MODx.load({
                                              xtype: 'fl-data-window-update',
                                              id: Ext.id(),
                                              addFields: fieldsArr, // Здесь передаем поля в вызов окна
                                              record: r,
                                              listeners: {
                                                  success: {
                                                      fn: function () {
                                                          this.refresh();
                                                      }, scope: this
                                                  },
                                                  hide: {
                                                      fn: function () {
                                                          setTimeout(function(){w.destroy();},200);
                                                      }, scope: this
                                                  }
                                              }
                                          });
                                          w.reset();
                                          w.setValues(r.object);
                                          w.show(e.target);
                                      }, scope: this
                                  }
                              }
                          });
                      }, scope: this}
                  }
              });

      В extende окна:
      Ext.extend(Fl.window.UpdateItem, MODx.Window, {
      
          getFields: function (config) {
              return [{
                  xtype: 'hidden',
                  name: 'id',
                  id: config.id + '-id',
                  value: config.id
              },{
                  xtype: 'xcheckbox',
                  boxLabel: _('fl_lang_active'),
                  name: 'active',
                  id: config.id + '-active',
                  checked: true,
              },
                  config.addFields   // ВОТ ТУТ И ДОБАВЛЯЮТСЯ ПОЛЯ, т.е. тот массив полей который передали в ajax запросе
              ];
          },
      
          loadDropZones: function () {
          }
      
      });
      Ext.reg('fl-data-window-update', Fl.window.UpdateItem);
      Как то так, наверняка посмотрев через год на этот код будет такая мысль:
      «Под чем я был кода писал этот код»
        unreal_serg
        13 августа 2021, 16:00
        0
        Блин, я года два назад искал точно такое же решение — чтобы поля после ajax-запроса формировались. Так и не нашел! А углубляться в Ext JS тупо времени не было. Пришлось сделать на Jquery и в чистом tpl без заготовок!
        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
        5