`

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

 
阅读更多

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

 

布局就是在一个窗口里内嵌一个表格控件,窗口的底部工具条带一个进度条,表格的顶部工具条带几个操作按钮和一个下来选择框,底部工具条作为一个信息显示区域显示文件的总数和总的上传大小。

我们来分析一下uploadDialog.js文件:

 

       var Application={};

       Application.uploadDialog={

             

              progressBarText:'正在上传:{0}{1}%完成',

             

              statuBarText:'文件总数:{0} ,大小:{1}',

             

              show:function(data){

                     if(!this.dialog)

                            this.initDialog();

                     //this.uploadGrid.store.removeAll();

                     if(data)

                           this.classStore.loadData(data);

                     this.uploadAction[0].enable();

                     this.uploadAction[1].disable();

                     this.uploadAction[2].disable();

                     this.uploadAction[3].disable();

                     this.uploadAction[4].enable();

                     //this.uploadProgressBar.updateProgress(0,'');

                     this.dialog.show();

              },

 

              hide:function(){

                     this.dialog.hide();

              },

 

              classStore:new Ext.data.SimpleStore({fields: ["id", "text"],data:[]}),

             

              uploadAction:[

                     new Ext.Action({text:'增加',

                            handler:function(){

                                   Application.uploadDialog.swfu.selectFiles();

                            }

                     }),

                     new Ext.Action({text:'删除',disabled:true,handler:function(){

                            var obj=Application.uploadDialog;

                            var grid=obj.uploadGrid;

                            var store=grid.store;

                            var selection=grid.getSelectionModel().getSelections();

                            for(var i=0;i<selection.length;i++){

                                   var rec=store.getAt(store.indexOfId(selection[i].id));

                                   obj.swfu.cancelUpload(rec.data.id);

                                   store.remove(rec);

                            }

                            obj.stateInfo.getEl().innerHTML=String.format(obj.statuBarText,obj.uploadGrid.store.getCount(),Ext.util.Format.fileSize(obj.uploadGrid.store.sum('size')));

                            if(obj.uploadGrid.store.getCount()==0){

                                   obj.uploadGrid.store.removeAll();

                                   obj.uploadAction[1].disable();

                                   obj.uploadAction[2].disable();

                                   obj.uploadAction[3].disable();

                            }

                     }}),

                     new Ext.Action({text:'清空',disabled:true,handler:function(){

                            var obj=Application.uploadDialog;

                            var store=obj.uploadGrid.store;

                            var len=store.getCount();

                            for(var i=0;i<len;i++){

                                   var rec=store.getAt(i);

                                   obj.swfu.cancelUpload(rec.data.id);

                            }

                            store.removeAll();

                            obj.classCombo.clearValue();

                            obj.stateInfo.getEl().innerHTML=String.format(obj.statuBarText,0,Ext.util.Format.fileSize(0));

                            obj.uploadProgressBar.updateProgress(0,'');

                            obj.uploadProgressBar.updateText("");

                            obj.uploadAction[0].enable();

                            obj.uploadAction[1].disable();

                            obj.uploadAction[2].disable();

                            obj.uploadAction[3].disable();

                     }}),

                     new Ext.Action({text:'上传',disabled:true,handler:function(){

                            var obj=Application.uploadDialog;

                            obj.uploadAction[0].disable();

                            obj.uploadAction[1].disable();

                            obj.uploadAction[2].disable();

                            obj.uploadAction[3].disable();

                            obj.uploadAction[4].disable();

                            var store=obj.uploadGrid.store;

                            var len=store.getCount();

                            var classid=obj.classCombo.getValue();

                            obj.swfu.setPostParams({'classid':classid});

                            obj.swfu.startUpload();

                     }}),

                     new Ext.Action({text:'关闭',handler:function(){

                            Application.uploadDialog.hide();

                     }}),

              ],

 

              initDialog:function(){

                     this.classCombo=new Ext.form.ComboBox({

                            hiddenName:'classid',name: 'classid_name',valueField:"id",displayField:"text",mode:'local',

                            store:this.classStore,blankText:'请选择类别',emptyText:'请选择类别',editable:true,anchor:'90%'

                     })

                    

                     this.swfu=new SWFUpload({

                            upload_url:"upload.asp",

             

                            file_size_limit : "102400",     

                            file_types : "*.jpg;*.gif",

                            file_types_description : "图片文件(*.jpg,*.gif)",

                            file_upload_limit : "30",

             

                            file_dialog_start_handler : this.fileDialogStart,

                            file_queued_handler : this.fileQueued,         

                            file_queue_error_handler : this.uploadError,

                            file_dialog_complete_handler : this.fileDialogComplete,

                            upload_start_handler : this.uploadFileStar,

                            upload_progress_handler : this.uploadProgress,

                            upload_error_handler : this.uploadError,

                            upload_complete_handler : this.uploadQueueComplete,

                            file_complete_handler : this.uploadFileComplete,

                                         

                            flash_url:"swfupload.swf",

             

                            ui_container_id : "SWFUploadTarget",

                            degraded_container_id : "divDegraded",

                            debug: false

                     })

                    

                     this.dialog=new Ext.Window({

             layout:'fit',width:600,height:500,title:'上传图片',closeAction:'hide',border:false,modal:true,

             plain:true,closable:false,resizable:false,

                            bbar:[this.uploadProgressBar=new Ext.ProgressBar({width:586})],

             items:[

                 Application.uploadDialog.uploadGrid=new Ext.grid.GridPanel({

                        autoExpandColumn:2,enableHdMenu:false,

                                          tbar:[Application.uploadDialog.uploadAction[0],Application.uploadDialog.uploadAction[1],Application.uploadDialog.uploadAction[2],

                                          '-',Application.uploadDialog.uploadAction[3],"-",Application.uploadDialog.classCombo,"->"

                                          ,Application.uploadDialog.uploadAction[4]],

                                          bbar:[Application.uploadDialog.stateInfo=new Ext.Toolbar.TextItem(String.format(Application.uploadDialog.statuBarText,0,Ext.util.Format.fileSize(0)))],

                           store: new Ext.data.SimpleStore({fields: ["id","state", "file","size","type"],data:[]}),

                           columns:[

                             new Ext.grid.RowNumberer(),

                             {id:'id',header: "id",hidden:true,width:150,dataIndex:'id',resizable:false,sortable:false},

                             {header: "文件名",width:Ext.grid.GridView.autoFill,dataIndex:'file',sortable:true},

                             {header: "大小", width: 80,renderer:Ext.util.Format.fileSize,dataIndex:'size',sortable:true,align:'right'},

                             {header: "类型", width: 80,dataIndex:'type',align:'center',sortable:true},

                             {header: "状态", width: 100,dataIndex:'state',align:'center',sortable:true}

                           ]

                                   })

                            ]

                     })

              },

 

              fileQueued:function(file){

                     var obj=Application.uploadDialog;

                     var filetype=(file.type.substr(1)).toUpperCase();

                     if(filetype=='JPG' | filetype=='GIF'){

                            var data=[];

                            data.push([file.id,'未上传',file.name,file.size,filetype]);

                            obj.uploadGrid.store.loadData(data,true);

                            obj.uploadAction[1].enable();

                            obj.uploadAction[2].enable();

                            obj.uploadAction[3].enable();

                            obj.stateInfo.getEl().innerHTML=String.format(obj.statuBarText,obj.uploadGrid.store.getCount(),Ext.util.Format.fileSize(obj.uploadGrid.store.sum('size')));

                     }

              },

                    

              uploadFileStar:function(file){

                     var obj=Application.uploadDialog;

                     var index=obj.findData(file.id);

                     if(index>=0){

                            obj.uploadGrid.store.getAt(index).set('state','正在上传……');

                     }

                     obj.uploadProgressBar.updateProgress(0,String.format(obj.progressBarText,file.name,0));

                     return true;

              },

      

                    

              uploadProgress:function(file,bytesloaded){

                     var obj=Application.uploadDialog

                     var percent = Math.ceil((bytesloaded / file.size) * 100);

                     obj.uploadProgressBar.updateProgress(percent/100,String.format(obj.progressBarText,file.name,percent));

              },

                    

              uploadFileComplete:function(file){

                     var obj=Application.uploadDialog;

                     var index=obj.findData(file.id);

                     if(index>=0){

                            obj.uploadGrid.store.getAt(index).set('state','已上传');

                     }

                     if(obj.swfu.getStats().files_queued>0)

                            obj.swfu.startUpload();

              },

                    

              uploadFileCancelled:function(file, queuelength){

              },

                    

              uploadQueueComplete:function(file,server_data){

                     console.log(server_data);

                     if(server_data=='ok'){

                            var obj=Application.uploadDialog;

                            obj.uploadProgressBar.updateProgress(1,'完成上传');              

                            obj.uploadAction[2].enable();

                            obj.uploadAction[4].enable();

                     }else{

                            alert(server_data);

                     }

              },

      

              uploadError:function(file,errcode,msg){

                     var index=Application.uploadDialog.findData(file.id);

                     if(index>=0)

                            Application.uploadDialog.uploadGrid.store.getAt(index).set('state','上传失败');

                     //alert(errcode+','+file.name+','+msg)

              },

                    

              uploadCancel:function(file, queuelength){

                     var index=Application.uploadDialog.findData(file.id);

                     if(index>=0)

                            Application.uploadDialog.uploadGrid.store.getAt(index).set('state','取消上传');

              },

             

              fileDialogStart:function(){

              },

             

              fileDialogComplete:function (num_files_queued){

              },

             

              findData:function(id){

                     var rowindex=Application.uploadDialog.uploadGrid.store.find('id',id);

                     return rowindex;

              }

 

       }//Application.uploadDialog

      

 

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

接着我定义了Application的子对象uploadDialogApplication.uploadDialog),改对象主要两个方法是showhide

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

 

<div id="SWFUploadTarget" style="height:0px;width:0px;disply:none;z-index:-1"></div>

<div id="divDegraded" style="height:0px;width:0px;disply:none;z-index:-2"></div>

 

这里要注意的就是ui_container_iddegraded_container_id 对象的divid不能错,呵呵。

flash_url对应的是swf文件的位置,改位置是相对于页面文件的位置,我为了方便,就放在同一目录,不然调这个挺烦的,老是因位置不对而出现错误。upload_url对应的是后台接收文件,其位置是相对于swf文件的位置,千万别搞错了。呵呵,还是放在同目录好,不用考虑路径。

因为我后台是用aspuoload组件的,所以不用考虑file_post_name属性,如果你是用php或其它后台语言,需要通过提交变量名获取文件数据则需要定义这个属性。例如php,定义file_post_nameFiledata,然后在后台通过“$_FILES["Filedata"]”提取数据。

在这个对话框里我限制了上传文件的大小最多是2Mfile_size_limit : "2048"),文件类型是jpggif文件(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里定义了增加、删除、清空、上传、关闭等5action,然后在表格的的顶部工具栏直接加入这些action就会自动变成按钮了:

 

       tbar:[Application.uploadDialog.uploadAction[0],Application.uploadDialog.uploadAction[1],Application.uploadDialog.uploadAction[2],

                                          '-',Application.uploadDialog.uploadAction[3],"-",Application.uploadDialog.classCombo,"->"

                                          ,Application.uploadDialog.uploadAction[4]],

 

感觉是不是有点脱裤子放屁,纯粹多此一举?呵呵。其实不是的,我这样做的主要原因是action可以预先定义,因为不用生成html元件,而且如果你想帮表格加入右键菜单的时候,你可以通过action同时控制toolbar上按钮和右键菜单上的动作,如disbaleenable,而不必分别做操作,而且还有用变量记录这些对象。 如果习惯delphi的开发,应该对action很熟悉了,非常好的一个功能。

在表格底部工具栏放置了一个TextItem,内容是一个格式化的文本“文件总数:{0} ,大小:{1}”。这个格式化文本的定义在文件头部(statuBarText:'文件总数:{0} ,大小:{1}')。通过Extstring对象将参数替换“{0}”、“{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)),通过storegetAt方法获取对应的记录。因我们在记录里已经保存了SWFUpload为每个队列文件生成的id,所以我们可以通过SWFUploadcancelUpload方法在队列中取消该文件的上传(cancelUpload (rec.data.id))。同时在store里删除该记录(store.remove(rec))。最后是更新一下状态行的统计信息和设置一下按钮的状态。

清空按钮主要作用就是清空表格信息和取消所以上传文件队列,操作方法和删除按钮类似。

上传按钮就是屏蔽各按钮,调用SWFUploadsetPostParams方法设置提交参数(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是否还要通过审核。例子在IIS6Firefox和装有Apsupload的机器上测试通过。后台程序的保存位置为Dtest目录,按源文件名保存,并将提交的参数写到了一个txt文件里。

分享到:
评论

相关推荐

    Ext2+SwfUpload(最新版)构建文件上传框

    通过这种方式,你可以利用`Ext2`的优雅UI和`SwfUpload`的先进上传功能,创建一个用户友好的文件上传框。在实际应用中,可能还需要考虑其他因素,如错误处理、多语言支持、文件预览等,以提供更加完善的用户体验。 ...

    Ext.net+swfupload实现文件上传

    Ext.net+swfupload实现上传组件。 特点: (1)适合嵌入到Ext.net项目中。 (2)避免了Ext.net的上传控件的缺点。Ext.net中上传控件在文件上传到服务器后在判断后缀、大小是否符合要求,这样在网速限制的情况下用户...

    Ext+swfupload实现多文件上传(java版)

    Ext+swfupload实现多文件上传(java版),是从MyEclipse工程中导出的war包,已通过测试,绝对能运行成功.

    jquery+SWFUpload+COS上传组件的使用

    jquery+SWFUpload+COS上传组件的使用 jquery+SWFUpload+COS上传组件的使用jquery+SWFUpload+COS上传组件的使用jquery+SWFUpload+COS上传组件的使用jquery+SWFUpload+COS上传组件的使用jquery+SWFUpload+COS上传组件...

    java+struts+swfupload文件上传下载

    2. **创建Struts Action**:在Struts框架中创建一个Action类,用于接收SwfUpload上传的文件。这个Action需要继承自Struts的抽象类,并覆盖上传方法。 3. **处理上传请求**:在Action的上传方法中,使用Java的IO流...

    JQ + swfupload 多文件上传

    3. **创建上传按钮**:SwfUpload通过隐藏原始的文件选择输入框并创建一个自定义的按钮来触发文件选择对话框。这个按钮可以自定义样式,以适应网页设计。 4. **处理上传事件**:当用户选择文件后,SwfUpload会调用...

    Struts+swfupload实现文件上传功能

    2. **创建Struts Action**:在Struts框架中,我们需要创建一个Action类来处理文件上传请求。这个Action需要实现文件接收和保存的功能。在Struts配置文件(struts.xml)中,为该Action定义一个对应的URL映射。 3. **...

    ext struts2 swfupload 跨域文件上传

    "ext struts2 swfupload 跨域文件上传"这个主题涉及到三个关键技术和概念:EXTJS(Ext JS)、Struts2以及SwfUpload,它们共同解决了Web应用中的跨域文件上传问题。 EXTJS是一种强大的JavaScript库,用于构建富...

    asp+SwfUpload图片文件上传源码亲测很好用

    SwfUpload则是一个流行的JavaScript和Flash组合的文件上传组件,它允许用户通过富互联网应用程序(RIA)界面进行多文件上传,且具有进度条显示等功能,提高了用户体验。 SwfUpload的工作原理是利用Flash插件在...

    strut2+swfupload+extjs4文件上传

    本示例解决了strut2+swfupload+extjs4文件上传过程中,后台struts接收不到上传文件的问题。而这个问题如果用servlet做后台可能就不存在。开发者可以用本例源码移植到自己项目中使用 。

    php + swfupload 实现批量上传图片实例

    在本文中,我们将深入探讨如何使用PHP和SWFUpload库实现一个批量图片上传的功能。SWFUpload是一个流行的JavaScript库,它允许用户通过Flash接口进行多文件上传,即使在不支持HTML5多文件上传功能的浏览器中也能工作...

    fckeditor+swfupload+图片本地化

    在fckeditor和swfupload的结合使用中,用户可以通过swfupload上传图片到服务器,然后在fckeditor中直接插入这些本地化的图片,实现编辑器内的一站式操作。 【文件列表详解】: 1. **fckconfig.js**:这是fckeditor...

    ThinkPHP+swfupload多图上传

    6. **数据库操作**:为了跟踪和管理这些上传的图片,通常会在数据库中创建一个记录,存储图片的路径、文件名、上传时间等信息。 7. **返回响应**:将处理结果(成功或失败)及可能的错误信息返回给前端,swfupload...

    thinkphp+swfupload上传多张图片

    在开发Web应用时,有时我们需要...总的来说,结合ThinkPHP和SwfUpload,你可以构建一个高效且用户体验良好的多张图片上传功能。但请务必考虑项目的长远需求,考虑使用更现代的上传方案,以保持应用的兼容性和安全性。

    extjs3.4+swfupload上传

    在IT行业中,Web开发经常会遇到文件上传的需求,而"extjs3.4+swfupload上传"就是一个典型的前端文件上传解决方案。EXT JS 3.4是一款强大的JavaScript框架,用于构建富客户端应用程序,提供了丰富的组件库和强大的...

    jquery+SWFUpload+COS上传组件的使用.doc

    SWFUpload是一个基于Flash的文件上传组件,它可以支持多文件上传,并且在用户界面上提供丰富的定制选项。COS(Cloud Object Storage)是腾讯云提供的云存储服务,能够安全、稳定地存储和分发大量数据。 **2. 使用...

    ecshop+swfupload实现批量上传图片

    总之,通过ECSHOP与SWFUpload的结合,你可以为用户提供一个高效、直观的批量图片上传体验。这个过程涉及到前端和后端的代码修改,需要对ECSHOP的结构和SWFUpload的工作原理有清晰的理解。希望这些信息能帮助你成功地...

Global site tag (gtag.js) - Google Analytics