Знатоки ExtJS подскажите, загрузка файла Решено


Делаю компонент по обновлению цен для сайта из excel (использую modExtra, почему свое решение — цены к ресурсу указываются через migx — диапазоны, и определенная логика). Функции импорта/экспорта из excel готовы (т.е. на входе parent — на выходе xlsx, на входе xlsx — на выходе массив id=>migx json). Хочу следующее:
— вкладка Импорт
кнопка «Загрузить файл», по клику окно выбора файла с компьютера, при выборе сразу загружается и парсится — на выдаче блоки — успешно (количество), не успешно/не найдены + лог подробностей, нет в файле импорта + лог подробностей (просто инфо блоки)

— вкладка Экспорт
тут проще — кнопка «Экспорт» + таблица файлов

С организацией экспорта в принципе все понятно (но если можете подсказать фишки — буду рад).
Вот импорт — подскажите где подсмотреть типа такого (загрузка файла, получение ответа и т.п.), на jquery сделал бы влет, ExtJS — разбираюсь, но подходящего примера пока не нашел.
16 февраля 2017, 00:14    Андрей Коробков   G+  
1    368 0

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

  1. DocentBF 16 февраля 2017, 09:51 # +1
    На примере CSV.
    1. Создаем кнопку, например, в верхнем баре:
    getTopBar: function() { return [{
                text: '<i class="icon icon-chevron-up"></i> ' + _('modExtra_items_export'),
                handler: this.exportCSV, // функция-обработчик кнопки
                scope: this
    }]

    2. Добавляем виджет-окно импорта с выбором файла:
    modExtra.window.ImportCSV = function(config) {
        config = config || {};
        this.ident = config.ident || 'modextra'+Ext.id();
        Ext.applyIf(config,{
            title: _('modextra_items_import')
            ,id: this.ident
            ,fileUpload: true
            ,autoHeight: true
            ,width: 650
            ,url: modExtra.config.connector_url
            ,action: 'mgr/item/import' // процессор загрузки и обработки файла, находится по пути modExtra/processors/mgr/item/import.class.php
            ,fields: [
                {
                    xtype: 'fileuploadfield',
                    fieldLabel: _('modextra_window_import_file'),
                    allowBlank: false
                }
            ]
            ,keys: [
                {
                    key: Ext.EventObject.ENTER
                    ,shift: true
                    ,fn: function() {this.submit() }
                    ,scope: this
                }
            ]
        });
        modExtra.window.ImportCSV.superclass.constructor.call(this,config);
    };
    Ext.extend(modExtra.window.ImportCSV,MODx.Window);
    Ext.reg('modextra-window-import-csv',modExtra.window.ImportCSV);
    
    3. Создаете handler кнопки, расширяя grid:
    Ext.extend(modExtra.grid.Items, MODx.grid.Grid, {
        windows: {},
        importCSV: function (btn, e) {
            if (!this.windows.ImportCSV) {
                this.windows.ImportCSV = MODx.load({
                    xtype: 'modextra-window-import-csv'
                    ,listeners: {
                        'success': {fn:function(){this.refresh();},scope:this}
                        ,'failure': {fn:function(){console.log("error")}}
                    }
                });
            }
            this.windows.ImportCSV.fp.getForm().reset();
            this.windows.ImportCSV.show(e.target);
        },
        ...
    
    4. Создаем процессор импорта (/core/components/modextra/processors/mgr/item/import.class.php):
    <?php
    /**
     *  Import
     */
    include_once MODX_CORE_PATH . 'model/modx/processors/browser/file/upload.class.php';
    class modExtraImportProcessor extends modBrowserFileUploadProcessor {
        public $objectType = 'modExtraItem';
        public $classKey = 'modExtraItem';
        public $languageTopics = array('modExtra');
    
        public function initialize() {
            $this->setDefaultProperties(array(
                'source' => 0,
                'path' => 'assets/components/modExtra/files/',
            ));
            if (!$this->getProperty('path')) return $this->modx->lexicon('file_folder_err_ns');
            return true;
        }
    
        /** {inheritDoc} */
        public function process(){
            if (!$this->getSource()) {
                return $this->failure($this->modx->lexicon('permission_denied'));
            }
            $this->source->setRequestProperties($this->getProperties());
            $this->source->initialize();
            $this->source->setProperties(array('basePath'=>''));
            if (!$this->source->checkPolicy('create')) {
                return $this->failure($this->modx->lexicon('permission_denied'));
            }
            $success = $this->source->uploadObjectsToContainer($this->getProperty('path'),$_FILES);
            $file_n = current($_FILES);
            $file = is_array($_FILES) ? $file_n['name'] : false;
    
            if (empty($success) || !$file) {
                $msg = '';
                $errors = $this->source->getErrors();
                foreach ($errors as $k => $msg) {
                    $this->modx->error->addField($k,$msg);
                }
                return $this->failure($msg);
            } else {
                $file = $_SERVER['DOCUMENT_ROOT'].'/'.$this->getProperty('path').$file;
                if(($handle = fopen($file,"r"))) {
                    while(($data = fgetcsv($handle,null,';'))) {
                        /*
                            Далее код разборки CSV и сохранение нового объекта
                            $rec = $modx->newObject();
                            $rec->set('field', $data[$n])
                            $rec->save();
                        */                    
                    }
                    @unlink($file);
                }
            }
            return $this->success();
        }
    
    
    }
    
    return 'modExtraImportProcessor';
    
    
    Код написан на скорую руку, может быть кто-то поправит?)
    1. Илья Уткин 16 февраля 2017, 11:35 # +1
      Я загрузку файла вот так делал: ilyaut.ru/xpdo/add-the-file-download-window-extjs/
      1. Андрей Коробков 16 февраля 2017, 20:13 # 0
        Большое спасибо за наводки, завтра буду пробовать
        Вы должны авторизоваться, чтобы оставлять комментарии.