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 批量上传预览的主要内容,如果未能解决你的问题,请参考以下文章