对 Ext 扩展的一些小总结
1、multicombo (多选下拉框)
Ext.onReady(function(){ Ext.BLANK_IMAGE_URL = '../../resources/images/default/s.gif'; var formPanel = new Ext.FormPanel({ height : 100,// 表单面板的高度 width : 400,// 表单面板的宽度 labelWidth : 120,// 字段标签宽度 labelAlign : "right",// 字段标签对齐方式 fileUpload: true,//支持文件上传 defaults : {// 默认form元素类型为textfield xtype : "textfield",// 默认类型为textfield width : 150 // 默认宽度 }, items : [{ xtype:'multicombo', id : 'multicombo' , width:250, store: new Ext.data.SimpleStore({ fields: ["name","value"], data:[['测试菜单1',1],['测试菜单2',2],['测试菜单3',3],['测试菜单4',4]]}), valueField :"value", displayField: "name", labelSeparator:':', displaySeparator:';', valueSeparator:',', mode: 'local', value:'1,2', forceSelection: true, hiddenName:'test', editable: true, triggerAction: 'all', allowBlank:false, emptyText:'请选择', fieldLabel: '多选下拉ComBo' }], buttons : [{ text : '提交', type : 'submit', handler : function() { Ext.Msg.alert('提交',Ext.getCmp('multicombo').getRawValue()); } }] }); formPanel.render("multicombo-div"); });
如图:
源码包见附件:multiCombox.rar 解压后,multiCombox\examples\form 目录下打开MultiComboBox.html,可见效果。
2、combotree(下拉树)
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Customizing ComboBoxTree</title> <link rel="stylesheet" type="text/css" href="<%=request.getContextPath() %>/ext-2.3.0/resources/css/ext-all.css" /> <script src="<%=request.getContextPath() %>/ext-2.3.0/adapter/ext/ext-base.js"></script> <script src="<%=request.getContextPath() %>/ext-2.3.0/ext-all.js"></script> <script src="<%=request.getContextPath() %>/js/ComboBoxTree.js"></script> <script type="text/javascript"> var comboBoxTree; Ext.BLANK_IMAGE_URL = 'ext-2.3.0/resources/images/default/s.gif'; Ext.onReady(function(){ comboBoxTree = new Ext.ux.ComboBoxTree({ renderTo : 'comboBoxTree', width : 250, tree : { xtype:'treepanel', bbar: ['名称:',{xtype:'trigger',id: 'searchName',width:200,triggerClass:'x-form-search-trigger',onTriggerClick:search}], loader: new Ext.tree.TreeLoader({dataUrl:'getNodes.jsp'}), root : new Ext.tree.AsyncTreeNode({id:'0',text:'根结点'}) }, //all:所有结点都可选中 //exceptRoot:除根结点,其它结点都可选(默认) //folder:只有目录(非叶子和非根结点)可选 //leaf:只有叶子结点可选 selectNodeModel:'leaf' }); }); function showValue(){ alert("显示值="+comboBoxTree.getRawValue()+" 真实值="+comboBoxTree.getValue()); } function search(){ var searchName = Ext.getDom('searchName').value; alert("查询字符串:"+searchName); } </script> </head> <body> <table> <tr> <td> </td> <td> <div id="comboBoxTree"></div> </td> <td> <input type='button' value='值' onclick='showValue()'> </td> </tr> </table> </body> </html>
getNodes.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" %> <% String id = request.getParameter("node"); String listNode = "["; if(id.length()<5){ for(int i=1;i<6;i++){ listNode += "{id:'"+i+"_"+id+"',text:'folder"+i+"_"+id+"'},"; } listNode = listNode.substring(0,listNode.length()-1) + "]"; }else{ for(int i=1;i<6;i++){ listNode += "{id:'"+i+"_"+id+"',text:'node"+i+"_"+id+"',leaf:true},"; } listNode = listNode.substring(0,listNode.length()-1) + "]";; } out.print(listNode); %>
效果图:
3、级联 combo 的实现
Ext.BLANK_IMAGE_URL = '../../lib/ext-2.1/resources/images/default/s.gif'; var store = null; var comboBox = null; var store1 = null; var comboBox1 = null; function CreatComboBox() { if (store1 == null) { store1 = new Ext.data.JsonStore( { url : 'com_getData.action?source=Province&keycolumnname=ID&valuecolumnname=PName', //totalProperty:"totalPorperty",root:"result", fields : [ 'key', 'value' ] }); store1.load(); comboBox1 = new Ext.form.ComboBox({ fieldLabel : '省级行政单位', id : 'province', store : store1, emptyText : "请选择", mode : 'local', typeAhead : true, triggerAction : 'all', valueField : 'key', displayField : 'value', selectOnFocus : true, width : 240, border : true, frame : true }); } if (store == null) { comboBox1 .on( 'select', function(combox) { //source的名称要和pojo的名称一致 var url = "com_getDateByPkpage.action?source=City&keycolumnname=ID&valuecolumnname=CityName&FKname=Pid&FKValue=" + combox.value store.proxy = new Ext.data.HttpProxy({ url : url }); store.load({ params : { start : 0, limit : 6 },//传入后台的分页数据 callback : function(r) { if (r.length >= 1) { var key = r[0].get('value'); comboBox.setValue(key); } } }); }); store = new Ext.data.JsonStore({ totalProperty : "totalporperty", root : "result",//后台返回的分页后的数据 fields : [ 'key', 'value' ] }); comboBox = new Ext.form.ComboBox({ id : "city", store : store, fieldLabel : '市级行政单位', emptyText : '请选择', mode : 'remote',//指定数据加载方式,如果直接从客户端加载则为local,如果从服务器断加载则为remote.默认值为:remote typeAhead : true, triggerAction : 'all', valueField : 'key', displayField : 'value', selectOnFocus : true, minListWidth : 220,//设置下拉列表的宽度,如果不指定分页工具栏可能会显示不全 width : 240, border : true, frame : true, resizable : true, pageSize : 6 //当元素加载的时候,如果返回的数据为多页,则会在下拉列表框下面显示一个分页工具栏,该属性指定每页的大小 //在点击分页导航按钮时,将会作为start及limit参数传递给服务端,默认值为0,只有在mode='remote'的时候才能够使用 }); } } Ext.onReady(function() { Ext.QuickTips.init(); CreatComboBox(); var form = new Ext.form.FormPanel({ title : '级联', labelWidth : 80, width : 400, frame : true, items : [ comboBox1, comboBox ] }); form.render("form"); });
效果图:
4、可编辑的树表 EditTreeGrid :
附件 TreeGridEditor v1.4.0-rc1.rar 已经上传。
5、可编辑的树表 EditGridTree 的另一个扩展
附件 edittreegrid-1.3.rar 已上传。
6、数据表格 ExplorerView
var grid, grid2; Ext.onReady(function(){ Ext.QuickTips.init(); var reader = new Ext.data.ArrayReader({}, [ {name: 'name'}, {name: 'modified', type: 'date', dateFormat: 'Y-m-d H:i'}, {name: 'type'}, {name: 'size'}, {name: 'icon'} ]); var largeIcons = new Ext.Template( '<div class="x-grid3-row ux-explorerview-item ux-explorerview-large-item" unselectable="on">'+ '<table class="ux-explorerview-icon" cellpadding="0" cellspacing="0">'+ '<tr><td align="center"><img src="images/large-{icon}"></td></tr></table>'+ '<div class="ux-explorerview-text"><div class="x-grid3-cell x-grid3-td-name" unselectable="on">{name}</div></div></div>' ); var mediumIcons = new Ext.Template( '<div class="x-grid3-row ux-explorerview-item ux-explorerview-medium-item">'+ '<table class="ux-explorerview-icon" cellpadding="0" cellspacing="0">'+ '<tr><td align="center"><img src="images/medium-{icon}"></td></tr></table>'+ '<div class="ux-explorerview-text"><div class="x-grid3-cell x-grid3-td-name" unselectable="on">{name}</div></div></div>' ); var smallIcons = new Ext.Template( '<div class="x-grid3-row ux-explorerview-item ux-explorerview-small-item">'+ '<div class="ux-explorerview-icon"><img src="images/small-{icon}"></div>'+ '<div class="ux-explorerview-text"><div class="x-grid3-cell x-grid3-td-name" unselectable="on">{name}</div></div></div>' ); var tileIcons = new Ext.Template( '<div class="x-grid3-row ux-explorerview-item ux-explorerview-tiles-item">'+ '<div class="ux-explorerview-icon"><img src="images/medium-{icon}"></div>'+ '<div class="ux-explorerview-text"><div class="x-grid3-cell x-grid3-td-name" unselectable="on">{name}<br/><span>{type}</span></div></div></div>' ); function changeView(item, checked) { var tpl; if (checked) { if (item.text == 'Large Icons') tpl = largeIcons; else if (item.text == 'Medium Icons') tpl = mediumIcons; else if (item.text == 'Small Icons') tpl = smallIcons; else if (item.text == 'Tiles') tpl = tileIcons; else tpl = null; grid.getView().changeTemplate(tpl); grid2.getView().changeTemplate(tpl); } } grid = new Ext.grid.GridPanel({ store: new Ext.data.GroupingStore({ reader: reader, data: Ext.grid.dummyData, sortInfo: {field: 'modified', direction: 'DESC'}, groupField: 'type' }), columns: [ {header: 'Name', sortable: true, dataIndex: 'name'}, {header: 'Modified', width: 40, sortable: true, renderer: Ext.util.Format.dateRenderer('Y-m-d H:i'), dataIndex: 'modified'}, {header: 'Type', width: 40, sortable: true, dataIndex: 'type'}, {header: 'Size', width: 40, sortable: true, dataIndex: 'size', align: 'right', renderer: Ext.util.Format.fileSize} ], view: new Ext.ux.grid.GroupingExplorerView({ rowTemplate: largeIcons, forceFit:true, groupTextTpl: '{text} ({[values.rs.length]})' }), tbar: new Ext.Toolbar({ items: [{ text: 'Views', menu: [{ group: 'view', checkHandler: changeView, checked: false, text: 'Extra Large Icons', iconCls: 'view-xl-icons', disabled: true }, { group: 'view', checkHandler: changeView, checked: true, text: 'Large Icons', iconCls: 'view-l-icons' }, { group: 'view', checkHandler: changeView, checked: false, text: 'Medium Icons', iconCls: 'view-m-icons' },{ group: 'view', checkHandler: changeView, checked: false, text: 'Small Icons', iconCls: 'view-s-icons' }, '-', { group: 'view', checkHandler: changeView, checked: false, text: 'List', iconCls: 'view-list', disabled: true }, '-', { group: 'view', checkHandler: changeView, checked: false, text: 'Details', iconCls: 'view-details' }, '-', { group: 'view', checkHandler: changeView, checked: false, text: 'Tiles', iconCls: 'view-tiles' }] }] }), enableDragDrop: true, frame:true, width: 700, height: 450, collapsible: true, animCollapse: false, title: 'ExplorerView Example with Grouping', iconCls: 'icon-grid', renderTo: document.body }); grid2 = new Ext.grid.GridPanel({ store: new Ext.data.Store({ reader: reader, data: Ext.grid.dummyData, sortInfo: {field: 'modified', direction: 'DESC'} }), columns: [ {id: 'name', header: 'Name', sortable: true, dataIndex: 'name'}, {header: 'Modified', width: 120, sortable: true, renderer: Ext.util.Format.dateRenderer('Y-m-d H:i'), dataIndex: 'modified'}, {header: 'Type', width: 120, sortable: true, dataIndex: 'type'}, {header: 'Size', width: 120, sortable: true, dataIndex: 'size', align: 'right', renderer: Ext.util.Format.fileSize} ], viewConfig: { rowTemplate: tileIcons }, enableDragDrop: true, autoExpandColumn: 'name', frame: true, width: 700, height: 450, collapsible: true, animCollapse: false, title: 'ExplorerView Example without Grouping', iconCls: 'icon-grid', renderTo: document.body }); }); Ext.grid.dummyData = [ ['Program Files', '2008-01-01 00:00', 'File Folder', 0, 'folder.png'], ['Program Files (x86)', '2008-01-01 00:03', 'File Folder', 0, 'folder.png'], ['ProgramData', '2008-02-06 13:21', 'File Folder', 0, 'folder.png'], ['temp', '2007-12-05 00:59', 'File Folder', 0, 'folder.png'], ['Users', '2008-05-01 18:08', 'File Folder', 0, 'folder.png'], ['Windows', '2008-01-01 04:57', 'File Folder', 0, 'folder.png'], ['install.exe', '2008-08-17 03:42', 'Application', 561671, 'application.png'], ['globdata.ini', '2008-10-01 16:01', 'Configuration Settings', 3214, 'application-settings.png'], ['VC_RED.MSI', '2008-10-09 07:31', 'Application', 9498742, 'application-installer.png'], ['VC_RED.cab', '2008-10-09 07:31', 'WinRAR Archive', 65789416, 'winrar-archive.png'] ];
可以实现试图间的变换,如图:
附件 explorerview.rar 已经上传。
7、可以实现过滤的树 TreeFilter
Ext.onReady(function(){ var myTree = new Ext.tree.TreePanel({ renderTo:'mytree', rootVisible:false, width:200, height:400, autoScroll:true, tbar:new Ext.Toolbar(), root:new Ext.tree.AsyncTreeNode({ children: [{ id: 'level', text: '用户类型', children: [{ id: 'allLevel', text: '全部', leaf: true }, { id: 'noSupport', text: '无支持', leaf: true }, { id: 'month', text: '包月', leaf: true }, { id: 'year', text: '包年', leaf: true }, { id: 'always', text: '终身', leaf: true }] }, { id: 'outOfDate', text: '是否过期', children: [{ id: 'allOutOfDate', text: '全部', leaf: true }, { id: 'notOutOfDate', text: '未过期', leaf: true }, { id: 'alreadyOutOfDate', text: '已过期', leaf: true }] }, { id: 'report', text: '统计图表', children: [{ id: 'levelReport', text: '按用户类型', leaf: true }, { id: 'outOfDateReport', text: '按是否过期', leaf: true }] }] }) }); var filterFiled = new Ext.form.TextField({ width:150, emptyText:'快速检索', enableKeyEvents: true, listeners:{ render: function(f){ this.myFilter = new QM.ux.TreeFilter(myTree,{ clearAction : 'expand' });//初始化TreeFilter }, keyup: {//添加键盘点击监听 fn:function(field,e){ field.myFilter.filter(field.getValue()); }, buffer: 450 } } }); myTree.expandAll(); var tbar = myTree.getTopToolbar(); tbar.add(filterFiled); tbar.doLayout(); });
效果图:
8、ECOTree 如图:
9、密码强度的现实 PasswordMeter 如图:
10、图片字段 imagefield : 如图:
JS 代码:
Ext.onReady(function(){ Ext.BLANK_IMAGE_URL = 'ext-2.3.0/resources/images/default/s.gif'; Ext.QuickTips.init(); var store = new Ext.data.JsonStore({ url: 'image.json', root: 'images', fields: [ 'name', 'url', {name:'size', type: 'float'}, {name:'lastmod', type:'date', dateFormat:'timestamp'} ] }); // create the template to use with the DataView var tpl = new Ext.XTemplate( '<tpl for=".">', '<div class="thumb-wrap" id="{name}">', '<div class="thumb"><img src="{url}" alt="{shortName}" title="{name}" /></div>', '</div>', '</tpl>' ); // create the DataView var imageView = new Ext.DataView({ store: store, tpl: tpl, autoHeight:true, autoWidth: true, overClass:'x-view-over', itemSelector:'div.thumb-wrap', emptyText: 'No images to display', loadingText: 'Loading...', singleSelect: true }); // create the test form var form = new Ext.form.FormPanel({ xtype:'form', title:'Ext.ux.form.ImageField', frame:true, labelWidth:70, width:240, //height:300, buttonAlign: 'right', id:'form', url:'form_dump.php', defaults : { width : 150, labelSeparator: '' }, items:[{ xtype: 'textfield', id:'user', fieldLabel:'Username', allowBlank: false },{ xtype: 'textfield', id:'pass', fieldLabel:'Password', allowBlank: false }, new Ext.ux.form.ImageField({ fieldLabel : 'Avatar', name: 'avatar', msgTarget: 'title', view: imageView, browserWidth: 275, windowConfig: { cls: 'images-view' }, id: 'avatarimage', defaultImage: 'image/blank.png' }) ], buttons:[{ text:'submit', handler: function(){ form.getForm().submit(); } }] }); form.render('form-ct'); });
附件: imagefield.rar
11、分组的下拉框 groupcombo 如图:
12、cellActions 表格中添加图标按钮 如图:
附件 :cellActions.rar
13、 带图标的下拉框 IconCombo 如图
Ext.namespace('Ext.ux.plugins'); /** * Ext.ux.plugins.IconCombo plugin for Ext.form.Combobox * @author Ing. Jozef Sakalos * @date January 7, 2008 * @class Ext.ux.plugins.IconCombo * @extends Ext.util.Observable */ Ext.ux.plugins.IconCombo = function(config) { Ext.apply(this, config); }; // plugin code Ext.extend(Ext.ux.plugins.IconCombo, Ext.util.Observable, { init:function(combo) { Ext.apply(combo, { tpl: '<tpl for=".">' + '<div class="x-combo-list-item ux-icon-combo-item ' + '{' + combo.iconClsField + '}">' + '{' + combo.displayField + '}' + '</div></tpl>', onRender:combo.onRender.createSequence(function(ct, position) { // adjust styles this.wrap.applyStyles({position:'relative'}); this.el.addClass('ux-icon-combo-input'); // add div for icon this.icon = Ext.DomHelper.append(this.el.up('div.x-form-field-wrap'), { tag: 'div', style:'position:absolute' }); }), // end of function onRender setIconCls:function() { var rec = this.store.query(this.valueField, this.getValue()).itemAt(0); if(rec) { this.icon.className = 'ux-icon-combo-icon ' + rec.get(this.iconClsField); } }, // end of function setIconCls setValue:combo.setValue.createSequence(function(value) { this.setIconCls(); }) }); } // end of function init }); // end of extend
附件:IconCombo.rar
14 、下拉树多选 ComboBoxCheckTree :如图
15、实现Tree的叶子节点的跳动:
源码:
<%@ page language="java" pageEncoding="UTF-8"%> <html> <head> <title>Jump Tree</title> <link rel="stylesheet" type="text/css" href="<%=request.getContextPath()+request.getSession().getAttribute("theme")%>/ext/resources/css/ext-all.css" /> <script type="text/javascript" src="${pageContext.request.contextPath}/js/ext/adapter/ext/ext-base.js"></script> <script type="text/javascript" src="${pageContext.request.contextPath}/js/ext/ext-all.js"></script> <script type="text/javascript" src="${pageContext.request.contextPath}/js/ext/ext-lang-zh_CN.js"></script> <script type="text/javascript"> //叶子节点跳动 function jumpIcon(id, duration){ var node = Ext.getCmp('userTree').getNodeById(id); node.attributes['jump']='true' ; if(node){ if(isNaN(duration))duration = 800; var iconEl = node.ui.getIconEl(); var textEl = node.ui.getTextEl(); var handler = window.setInterval(function(){ if(node.attributes.jump == 'true'){//是否跳动的标志 iconEl.style.marginLeft = "5px"; textEl.style.marginLeft = "3px"; } window.setTimeout(function(){ iconEl.style.marginLeft = ""; textEl.style.marginLeft = ""; if(node.attributes.jump != 'true'){return;} },duration/2); }, duration); } }; Ext.onReady(function(){ Ext.BLANK_IMAGE_URL = '${pageContext.request.contextPath}/js/ext/resources/images/default/s.gif'; var tree = new Ext.tree.TreePanel({ id: 'userTree' , renderTo: 'tree-div', useArrows: true, autoScroll: true, animate: true, enableDD: true, containerScroll: true, border: false, loader: new Ext.tree.TreeLoader(), root: new Ext.tree.AsyncTreeNode({ expanded: true, text : 'Root' , children: [{ text: 'User 1', leaf: true , id : 'aaa' }, { text: 'User 2', leaf: true , id : 'bbb' }, { text: 'User 3', leaf: true , id : 'ccc' }] }), listeners : { 'dblclick' : function(node,e){ node.attributes['jump']='false' ; Ext.Msg.alert("提示",node.text+" 停止跳动"); }, 'click' : function(node,e){ jumpIcon(node.id,600); } } }); tree.getRootNode().expand(); }); </script> </head> <body> <div id="tree-div"></div> </body> </html>
效果图就不上传了,上传静态图片看不出来效果。