ux.plup.File plupload 集成 ux.plup.FileLis 批量上传预览

Posted 魔狼再世

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ux.plup.File plupload 集成 ux.plup.FileLis 批量上传预览相关的知识,希望对你有一定的参考价值。

  1 //plupload 集成
  2 Ext.define(‘ux.plup.File‘, {
  3     extend: ‘Ext.form.field.Text‘,
  4     xtype: ‘plupFile‘,
  5     alias: [‘widget.plupFile‘],
  6     requires: [‘Ext.form.trigger.Component‘, ‘Ext.button.Button‘, ‘Ext.window.Toast‘],
  7     //plup对象
  8     uploader: null,
  9     //上传文件最大数量限制,最小只能设置为1
 10     maxFileCount: 1,
 11     //是否单文件上传,结合FileList使用时必须设置为false,否则不会有预览效果
 12     onlyOne: true,
 13     //上传地址,必须
 14     url: ‘upload.php,
 15     //上传控件配置
 16     pluploadConfig: {
 17         //url 服务器端的上传页面地址,必须指定
 18         //swf文件,当需要使用swf方式进行上传时需要配置该参数,必须指定
 19         flash_swf_url: ‘app/js/plupload/js/Moxie.swf‘,
 20         //用来指定上传方式,指定多个上传方式请使用逗号隔开。一般情况下,你不需要配置该参数,因为Plupload默认会根据你的其他的参数配置来选择最合适的上传方式。如果没有特殊要求的话,Plupload会首先选择html5上传方式,如果浏览器不支持html5,则会使用flash或silverlight,如果前面两者也都不支持,则会使用最传统的html4上传方式。如果你想指定使用某个上传方式,或改变上传方式的优先顺序,则你可以配置该参数。
 21         //html5,flash,silverlight,html4
 22         runtimes: ‘html5,flash,html4‘,
 23         // 可以使用该参数来限制上传文件的类型,大小等,该参数以对象的形式传入,它包括三个属性: 
 24         filters: {
 25             //mime_types:用来限定上传文件的类型,为一个数组,该数组的每个元素又是一个对象,该对象有title和extensions两个属性,title为该过滤器的名称,extensions为文件扩展名,有多个时用逗号隔开。该属性默认为一个空数组,即不做限制。
 26             //max_file_size:用来限定上传文件的大小,如果文件体积超过了该值,则不能被选取。值可以为一个数字,单位为b,也可以是一个字符串,由数字和单位组成,如‘200kb‘
 27             //prevent_duplicates:是否允许选取重复的文件,为true时表示不允许,为false时表示允许,默认为false。如果两个文件的文件名和大小都相同,则会被认为是重复的文件
 28             prevent_duplicates: true
 29         }
 30         // multi_selection:是否可以在文件浏览对话框中选择多个文件,true为可以,false为不可以。默认true,即可以选择多个文件。需要注意的是,在某些不支持多选文件的环境中,默认值是false。比如在ios7的safari浏览器中,由于存在bug,造成不能多选文件。当然,在html4上传方式中,也是无法多选文件的。 
 31     },
 32     /**
 33      * @cfg {String} emptyText
 34      * Overridden to undefined as {@link #emptyText} is not supported with {@link #inputType inputType}:‘file‘ and should be avoided.
 35      * The default text to place into an empty field.
 36      */
 37     emptyText: undefined,
 38 
 39     needArrowKeys: false,
 40 
 41     triggers: {
 42         //禁用时显示的按钮
 43         //因为上传按钮禁用效果无效,所以在禁用时显示另外一个按钮
 44         //这样就可以避免禁用按钮失效的bug
 45         disableButton: {
 46             type: ‘component‘,
 47             hideOnReadOnly: false,
 48             hidden: true,
 49             // Most form fields prevent the default browser action on mousedown of the trigger.
 50             // This is intended to prevent the field‘s input element from losing focus when
 51             // the trigger is clicked.  File fields disable this behavior because:
 52             // 1. The input element does not receive focus when the field is focused. The button does.
 53             // 2. Preventing the default action of touchstart (translated from mousedown
 54             // on mobile browsers) prevents the browser‘s file dialog from opening.
 55             preventMouseDown: false
 56         },
 57         filebutton: {
 58             type: ‘component‘,
 59             hideOnReadOnly: false,
 60             // Most form fields prevent the default browser action on mousedown of the trigger.
 61             // This is intended to prevent the field‘s input element from losing focus when
 62             // the trigger is clicked.  File fields disable this behavior because:
 63             // 1. The input element does not receive focus when the field is focused. The button does.
 64             // 2. Preventing the default action of touchstart (translated from mousedown
 65             // on mobile browsers) prevents the browser‘s file dialog from opening.
 66             preventMouseDown: false
 67         }
 68     },
 69 
 70     //<locale>
 71     /**
 72      * @cfg {String} buttonText
 73      * The button text to display on the upload button. Note that if you supply a value for
 74      * {@link #buttonConfig}, the buttonConfig.text value will be used instead if available.
 75      */
 76     buttonText: ‘选择文件‘,
 77     //</locale>
 78     /**
 79      * @cfg {Boolean} buttonOnly
 80      * True to display the file upload field as a button with no visible text field. If true, all
 81      * inherited Text members will still be available.
 82      */
 83     buttonOnly: false,
 84 
 85     /**
 86      * @cfg {Number} buttonMargin
 87      * The number of pixels of space reserved between the button and the text field. Note that this only
 88      * applies if {@link #buttonOnly} = false.
 89      */
 90     buttonMargin: 3,
 91 
 92     /**
 93      * @cfg {Boolean} clearOnSubmit
 94      * 提交后清除值
 95      */
 96     clearOnSubmit: true,
 97 
 98     /**
 99      * @private
100      */
101     extraFieldBodyCls: Ext.baseCSSPrefix + ‘form-file-wrap‘,
102 
103     /**
104      * @private
105      */
106     inputCls: Ext.baseCSSPrefix + ‘form-text-file‘,
107 
108     /**
109      * @cfg {Boolean} [readOnly=true]
110      *只读,禁止修改
111      */
112     readOnly: true,
113 
114     /**
115      * @cfg {Boolean} editable
116      * @inheritdoc
117      */
118     editable: false,
119     //form表单中不提交值
120     submitValue: true,
121 
122     /**
123      * Do not show hand pointer over text field since file choose dialog is only shown when clicking in the button
124      * @private
125      */
126     triggerNoEditCls: ‘‘,
127 
128     /**
129      * @private
130      * Extract the file element, button outer element, and button active element.
131      */
132     childEls: [‘browseButtonWrap‘],
133 
134     /**
135      * @private 创建上传按钮
136      */
137     applyTriggers: function (triggers) {
138         var me = this,
139         triggerCfg = (triggers || {}).filebutton,
140         disableCfg = triggers.disableButton;
141         //增加禁用按钮
142         if (disableCfg) {
143             disableCfg.component = Ext.apply({
144                 xtype: ‘button‘,
145                 ownerCt: me,
146                 id: me.id + ‘-disableButton‘,
147                 ui: me.ui,
148                 disabled: true,
149                 text: me.buttonText
150             })
151         }
152         //增加上传按钮
153         if (triggerCfg) {
154             triggerCfg.component = Ext.apply({
155                 xtype: ‘button‘,
156                 ownerCt: me,
157                 id: me.id + ‘-button‘,
158                 ui: me.ui,
159                 disabled: me.disabled,
160                 text: me.buttonText,
161                 //设置margin-left
162                 style: me.buttonOnly ? ‘‘ : me.getButtonMarginProp() + me.buttonMargin + ‘px‘,
163                 listeners: {
164                     scope: me,
165                     render: me.createPlup
166                 }
167             },
168             me.buttonConfig);
169 
170             return me.callParent([triggers]);
171         }
172             // <debug>
173         else {
174             Ext.raise(me.$className + ‘ requires a valid trigger config containing "button" specification‘);
175         }
176         // </debug>
177     },
178 
179     /**
180      * @private
181      */
182     onRender: function () {
183         var me = this,
184         inputEl, button, buttonEl, trigger;
185 
186         me.callParent(arguments);
187 
188         inputEl = me.inputEl;
189         //它不应该有name
190         inputEl.dom.name = ‘‘;
191 
192         //有些浏览器会显示在该领域的闪烁的光标,即使它是只读的。如果我们有这样的事情
193         //获得焦点,就转发给我们focusEl。还注意到,在IE中,文件输入作为处理
194         //2元素Tab键的目的(文本,然后按钮)。所以,当你通过TAB键,这将需要2
195         //标签才能到下一个字段。据我知道有没有办法解决这个在任何一种合理的方式。
196         inputEl.on(‘focus‘, me.onInputFocus, me);
197         inputEl.on(‘mousedown‘, me.onInputMouseDown, me);
198         //获取上传按钮
199         trigger = me.getTrigger(‘filebutton‘);
200         button = me.button = trigger.component;
201         buttonEl = button.el;
202         if (me.buttonOnly) {
203             me.inputWrap.setDisplayed(false);
204             me.shrinkWrap = 3;
205         }
206 
207         // Ensure the trigger element is sized correctly upon render
208         trigger.el.setWidth(buttonEl.getWidth() + buttonEl.getMargin(‘lr‘));
209         if (Ext.isIE) {
210             me.button.getEl().repaint();
211         }
212     },
213     /**
214      * Gets the markup to be inserted into the subTplMarkup.
215      */
216     getTriggerMarkup: function () {
217         console.log(‘getTriggerMarkup‘);
218         return ‘<td id="‘ + this.id + ‘-browseButtonWrap" data-ref="browseButtonWrap" role="presentation"></td>‘;
219     },
220     onShow: function () {
221         this.callParent();
222         //如果我们开始了隐藏,按钮可能有一个搞砸布局
223         //因为我们不像个容器
224         this.button.updateLayout();
225     },
226     //创建上传控件
227     createPlup: function (btn) {
228         var me = this,
229         //上传配置
230         config = me.pluploadConfig,
231         //name值
232         name = me.getName(),
233         //设置上传地址
234         url = me.url,
235         uploader;
236         //获取当前按钮id
237         config.browse_button = btn.getId();
238         //指定文件上传时文件域的名称,默认为file,例如在php中你可以使用$_FILES[‘file‘]来获取上传的文件信息
239         if (name) {
240             config.file_data_name = name;
241         }
242         if (url) {
243             config.url = url;
244         }
245         //上传文件最大数量限制为1时,选择文件只能选择一个
246         if (me.maxFileCount === 1) {
247             config.multi_selection = false;
248         }
249 
250         //创建上传对象
251         uploader = me.uploader = new plupload.Uploader(config);
252         //初始化
253         uploader.init();
254         //监听错误文件被添加到上传队列时
255         uploader.bind(‘FilesAdded‘,
256         function (uploader, files) {
257             me.filesAdded(uploader, files);
258         });
259         //监听错误
260         //-602 重复文件
261         uploader.bind(‘Error‘,
262         function (uploader, file) {
263             var code = file.code;
264             if (code === -200) {
265                 //上传失败
266                 me.loadedFailure(uploader, {
267                     message: file.message
268                 });
269             } else {
270                 //抛出内部错误
271                 me.markInvalid(file.message);
272             }
273         });
274         //上传完成
275         uploader.bind(‘FileUploaded‘,
276         function (loader, file, response) {
277             response = Ext.decode(response.response);
278             if (response.success) {
279                 //上传成功
280                 me.loadedSuccess(response);
281             } else {
282                 //上传失败
283                 me.loadedFailure(loader, response);
284             }
285         });
286         //会在文件上传过程中不断触发,可以用此事件来显示上传进度 
287         uploader.bind(‘UploadProgress‘,
288         function (loader, file) {
289              Ext.Msg.updateProgress(loader.total.percent / 100, loader.total.percent + ‘%‘, ‘正在上传:‘ + file.name);
290             //console.log(loader.total.percent);
291             if (loader.total.percent == 100) {
292                 Ext.Msg.wait(‘上传成功,正在处理数据...‘,‘上传文件‘);
293             } 
294         });
295     },
296     //文件被添加到上传队列
297     //uploader 上传对象
298     //files 当前选中文件组
299     filesAdded: function (uploader, files) {
300         var me = this,
301         //上传文件最大数量限制
302         maxFileCount = me.maxFileCount,
303         //现有文件(包括新选择的文件)
304         oldFiles = uploader.files,
305         //现有文件总数
306         length = oldFiles.length,
307         i, count;
308 
309         //上传文件最大数量限制为1,并且onlyOne为true时
310         if (maxFileCount === 1 && me.onlyOne) {
311             length = length - 2;
312             //移除除最新文件之外所有文件
313             for (i = length; i >= 0; i--) {
314                 uploader.removeFile(oldFiles[i]);
315             }
316             //设置文本框显示值
317             me.setValue(oldFiles[0].name);
318         } else {
319             //文件数量超过或等于最大限制,禁用文件选择
320             if (length >= maxFileCount) {
321                 count = length - maxFileCount;
322                 //从files中移除多于最大数量限制的文件,从最新选择的文件开始移除
323                 for (i = 0; i < count; i++) {
324                     files.pop();
325                 }
326                 me.onDisable();
327             }
328             length = length - 1;
329             maxFileCount = maxFileCount - 1;
330             //移除多于最大数量限制的文件,从最新选择的文件开始移除
331             for (i = length; i > maxFileCount; i--) {
332                 uploader.removeFile(oldFiles[i]);
333             }
334             //设置文本框显示值
335             me.setValue(files[0].name);
336             //抛出事件,供FileList使用
337             me.fireEvent(‘addField‘, files);
338         }
339     },
340     //移除文件
341     removeFile: function (file) {
342         var me = this,
343         uploader = me.uploader,
344         files;
345         //移除文件
346         uploader.removeFile(file);
347         files = uploader.files;
348         //取消禁用
349         me.onEnable();
350         //设置文本框的值
351         if (uploader.files.length <= 0) {
352             me.setValue(null);
353         } else {
354             me.setValue(files[0].name);
355         }
356     },
357     submit: function (params) {
358         var me = this,
359         url = params.url,
360         waitMsg = params.waitMsg || ‘正在上传‘,
361         optionParams = params.params,
362         uploader = me.uploader;
363         //设置上传地址
364         if (url) {
365             uploader.setOption(‘url‘, url);
366         }
367         //设置参数
368         if (optionParams) {
369             uploader.setOption(‘multipart_params‘, optionParams);
370         }
371         //上传成功执行方法
372         me.success = params.success || Ext.emptyFn;
373         //上传失败执行方法
374         me.failure = params.failure || Ext.emptyFn;
375         uploader.start();
376         Ext.Msg.progress(‘上传文件‘, waitMsg);
377     },
378     //上传成功
379     loadedSuccess: function (response) {
380         Ext.MessageBox.hide();
381         this.reset();
382         //抛出事件
383         this.fireEvent(‘loadedSuccess‘, this);
384         //执行成功函数
385         this.success(response);
386     },
387     //上传失败
388     loadedFailure: function (loader, response) {
389         //停止上传
390         loader.stop();
391         //隐藏进度条
392         Ext.MessageBox.hide();
393         //重置
394         this.reset();
395         //抛出事件
396         this.fireEvent(‘loadedFailure‘, this);
397         //执行失败函数
398         this.failure(response);
399     },
400     //上传成功执行,submit方法回调
401     success: Ext.emptyFn,
402     //上传失败执行,submit方法回调
403     failure: Ext.emptyFn,
404     //重置上传控件
405     reset: function () {
406         var uploader = this.uploader,
407         files = uploader.files,
408         //现有文件总数
409         length = files.length - 1,
410         i;
411         //移除所有文件
412         for (i = length; i > -1; i--) {
413             uploader.removeFile(files[i]);
414         }
415         this.onEnable();
416         this.callParent();
417     },
418     //禁用控件tab键切换功能
419     getSubTplData: function (fieldData) {
420         var data = this.callParent([fieldData]);
421         //因为它是上传控件不应该获取焦点;
422         //然而input元素自然是可聚焦,所以我们必须
423         //由它的tabIndex设置为-1停用。
424         data.tabIdx = -1;
425 
426         return data;
427     },
428     //禁用
429     onDisable: function () {
430         this.callParent();
431         this.setFileEnable(true);
432     },
433     //取消禁用
434     onEnable: function () {
435         this.callParent();
436         this.setFileEnable(false);
437     },
438     //更改禁用状态
439     setFileEnable: function (is) {
440         var me = this;
441         //设置上传控件是否禁用
442         //某些情况下设置会失效,原因不明
443         me.uploader.disableBrowse(is);
444         //当上传按钮隐藏时显示一个假按钮
445         //上传按启用时隐藏加按钮
446         //这个解决方案是为了避免上面说的禁用失效问题
447         me.getTrigger(‘disableButton‘).setHidden(!is);
448         me.getTrigger(‘filebutton‘).setHidden(is);
449         //重绘布局
450         me.updateLayout();
451     },
452     //销毁
453     onDestroy: function () {
454         this.uploader.destroy();
455         this.callParent();
456     },
457     restoreInput: function (el) {
458         //如果我们不渲染,我们不需要做任何事情,它会创建
459         //当我们刷新到DOM。
460         if (this.rendered) {
461             var button = this.button;
462             button.restoreInput(el);
463             this.fileInputEl = button.fileInputEl;
464         }
465     },
466     getButtonMarginProp: function () {
467         return ‘margin-left:‘;
468     },
469     //输入框获得焦点
470     onInputFocus: function () {
471         this.focus();
472         //从只读输入元素切换焦点文件输入
473         //结果在文件输入的不正确的定位。
474         //添加和删除位置:相对有助于解决这个问题。
475         //见https://sencha.jira.com/browse/EXTJS-18933
476         if (Ext.isIE9m) {
477             this.fileInputEl.addCls(Ext.baseCSSPrefix + ‘position-relative‘);
478             this.fileInputEl.removeCls(Ext.baseCSSPrefix + ‘position-relative‘);
479         }
480     },
481     //点击输入框
482     onInputMouseDown: function (e) {
483         //console.log(‘onInputMouseDown‘);
484         //有些浏览器将显示即使输入是只读的光标,
485         //这将在inputEl之间聚焦随后的聚焦跳跃的短瞬间
486         //和文件按钮是可见的。 
487         //从闪烁的重点消除防止inputEl。以上是关于ux.plup.File plupload 集成 ux.plup.FileLis 批量上传预览的主要内容,如果未能解决你的问题,请参考以下文章

Plupload 上传插件 使用指南 jquery

plupload文件上传插件

如何使用 PLupload 发送附加数据?

plupload 实例

Plupload .csv 问题

前端上传插件Plupload的实际使用(个人实操)