Манипулирование 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, 12:57    Константин Ильин   G+  
1    482 +1

Комментарии (4)

  1. Константин Ильин 07 октября 2016, 19:18 # 0
    Ребят, никто не сталкивался с таким?
    1. Сергей Шлоков 07 октября 2016, 19:50 # 0
      Я делаю так.
      1. Константин Ильин 07 октября 2016, 20:32 # 0
        Понял, ты как и советовал мне Илья Уткин, в ответе создаешь новые элементы.
        Ух, буду разбираться в ExtJs
        Как сделаю отпишу здесь, вдруг кому пригодиться)
        Спасибо Сергей, как всегда выручаешь!
      2. Константин Ильин 16 ноября 2016, 19:55 # +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);
        Как то так, наверняка посмотрев через год на этот код будет такая мысль:
        «Под чем я был кода писал этот код»
        Вы должны авторизоваться, чтобы оставлять комментарии.