很久没有用过ExtJS,正好一个新的在线系统需要搭建一个运营平台,没有交互,没有页面设计,没有原型,我那点可怜的美感只能借助Extjs来搭建了。
1.通用的架子典型的Border布局+tree菜单+TabPanel的内容区的框架,模块清晰简单,菜单可配置。
Ext.BLANK_IMAGE_URL="ext/resources/images/default/s.gif"; Ext.QuickTips.init(); /*菜单面板*/ MenuPanel=function(config){ config=config||{}; var config_=Ext.applyIf({ layout:'accordion', region:'west', split:true, width:200, collapsible:true, border:false, animate: true },config); MenuPanel.superclass.constructor.call(this,config_); }; Ext.extend(MenuPanel,Ext.Panel,{}); /*菜单模块面板*/ ModulePanel=function(config){ config=config||{}; var nodes_loader=new Ext.tree.TreeLoader({dataUrl:config.dataUrl}); ModulePanel.superclass.constructor.call(this,{ animate: true, title:config.title, rootVisible:false, iconCls:'tab_icon', region:'west', split:true, width:200, collapsible:true, root:{ }, loader:nodes_loader }); }; Ext.extend(ModulePanel,Ext.tree.TreePanel,{ setTargetOpen:function(contentPanel){ this.on("click",function(node){ if(!node.attributes.leaf){ return true; } var tabid="module_tab_"+node.attributes.id; var exist_panel=contentPanel.getComponent(tabid); if(exist_panel){ contentPanel.setActiveTab(exist_panel); }else{ var iframe_in_tab="iframe_"+tabid; var iframe_html="<iframe width=100% height=100% id='"+iframe_in_tab+"'/>" var panel=new Ext.Panel({ title:node.attributes.text, id:tabid, closable:true, iconCls:'tab_icon_2', html:iframe_html }); contentPanel.add(panel); contentPanel.setActiveTab(panel); Ext.get(iframe_in_tab).set({ src:node.attributes.url }); } }); } }); /*主面板*/ MainPanel=function(){ MainPanel.superclass.constructor.call(this,{ region:'center', margins:'0 5 5 0', resizeTabs: true, minTabWidth: 135, tabWidth: 135, enableTabScroll: true, activeTab: 0, items:[{ title:'公告面板', closable:true, html:'管理平台欢迎您,如有问题,请联系coreycui,timwen,liubangchen' }], tbar:new Ext.Toolbar({ items:[ {xtype:'displayfield',value:'内容页面导航: ',style:'color:RED'}, {xtype:'button',iconCls:'prev_icon',tooltip:'后退',handler:function(){ var activePanel=this.findParentByType("toolbar",false).ownerCt.getActiveTab(); var activePanelId=activePanel.getItemId(); var iframe_in_tab=Ext.get("iframe_"+activePanelId); Ext.getDom("iframe_"+activePanelId).contentWindow.history.back(); }}, {xtype:'button',iconCls:'next_icon',tooltip:'前进',handler:function(){ var activePanel=this.findParentByType("toolbar",false).ownerCt.getActiveTab(); var activePanelId=activePanel.getItemId(); var iframe_in_tab=Ext.get("iframe_"+activePanelId); Ext.getDom("iframe_"+activePanelId).contentWindow.history.forward(); }}, {xtype:'button',iconCls:'refresh_icon',tooltip:'刷新',handler:function(){ var activePanel=this.findParentByType("toolbar",false).ownerCt.getActiveTab(); var activePanelId=activePanel.getItemId(); var iframe_in_tab=Ext.get("iframe_"+activePanelId); Ext.getDom("iframe_"+activePanelId).contentWindow.document.location.reload(); }} ] }) }); } Ext.extend(MainPanel,Ext.TabPanel,{}); Ext.onReady(function(){ var contentPanel=new MainPanel(); var menu_panel=new ModulePanel({ title:'功能导航', dataUrl:'menu_node.jsp' }); menu_panel.setTargetOpen(contentPanel); var viewport=new Ext.Viewport({ layout:'border', items:[ {region:'north',border:false,contentEl:'header',split:true}, menu_panel, contentPanel ] }); });
[ { text:'直通车',children:[ {text:'a1',leaf:true,url:'http://com/g/s?aid=index&g_ut=1',id:'a1'}, {text:'a2',leaf:true,url:'http://com/g/s?aid=index&g_ut=2',id:'a2'}, {text:'a3',leaf:true,url:'http://.com',id:'a3'}, {text:'a4',leaf:true,url:'http://com',id:'a4'}, {text:'a5',leaf:true,url:'http://0',id:'a5'}, {text:'a6',leaf:true,url:'http://a1p',id:'a6'} ] }, { text:'XX管理',children:[ {text:'XX查询',leaf:true,url:'<%=request.getContextPath()%>/xxmanage/querycp.jsp',id:'xx_query'}, {text:'XX审核',leaf:true,url:'<%=request.getContextPath()%>/xxmanage/querycp4manage.jsp',id:'xx_manage'} ] } ]
MenuPanel=function(config){ config=config||{}; var config_=Ext.applyIf({ layout:'accordion', region:'west', split:true, width:200, collapsible:true, border:false, animate: true },config); MenuPanel.superclass.constructor.call(this,config_); }; Ext.extend(MenuPanel,Ext.Panel,{});
MenuPanel.superclass.constructor.call(this,config_);
var config_=Ext.applyIf();主要用来指定一些固定的初始化option
var columnModel=new Ext.grid.ColumnModel([ {header:'日期',dataIndex:'stat_date'} /*............*/ ]); var grid=new Ext.grid.GridPanel({ cm:columnModel, store:store, renderTo:'grid', autoHeight:true, viewConfig:{ forceFit:true }, loadMask:{ msg:'不要着急,休息一下,休息一下 :)..' }, bbar:new Ext.PagingToolbar({ pageSize:10, store:store, stripeRows:true, displayInfo:true, displayMsg:'显示第{0}条到第{1}条,一共{2}条', emptyMsg:'无记录' }) }); var form=new Ext.form.FormPanel({ renderTo:'data_setting_div', labelAlign:'right', labelWidth:60, items:[ { xtype: 'compositefield', fieldLabel: '日期范围', defaults:{ width:150 }, items:[ {xtype:'datefield',id:'startdate',name:'startdate'}, {xtype:'displayfield',value:'--',width:10}, {xtype:'datefield',name:'enddate',id:'enddate'}, {xtype:'button',text:'查询',listeners:{ click:function(){ startDate=form.getForm().findField("startdate").getValue().format('Y-m-d') endDate=form.getForm().findField("enddate").getValue().format('Y-m-d'); store.reload(); } }} ] } ] }); store.load({params:{start:0, limit:10,fromButton:'refresh'}});
viewConfig:{ forceFit:true }
store.load({params:{start:0, limit:10,fromButton:'refresh'}});
{xtype:'button',text:'查询',listeners:{ click:function(){ startDate=form.getForm().findField("startdate").getValue().format('Y-m-d') endDate=form.getForm().findField("enddate").getValue().format('Y-m-d'); store.reload(); } }}还必须添加以下事件:
var store=new Ext.data.Store({ proxy:new Ext.data.HttpProxy({ url:gridDataUrl }), reader:new Ext.data.JsonReader({ totalProperty: 'totalCount', root:'list' },[ {name:'stat_date'} /*{}*/ ]), listeners:{ beforeload:function(thiz,options){ Ext.apply ( thiz.lastOptions.params, { startDate : startDate, endDate : endDate } ); } } });
thiz.lastOptions.params代表最后提交的参数。
new Ext.form.HtmlEditor({ fieldLabel:'正文', id:'news_details', name:'news_details', plugins:new FileInsertPlugin({url:FileUpload.url,MVC_BUS:'FileManager',MVC_ACTION:'upload'}) }),
FileInsertPlugin:
/*coreycui*/ FileInsertPlugin = function(config) { config=config||{}; var editor; var win; /*创建图片*/ var createImage = function() { var imageWidth = win.getImageWidth(); var imageHeight = win.getImageHeight(); var element = document.createElement("img"); element.src = win.getImageSrc(); element.alt = win.getImageAlt(); if (imageWidth == null || imageWidth == '') { } else { element.style.width = imageWidth + "px" } if (imageHeight == null || imageHeight == '') { } else { element.style.height = imageHeight + "px" } return element; } // 把图片插入editor中 var insertImageByBrowser = function() { if (Ext.isIE) { return function() { var selection = editor.doc.selection; var range = selection.createRange(); range.pasteHTML(createImage().outerHTML); }; } else { return function() { var selection = editor.win.getSelection(); if (!selection.isCollapsed) { selection.deleteFromDocument(); } selection.getRangeAt(0).insertNode(createImage()); }; } }(); /*插入图片*/ var insertImage = function() { editor.win.focus(); insertImageByBrowser(); editor.updateToolbar(); editor.deferFocus(); }; /*图片成功回调*/ var whenImgUploadSuccess=function(result){ insertImage(); win.close(); }; /*图片失败回调*/ var whenImgUploadFailure=function(result){ Msg.MessageBox.alert("图片上传失败",result.msg); win.close(); } /*打开图片上传窗口*/ var openImageWindow = function() { win=new FileUploadWindow(config); win.setSuccessCallback(whenImgUploadSuccess); win.setFailureCallback(whenImgUploadFailure); win.show(this); } var onRender=function(){ editor.tb.add({ itemId : 'image', cls : 'x-btn-icon x-edit-image', handler : openImageWindow, tooltip : { title : '图片', text : '插入图片', cls : 'x-html-editor-tip' } }); } return { init : function(htmlEditor) { editor = htmlEditor; editor.on('render',onRender); } } }
init : function(htmlEditor) { editor = htmlEditor; editor.on('render',onRender); }主要是将生成的HTML代码插入在编辑器中:
var selection = editor.doc.selection; var range = selection.createRange(); range.pasteHTML(createImage().outerHTML);
/*文件上传窗口*/ FileUploadWindow=function(config){ config=config||{}; /*成功的回调函数*/ var successCallback; var failureCallback; var fileUrl; var fileUploadForm=new Ext.form.FormPanel({ fileUpload:true, url:config.url, labelAlign:'right', labelWidth:60, defaults:{ anchor:'-20' }, items:[ {fieldLabel:'本地文件',xtype:'textfield',name:'file',id:'file',inputType:'file'}, {fieldLabel:'文件描述',xtype:'textfield',name:'filedesc',id:'filedesc',width:190}, {fieldLabel:'高度',xtype:'textfield',name:'fileheight',id:'fileheight',width:190}, {fieldLabel:'宽度',xtype:'textfield',name:'filewidth',id:'filewidth',width:190} ], buttons:[ {text:'提交',handler:function(){ fileUploadForm.getForm().submit({ params:config, failure:function(form,action){ if(failureCallback){ failureCallback(action.result); } }, success:function(form,action){ fileUrl=action.result.fileUrl; if(successCallback){ successCallback(action.result); } } }); }} ] }); Ext.apply(config,{ width:325, title:'图片插入', autoHeight:true, items:[fileUploadForm] }); FileUploadWindow.superclass.constructor.call(this,config); /*获取表单*/ this.getForm=function(){ return fileUploadForm; } /*获取基础表单*/ this.getBasicForm=function(){ return fileUploadForm.getForm(); } /*设置成功回调函数*/ this.setSuccessCallback=function(callbackfn){ successCallback=callbackfn; } /*设置失败回调函数*/ this.setFailureCallback=function(callbackfn){ failureCallback=callbackfn; } this.getImageSrc=function(){ return fileUrl; } this.getImageAlt=function(){ return this.getBasicForm().findField('filedesc').getValue(); } this.getImageWidth=function(){ return this.getBasicForm().findField('filewidth').getValue(); } this.getImageHeight=function(){ return this.getBasicForm().findField('fileheight').getValue(); } } Ext.extend(FileUploadWindow,Ext.Window,{});
tbar:new Ext.Toolbar({ items:[ {xtype:'button',text:'新增新闻',iconCls:'add',handler:function(thiz,option){ var newsForm=new NewsForm(mvcUrl); var newsAddWin=new AddOrEditWindow({autoScroll:true,width:800,height:500,title:'新增新闻',mvcUrl:mvcUrl},newsForm) newsAddWin.show(); newsAddWin.setParams({ MVC_BUS:'News', MVC_ACTION:'add' }); newsAddWin.setSuccessCallback(function(){ store.reload(); }); }}, {xtype:'button',text:'编辑新闻',iconCls:'icon_window',handler:function(thiz,option){ var selections=sm.getSelections(); if(selections.length!=1){ Ext.example.msg("警告","请选择一条记录!"); }else{ var id=selections[0].get("id"); var newsForm=new NewsForm(mvcUrl); var newsAddWin=new AddOrEditWindow({autoScroll:true,width:800,height:500,title:'编辑新闻',mvcUrl:mvcUrl},newsForm) newsAddWin.show(); newsAddWin.initFormData(config.getDataUrl,{id:id}); newsAddWin.setParams({ MVC_BUS:'News', MVC_ACTION:'edit' }); newsAddWin.setSuccessCallback(function(){ store.reload(); }); } }} ] })
var newsAddWin=new AddOrEditWindow({autoScroll:true,width:800,height:500,title:'编辑新闻',mvcUrl:mvcUrl},newsForm)
this.setFields=function(obj){ this.getForm().findField("news_title").setValue(obj.result.summary.news_title); this.getForm().findField("summary").setValue(obj.result.summary.summary); this.getForm().findField("status_combo").setValue(obj.result.summary.status); this.getForm().findField("news_order").setValue(obj.result.summary.news_order); editor.setSource(obj.result.details.news_details); if(obj.result.types){ for(var i=0;i<obj.result.types.length;i++){ var typeCheckboxId="news_type_"+obj.result.types[i]; var checkBoxType=Ext.getCmp(typeCheckboxId); checkBoxType.setValue(true); } } }调用
newsAddWin.initFormData(config.getDataUrl,{id:id});系统会从第一个参数URL中用第二个param map去远程服务器获取一个obj数据对象。调用form的setFields进行填充,并且将id属性关联在该修改表单上。
AddOrEditWindow = function(config, form) { config = config || {}; var thiz = this; var params = {}; var successCallback; var failureCallback; var formPanel = form; var sumitForm = function() { formPanel.getForm().submit({ params : params, success : function(form, action) { Ext.example.msg("提示", "操作成功"); if (successCallback) { successCallback(); } thiz.close(); }, failure : function(form, action) { Ext.example.msg("提示", "操作失败"); if (failureCallback) { failureCallback(); } thiz.close(); } }); } Ext.apply(config, { iconCls : 'icon_window', items : [ formPanel ], buttons : [ { xtype : 'button', text : '提交', iconCls : 'save', handler : function() { sumitForm(); } }, { xtype : 'button', text : '关闭', iconCls : 'delete', handler : function() { thiz.close(); } } ] }); AddOrEditWindow.superclass.constructor.call(this, config); this.setParams = function(ps) { Ext.apply(params, ps); } this.initFormData = function(url, ps) { Ext.Ajax.request({ url : url, params : ps, success : function(resp, options) { var respText = Ext.util.JSON.decode(resp.responseText); params.id = respText.result.id; formPanel.setFields(respText); }, failure : function(resp, options) { thiz.close(); } }); } this.setSuccessCallback = function(fn) { successCallback = fn; } this.setFailureCallback = function(fn) { failureCallback = fn; } }; Ext.extend(AddOrEditWindow, Ext.Window, {});
{xtype:'actioncolumn',width:70,items:[{ icon: '../ext/selfimg/picture_delete.png', tooltip:'删除封面', handler:function(grid, rowIndex, colIndex){ var rec = store.getAt(rowIndex); var id=rec.get("id"); Ext.MessageBox.confirm("删除确认","确认是否删除?",function(btn){ } }); } }]}
actioncolumn
<script type="text/javascript" src="../ext/jquery-1.4.2.min.js"></script> <script type="text/javascript" src="../ext/ext-jquery-adapter.js"></script> <script type="text/javascript" src="../ext/xheditor-1.1.9-zh-cn.min.js"></script> <script type="text/javascript" src="../ext/ext-all.js"></script> <script type="text/javascript" src="../ext/ext-lang-zh_CN.js"></script>
如使用jquery的插件XKEditor编辑器。
{xtype:'textarea',fieldLabel:'正文',id:'news_details_proxy',name:'news_details_proxy',height:400,anchor: '-20'}
editor=$('#news_details_proxy').xheditor({html5Upload:false,upLinkUrl:fileUploadUrl,upLinkExt:"zip,rar,txt",upImgUrl:fileUploadUrl,upImgExt:"jpg,jpeg,gif,png",upFlashUrl:fileUploadUrl,upFlashExt:"swf",upMediaUrl:fileUploadUrl,upMediaExt:"avi"});
var renderNewsTypes=function(){ Ext.Ajax.request({ url : '<%=request.getContextPath()%>/mvc?MVC_BUS=NewsTypes&MVC_ACTION=list', success : function(resp, options) { var respText = Ext.util.JSON.decode(resp.responseText); var types=respText.list; typesInited=true; for(var i=0;i<types.length;i++){ typesCheckBoxes.push({xtype:'checkbox',boxLabel:types[i].type_name,inputValue:types[i].id,name:'news_type_'+types[i].id,id:'news_type_'+types[i].id}); } thiz.get(0).insert(1,{fieldLabel:'新闻类型',xtype:"checkboxgroup",columns: 4,items:typesCheckBoxes,name:'news_type_group',id:'news_type_group'}); thiz.get(0).remove(thiz.get(0).findById("news_types_proxy")); thiz.doLayout(); },failure:function(){ Ext.MessageBox.alert("警告","新闻内容拉取失败"); } }); }
thiz.doLayout(); editor=$('#news_details_proxy').xheditor({html5Upload:false,upLinkUrl:fileUploadUrl,upLinkExt:"zip,rar,txt",upImgUrl:fileUploadUrl,upImgExt:"jpg,jpeg,gif,png",upFlashUrl:fileUploadUrl,upFlashExt:"swf",upMediaUrl:fileUploadUrl,upMediaExt:"avi"});