一个Ext2+SWFUpload做的图片上传对话框的例程

我们先看看对话框的布局:

布局就是在一个窗口里内嵌一个表格控件,窗口的底部工具条带一个进度条,表格的顶部工具条带几个操作按钮和一个下来选择框,底部工具条作为一个信息显示区域显示文件的总数和总的上传大小。
我们来分析一下uploadDialog.js文件:
  1. var Application={};
  2. Application.uploadDialog={
  3. progressBarText:'正在上传:{0},{1}%完成',
  4. statuBarText:'文件总数:{0}个  ,大小:{1}',
  5. show:function(data){
  6. if(!this.dialog)
  7. this.initDialog();
  8. //this.uploadGrid.store.removeAll();
  9. if(data)
  10. this.classStore.loadData(data);
  11. this.uploadAction[0].enable();
  12. this.uploadAction[1].disable();
  13. this.uploadAction[2].disable();
  14. this.uploadAction[3].disable();
  15. this.uploadAction[4].enable();
  16. //this.uploadProgressBar.updateProgress(0,'');
  17. this.dialog.show();
  18. },
  19. hide:function(){
  20. this.dialog.hide();
  21. },
  22. classStore:new Ext.data.SimpleStore({fields: ["id", "text"],data:[]}),
  23. uploadAction:[
  24. new Ext.Action({text:'增加',
  25. handler:function(){
  26. Application.uploadDialog.swfu.selectFiles();
  27. }
  28. }),
  29. new Ext.Action({text:'删除',disabled:true,handler:function(){
  30. var obj=Application.uploadDialog;
  31. var grid=obj.uploadGrid;
  32. var store=grid.store;
  33. var selection=grid.getSelectionModel().getSelections();
  34. for(var i=0;i<selection.length;i++){
  35. var rec=store.getAt(store.indexOfId(selection[i].id));
  36. obj.swfu.cancelUpload(rec.data.id);
  37. store.remove(rec);
  38. }
  39. obj.stateInfo.getEl().innerHTML=String.format(obj.statuBarText,obj.uploadGrid.store.getCount(),Ext.util.Format.fileSize(obj.uploadGrid.store.sum('size')));
  40. if(obj.uploadGrid.store.getCount()==0){
  41. obj.uploadGrid.store.removeAll();
  42. obj.uploadAction[1].disable();
  43. obj.uploadAction[2].disable();
  44. obj.uploadAction[3].disable();
  45. }
  46. }}),
  47. new Ext.Action({text:'清空',disabled:true,handler:function(){
  48. var obj=Application.uploadDialog;
  49. var store=obj.uploadGrid.store;
  50. var len=store.getCount();
  51. for(var i=0;i<len;i++){
  52. var rec=store.getAt(i);
  53. obj.swfu.cancelUpload(rec.data.id);
  54. }
  55. store.removeAll();
  56. obj.classCombo.clearValue();
  57. obj.stateInfo.getEl().innerHTML=String.format(obj.statuBarText,0,Ext.util.Format.fileSize(0));
  58. obj.uploadProgressBar.updateProgress(0,'');
  59. obj.uploadProgressBar.updateText("");
  60. obj.uploadAction[0].enable();
  61. obj.uploadAction[1].disable();
  62. obj.uploadAction[2].disable();
  63. obj.uploadAction[3].disable();
  64. }}),
  65. new Ext.Action({text:'上传',disabled:true,handler:function(){
  66. var obj=Application.uploadDialog;
  67. obj.uploadAction[0].disable();
  68. obj.uploadAction[1].disable();
  69. obj.uploadAction[2].disable();
  70. obj.uploadAction[3].disable();
  71. obj.uploadAction[4].disable();
  72. var store=obj.uploadGrid.store;
  73. var len=store.getCount();
  74. var classid=obj.classCombo.getValue();
  75. obj.swfu.setPostParams({'classid':classid});
  76. obj.swfu.startUpload();
  77. }}),
  78. new Ext.Action({text:'关闭',handler:function(){
  79. Application.uploadDialog.hide();
  80. }}),
  81. ],
  82. initDialog:function(){
  83. this.classCombo=new Ext.form.ComboBox({
  84. hiddenName:'classid',name: 'classid_name',valueField:"id",displayField:"text",mode:'local',
  85. store:this.classStore,blankText:'请选择类别',emptyText:'请选择类别',editable:true,anchor:'90%'
  86. })
  87. this.swfu=new SWFUpload({
  88. upload_url:"upload.asp",
  89. file_size_limit : "102400",
  90. file_types : "*.jpg;*.gif",
  91. file_types_description : "图片文件(*.jpg,*.gif)",
  92. file_upload_limit : "30",
  93. file_dialog_start_handler : this.fileDialogStart,
  94. file_queued_handler : this.fileQueued,
  95. file_queue_error_handler : this.uploadError,
  96. file_dialog_complete_handler : this.fileDialogComplete,
  97. upload_start_handler : this.uploadFileStar,
  98. upload_progress_handler : this.uploadProgress,
  99. upload_error_handler : this.uploadError,
  100. upload_complete_handler : this.uploadQueueComplete,
  101. file_complete_handler : this.uploadFileComplete,
  102. flash_url:"swfupload.swf",
  103. ui_container_id : "SWFUploadTarget",
  104. degraded_container_id : "divDegraded",
  105. debug: false
  106. })
  107. this.dialog=new Ext.Window({
  108. layout:'fit',width:600,height:500,title:'上传图片',closeAction:'hide',border:false,modal:true,
  109. plain:true,closable:false,resizable:false,
  110. bbar:[this.uploadProgressBar=new Ext.ProgressBar({width:586})],
  111. items:[
  112. Application.uploadDialog.uploadGrid=new Ext.grid.GridPanel({
  113. autoExpandColumn:2,enableHdMenu:false,
  114. tbar:[Application.uploadDialog.uploadAction[0],Application.uploadDialog.uploadAction[1],Application.uploadDialog.uploadAction[2],
  115. '-',Application.uploadDialog.uploadAction[3],"-",Application.uploadDialog.classCombo,"->"
  116. ,Application.uploadDialog.uploadAction[4]],
  117. bbar:[Application.uploadDialog.stateInfo=new Ext.Toolbar.TextItem(String.format(Application.uploadDialog.statuBarText,0,Ext.util.Format.fileSize(0)))],
  118. store: new Ext.data.SimpleStore({fields: ["id","state", "file","size","type"],data:[]}),
  119. columns:[
  120. new Ext.grid.RowNumberer(),
  121. {id:'id',header: "id",hidden:true,width:150,dataIndex:'id',resizable:false,sortable:false},
  122. {header: "文件名",width:Ext.grid.GridView.autoFill,dataIndex:'file',sortable:true},
  123. {header: "大小", width: 80,renderer:Ext.util.Format.fileSize,dataIndex:'size',sortable:true,align:'right'},
  124. {header: "类型", width: 80,dataIndex:'type',align:'center',sortable:true},
  125. {header: "状态", width: 100,dataIndex:'state',align:'center',sortable:true}
  126. ]
  127. })
  128. ]
  129. })
  130. },
  131. fileQueued:function(file){
  132. var obj=Application.uploadDialog;
  133. var filetype=(file.type.substr(1)).toUpperCase();
  134. if(filetype=='JPG' | filetype=='GIF'){
  135. var data=[];
  136. data.push([file.id,'未上传',file.name,file.size,filetype]);
  137. obj.uploadGrid.store.loadData(data,true);
  138. obj.uploadAction[1].enable();
  139. obj.uploadAction[2].enable();
  140. obj.uploadAction[3].enable();
  141. obj.stateInfo.getEl().innerHTML=String.format(obj.statuBarText,obj.uploadGrid.store.getCount(),Ext.util.Format.fileSize(obj.uploadGrid.store.sum('size')));
  142. }
  143. },
  144. uploadFileStar:function(file){
  145. var obj=Application.uploadDialog;
  146. var index=obj.findData(file.id);
  147. if(index>=0){
  148. obj.uploadGrid.store.getAt(index).set('state','正在上传……');
  149. }
  150. obj.uploadProgressBar.updateProgress(0,String.format(obj.progressBarText,file.name,0));
  151. return true;
  152. },
  153. uploadProgress:function(file,bytesloaded){
  154. var obj=Application.uploadDialog
  155. var percent = Math.ceil((bytesloaded / file.size) * 100);
  156. obj.uploadProgressBar.updateProgress(percent/100,String.format(obj.progressBarText,file.name,percent));
  157. },
  158. uploadFileComplete:function(file){
  159. var obj=Application.uploadDialog;
  160. var index=obj.findData(file.id);
  161. if(index>=0){
  162. obj.uploadGrid.store.getAt(index).set('state','已上传');
  163. }
  164. if(obj.swfu.getStats().files_queued>0)
  165. obj.swfu.startUpload();
  166. },
  167. uploadFileCancelled:function(file, queuelength){
  168. },
  169. uploadQueueComplete:function(file,server_data){
  170. console.log(server_data);
  171. if(server_data=='ok'){
  172. var obj=Application.uploadDialog;
  173. obj.uploadProgressBar.updateProgress(1,'完成上传');
  174. obj.uploadAction[2].enable();
  175. obj.uploadAction[4].enable();
  176. }else{
  177. alert(server_data);
  178. }
  179. },
  180. uploadError:function(file,errcode,msg){
  181. var index=Application.uploadDialog.findData(file.id);
  182. if(index>=0)
  183. Application.uploadDialog.uploadGrid.store.getAt(index).set('state','上传失败');
  184. //alert(errcode+','+file.name+','+msg)
  185. },
  186. uploadCancel:function(file, queuelength){
  187. var index=Application.uploadDialog.findData(file.id);
  188. if(index>=0)
  189. Application.uploadDialog.uploadGrid.store.getAt(index).set('state','取消上传');
  190. },
  191. fileDialogStart:function(){
  192. },
  193. fileDialogComplete:function (num_files_queued){
  194. },
  195. findData:function(id){
  196. var rowindex=Application.uploadDialog.uploadGrid.store.find('id',id);
  197. return rowindex;
  198. }
  199. }//Application.uploadDialog

在文件里我先定义了一个Application 对象(Application={}),对象为JSON结构,主要方便将应用的各个功能模块作为Application的一个子对象,方便未来调用与区分。当然了,如果你不喜欢的话可以不要这个,不过这文件就要修改不少东西(:))。

接着我定义了Application的子对象uploadDialog(Application.uploadDialog),改对象主要两个方法是show和hide。
在show方法里可以传入下拉对话框的数据。在show方法里我们首先判断对话框是否已初始化(if(!this.dialog)),如果还没初始化就初始化对话框(this.initDialog())。初始化之后我们就在下来对话框里加载数据(this.classStore.loadData(data)),这个加载方法可参考我的另一片文章《Ext2.0本地模式动态修改combobox选择项》。然后就是设置一下按钮的开关属性,最后是显示对话框。
hide方法主要是关闭对话框了。
我们接着看初始化对话框这函数。
函数第一部是创建了一个下拉对话框并将用uploadDialog的子对象classCombo记录下该对象方便操作。下拉对话框的定义请参考我的文章《Ext2.0 form实例》。这里要注意的是我已经定义了一个下拉对话框的数据存储对象classStore,直接定义给下拉对话框的store属性就行了。
接着定义了一个SWFUpload的对象,该SWFUpload对象用的是“SWFUpload 0.8.3 Revision 7.0 by Jacob Roberts”版本,本来想用最新版本的,但是还没找到怎么传递参数的办法(我要传递图片类别参数),所以放弃了,用回旧版。SWFUpload的使用我们要注意的就是要预先在页面放置两个div容易让SWFUpload加入嵌入swf的代码。我是在页面底部加入两个隐藏的div:
  1. <div id="SWFUploadTarget"  style="height:0px;width:0px;disply:none;z-index:-1"></div>
  2. <div id="divDegraded" style="height:0px;width:0px;disply:none;z-index:-2"></div>
这里要注意的就是ui_container_id和degraded_container_id 对象的div的id不能错,呵呵。
flash_url对应的是swf文件的位置,改位置是相对于页面文件的位置,我为了方便,就放在同一目录,不然调这个挺烦的,老是因位置不对而出现错误。upload_url对应的是后台接收文件,其位置是相对于swf文件的位置,千万别搞错了。呵呵,还是放在同目录好,不用考虑路径。
因为我后台是用aspuoload组件的,所以不用考虑file_post_name属性,如果你是用php或其它后台语言,需要通过提交变量名获取文件数据则需要定义这个属性。例如php,定义file_post_name为Filedata,然后在后台通过“$_FILES["Filedata"]”提取数据。
在这个对话框里我限制了上传文件的大小最多是2M(file_size_limit : "2048"),文件类型是jpg或gif文件(file_types : "*.jpg;*.gif"),在选择对话框类型描述里显示图片文件(file_types_description : "图片文件"),一次最多上传30个文件(file_upload_limit : "30")。
下面的就是写句柄的定义了,这里下面会说到,这里就先不说明了。
最后就是定义一个窗口了,用dialog属性来保存这个窗口。窗口我设置成模态显示,不显示关闭按钮,不能改变大小。窗口的底部工具条定义了一个宽度为586的进度条,本来是不用定义的,但是auto的宽度定义,文字居中不能居中,郁闷,不然可以将窗口设置为改变大小的。
在items里就是一个表格面板了,用uploadGrid属性保存了。主要显示5列:行号、文件名、大小、类型和状态,还有一个隐藏列id。行号是Ext2.0新增的一个功能,强,哈哈。使用很简单,在列定义(columns)里将改列定义为“new Ext.grid.RowNumberer()”就行了,简单方便。隐藏列只要设置改列hidden属性为true就行了。文件大小我用了Ext的文件大小格式定义“Ext.util.Format.fileSize”,设置改列的属性renderer为“Ext.util.Format.fileSize”就行了。
为了不让用户通过标题栏的下拉列表将隐藏栏显示出来,我设置了隐藏表格的下拉列表菜单(enableHdMenu:false)。
我在uploadAction里定义了增加、删除、清空、上传、关闭等5个action,然后在表格的的顶部工具栏直接加入这些action就会自动变成按钮了:
  1. tbar:[Application.uploadDialog.uploadAction[0],Application.uploadDialog.uploadAction[1],Application.uploadDialog.uploadAction[2],
  2. '-',Application.uploadDialog.uploadAction[3],"-",Application.uploadDialog.classCombo,"->"
  3. ,Application.uploadDialog.uploadAction[4]],
感觉是不是有点***子放屁,纯粹多此一举?呵呵。其实不是的,我这样做的主要原因是action可以预先定义,因为不用生成html元件,而且如果你想帮表格加入右键菜单的时候,你可以通过action同时控制toolbar上按钮和右键菜单上的动作,如disbale、enable,而不必分别做操作,而且还有用变量记录这些对象。 如果习惯delphi的开发,应该对action很熟悉了,非常好的一个功能。
在表格底部工具栏放置了一个TextItem,内容是一个格式化的文本“文件总数:{0}个,大小:{1}”。这个格式化文本的定义在文件头部(statuBarText:'文件总数:{0}个,大小:{1}')。通过Ext的string对象将参数替换“{0}”、“{1}”等标记就是正式的显示文本了,是不是很方便?主要代码如下:
  1. new Ext.Toolbar.TextItem(String.format(Application.uploadDialog.statuBarText,0,Ext.util.Format.fileSize(0)))
String.format的第一参数就是带标记的字符串,从第二个参数开始从标记“{0}”开始进行替换。
下面我们来看看各个按钮的操作。
增加按钮(uploadAction里面的第一个action)很简单,就是调用SWFUpload的选择文件函数打开文件选择对话框。我在这里用的是多文件选择,如果需要,你可以替换为单文件选择(selectFile)。
删除按钮主要动作就是清除选择行并将SWFUpload对象里文件队列对应的文件设置为取消状态。通过表格的getSelectionModel方法获取一个选择模型,然后通过getSelections方法获取选择行。通过选择行的id(该id是表格自动创建来标识行的)在sotre对象里找到对应的行号(store.indexOfId(selection[i].id)),通过store的getAt方法获取对应的记录。因我们在记录里已经保存了SWFUpload为每个队列文件生成的id,所以我们可以通过SWFUpload的cancelUpload方法在队列中取消该文件的上传(cancelUpload (rec.data.id))。同时在store里删除该记录(store.remove(rec))。最后是更新一下状态行的统计信息和设置一下按钮的状态。
清空按钮主要作用就是清空表格信息和取消所以上传文件队列,操作方法和删除按钮类似。
上传按钮就是屏蔽各按钮,调用SWFUpload的setPostParams方法设置提交参数(setPostParams({'classid':classid})),然后通过startUpload方法开始文件上传。
关闭按钮就是关闭本窗口。
最后就是文件的处理了。
在SWFUpload定义的file_queued_handler句柄在选择文件后产生一个队列时触发,在这个函数里,我们要做的操作就是判断文件的扩展名是否符合要求,然后将数据加入store。加入方法是下来对话框的一样,使用loadData方法,不过要设置第二参数为true,表示是追加而不是覆盖旧的数据。最后是更新按钮状态和统计信息。
upload_start_handler句柄会在文件开始上传时出发。这个函数也没什么特别的地方,就是更新一下状态信息和初始化进度条。进度条的显示文本也使用了一个格式化的字符串。不过这里要注意,“return true”一定要有,不然不会上传文件,会提示错误。
upload_progress_handler句柄不用说就是上传进度了,它有两个参数,第一是文件对象,第二就是已上传的字节数,通过换算就可以获得百分比,然后更新进度条。
file_complete_handler句柄在一个文件上传完成后触发,这里要做的除了更新状态信息外,还要检查SWFUpload文件队列里是否还有要上传的文件,如果有,则继续上传(if(obj.swfu.getStats().files_queued>0) obj.swfu.startUpload();)。
upload_complete_handler句柄在文件全部上传后触发,其操作也是更新状态信息。不过可以通过第二个参数server_data获取后台反馈回来的信息,判断上传结果。
upload_error_handler句柄在文件上传发生错误时触发,这里要做的就是更新文件状态信息为“上传失败”。
还有其它的句柄我就不一一介绍了,大家可以去看相应的文章和例子。我推荐一个网址是http://swfupload.praxion.co.za/。其实我这个就是通过它这个修改过来的,呵呵。
该对话框的实用性可能不大,不过对大家学习一下Ext我觉得还是不错的例子。例子没有详细测试过,所以有bug在所难免,希望大家谅解!有什么地方不明白的请与我联系,或者有什么改进意见,也请大家给发邮件给我。多谢!
本例子例程请到我在csdn的资源那里找!相当郁闷,每次发布的资源都不能即时找到路径,不知道csdn是否还要通过审核。例子在IIS6、Firefox和装有Apsupload的机器上测试通过。后台程序的保存位置为D盘test目录,按源文件名保存,并将提交的参数写到了一个txt文件里。

例程下载地址:http://download.csdn.net/source/262788

一个Ext2+SWFUpload做的图片上传对话框相关推荐

  1. struts+swfupload实现批量图片上传(上):swfupload

    custom_settings : {progressTarget : "fsUploadProgress",cancelButtonId : "btnCancel&qu ...

  2. 关于这些年做的 图片上传下载做的处理总结(including根据图片url上传文件)

    下载文档 我们查柜的认知是后端给前端传一个链接地址,将地址放在a标签上,点击链接下载文件. 可有时候往往不是这样的,后端给前端返回了一个文档流,这就需要我们自己转换为Blob格式的数据,再使用这个数据 ...

  3. 接口自动化实现图片上传(selenium/RF)

    最近做自动化碰到一个问题: 就是带图片上传的不知道怎么实现自动化:整理了下实现如下: 上传图片postman 结果请求如下,上传图片后返回一个图片地址: post请求 body 是form-data ...

  4. 使用FCKeditor2.2图片上传的小技巧

    FCKeditor的确是个错的编辑器,从ASP.NET 1.1就开始在用. 之前没做过图片上传,最近要做个产品发布的小东西,使用ASP.NET2.0的文件上传组件老是出问题.考虑到FCKeditor中 ...

  5. Ueditor编辑器图片上传

    Ueditor编辑器图片上传 UEditor的图片上传采用了Flash上传的方式,在功能上支持批量.本地预览和实时进度提示,在界面上支持自定义背景.上传按钮和预览框等视觉元素的样式属性,基本能够满足各 ...

  6. 用Swift实现iOS相机及相册图片上传

    最近要做一个iOS相机及相册图片上传,其中遇到了这些问题:1.图片增删在UICollectionView里的变化:2.获取相机拍摄的照片和相册的照片:3.将PHAsset对象转为UIImage对象: ...

  7. $_post 数据上传到那个位置_如何实现图片上传并保存到数据库?

    (给Web前端雪儿加星标,提升前端技能) 之前写过图片上传的案例,但是时间一长就忘了,这次写的这个程序用到了图片的上传,并且能够图文显示,所以写了这篇文章来记录一下.由于人们的生活质量的提高及网络的发 ...

  8. Asp.Net Core Web Api图片上传及MongoDB存储实例教程(一)

    图片或者文件上传相信大家在开发中应该都会用到吧,有的时候还要对图片生成缩略图.那么如何在Asp.Net Core Web Api实现图片上传存储以及生成缩略图呢?今天我就使用MongoDB作为图片存储 ...

  9. Asp.Net Core Web Api图片上传(一)集成MongoDB存储实例教程

    Asp.Net Core Web Api图片上传(一)集成MongoDB存储实例教程 原文:Asp.Net Core Web Api图片上传(一)集成MongoDB存储实例教程 Asp.Net Cor ...

最新文章

  1. 百度快照被劫持跳转的解决办法
  2. 利用mem数组在MM32 MicroPython中实现COMP的功能
  3. 二十五、长短时记忆神经网络
  4. C和指针之函数之把数字字符串转为整数并且返回这个数字(ascii_to_integer)
  5. keepalived mysql双主架构图_MySQL双机热备(keepalived+mysql双主)
  6. iOS:Covert p12 back to CSR
  7. [转]Java5泛型的用法,T.class的获取和为擦拭法站台
  8. java扑克牌排序_扑克牌排列 运用List ArrayList Arrays
  9. 让lubuntu13.10中的virtualbox使用u盘
  10. java remove map_Java HashMap remove()方法
  11. JavaScript学习(二十七)—解决IE以及IE8之前的浏览器下面的添加事件或者删除事件
  12. Clean Code 《代码整洁之道》前四章读书笔记
  13. 模式识别 算法练习(一)——C均值算法
  14. mmap设备文件操作
  15. GlobalSign 企业型SSL 证书
  16. 记录MEMORY_MANAGEMENT蓝屏解决过程
  17. with recompile
  18. 有效学习python
  19. 使用OpenLayers根据经纬度对地图进行单个标点,以及点击标点弹框的实现(没有从后台获取经纬度数据)
  20. C 语言 宏定义 :字符串化 stringify 的应用

热门文章

  1. Tomcat关闭后,重新启动,session中保存的对象为什么还存在解决方法
  2. NFS企业级网络文件共享
  3. Ubuntu 安装mysql和简单操作
  4. dd skip 和 seek参数理解(转)
  5. java部署web service的方式
  6. flutter中的生命周期函数
  7. 26期20180626 rpm 安装软件包的方法 yum
  8. Docker+Jenkins持续集成环境(3)集成PMD、FindBugs、Checkstyle静态代码检查工具并邮件发送检查结果...
  9. 阿里年会的马老师说:认真生活、快乐工作、保持理想
  10. 远程SSH连接服务与基本排错