ExtJs中,除了border布局可以很好地做出成熟的界面,《【ExtJs】利用树状结构、Border布局与标签页刻划OA界面》(点击打开链接),常用的标签页布局《【ExtJs】tabPanel标签页与修改标签页的内容》(点击打开链接)以外。在ExtJs中我觉得最好的主布局还有折叠式布局与卡片式布局,而使组件一列排列vbox布局,与使组件一行排列hbox布局,我觉得还可以出出子布局,也就是主布局里面的东西,而那些什么表格布局,我觉得真没有什么用了,还不如直接放一个table标签或者div标签上去不用这么繁琐。
一、基本目标
下面用两个小例子,还说明个人认为ExtJs的重要的主布局,折叠式布局与卡片式布局。
首先是折叠式布局。如下图,能自动调整、自动移位的。
然后是卡片式布局,如下图,做了一个小小的计算器说明问题,这正如VC6中的《【mfc】利用单一对话框内的分页技术实现向导功能》(点击打开链接)一样也可以用来分页之类的,不解释了。
二、制作过程
1、首先是简单的HTML布局,除了引入ExtJs4资源,还有两个Button之外,再也没有了。ExtJs真的可以纯粹用JavaScript完成
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Ext折叠、卡片</title> <script type="text/javascript" src="js/ext-all.js"></script> <script type="text/javascript" src="js/bootstrap.js"></script> <script type="text/javascript" src="js/ext-lang-zh_CN.js"></script> <link href="ext-theme-classic/ext-theme-classic-all.css" rel="stylesheet" type="text/css"> </head> <body> <button id="btn1" type="button">打开折叠框</button> <button id="btn2" type="button">打开卡片框</button> </body> </html>
2、首先是折叠框部分,折叠框的功能较少,因此代码也较短。折叠框使用窗口呈现,这不同于ExtJs中不可以移动、不可以调整的容器《【ExtJs】带日期组件的文本输入框、容器与Ext.Msg.alert告警框告警两次》(点击打开链接),但要注意ExtJs声明完窗口之后,绑定btn1这个在HTML中已经声明的按钮,使用show()方法显示。你需要多少个折叠页就在items中声明。折叠页还可以使用xtype或者html直接布局。
//声明一个折叠框 var window1 = Ext.create('Ext.window.Window', { layout: 'accordion', width: 260, height: 300, title: '折叠框', resiziable: true,//表示可以自由调整折叠框的大小 titleCollapse: true, //表示点击标题折叠 renderTo: Ext.getBody(), items: [{ title: '标题1', hideCollapseTool: true, html: '内容1' }, { title: '标题2', hideCollapseTool: true,//表示隐藏所含Panel的展开/收缩工具按钮 html: '内容2' }, { title: '标题3', hideCollapseTool: true, html: '内容3' }] }); Ext.get("btn1").on("click", function(){ window1.show()//窗口默认不显示; });
3、之后是卡片框。功能有点多,代码比较长,但是主要集中在最后一页的各个button的监听事件。其实这些监听事件都是相同,一段拿走第0页与第1页的输入框的内容,检测是否是数之后,再相加。这个代码在《【JavaScript】对数的判断与对数的处理》(点击打开链接)写过了。不赘述了。
//这里是卡片布局中“上一步”、“下一步”两个按钮的必要设置 var navigate = function(panel, direction){ var layout = panel.getLayout(); layout[direction](); Ext.getCmp('move-prev').setDisabled(!layout.getPrev()); Ext.getCmp('move-next').setDisabled(!layout.getNext()); }; var window2 = Ext.create('Ext.window.Window', { title: '卡片布局', width: 300, height: 200, layout: 'card', bodyStyle: 'padding:15px',//设置内容上下左右冗余15px bbar: [{ id: 'move-prev', text: '上一步', handler: function(btn){ navigate(btn.up("panel"), "prev"); }, disabled: true }, { xtype: 'tbfill' }, // 占位符,使上一步按钮、下一步按钮分居两侧 { id: 'move-next', text: '下一步', handler: function(btn){ navigate(btn.up("panel"), "next"); } }], // 布局下的各子面板 // 第0页与第1页都是使用hbox,组件一行排列的布局声明好id,为最后1页,也就是第2页的按钮所操作。 items: [{ id: 'card-0', layout:'hbox', items:[{ xtype:'label', text:'第一个数:' }, { xtype:'textfield', //与<input type="text" id="num1" />没有任何区别 id:'num1' }] }, { id: 'card-1', layout:'hbox', items:[{ xtype:'label', text:'第二个数:' }, { xtype:'textfield', id:'num2' }] }, { id: 'card-2', layout:'hbox', items:[{ xtype:'button', text:'求和', listeners: {//此乃按钮被点击的事件,与<button onclick="">求和</button>没有任何区别 click: function(){ var num1=Ext.getCmp("num1").getValue(); var num2=Ext.getCmp("num2").getValue(); var result; if(isNaN(num1)||isNaN(num2)||!num1||!num2) result="任意一个不是数!" else{ result="两数相加的结果是:"+(parseFloat(num1)+parseFloat(num2)); } Ext.Msg.alert("两数之和",result); } } },{ xtype: 'button', text: '求差', listeners: { click: function(){ var num1 = Ext.getCmp("num1").getValue(); var num2 = Ext.getCmp("num2").getValue(); var result; if (isNaN(num1) || isNaN(num2) || !num1 || !num2) result = "任意一个不是数!" else { result = "两数相减的结果是:" + (parseFloat(num1) - parseFloat(num2)); } Ext.Msg.alert("两数之差", result); } } },{ xtype: 'button', text: '求积', listeners: { click: function(){ var num1 = Ext.getCmp("num1").getValue(); var num2 = Ext.getCmp("num2").getValue(); var result; if (isNaN(num1) || isNaN(num2) || !num1 || !num2) result = "任意一个不是数!" else { result = "两数相乘的结果是:" + (parseFloat(num1) * parseFloat(num2)); } Ext.Msg.alert("两数之积", result); } } },{ xtype: 'button', text: '求商', listeners: { click: function(){ var num1 = Ext.getCmp("num1").getValue(); var num2 = Ext.getCmp("num2").getValue(); var result; if (isNaN(num1) || isNaN(num2) || !num1 || !num2) result = "任意一个不是数!" else { result = "两数相除的结果是:" + (parseFloat(num1) / parseFloat(num2)); } Ext.Msg.alert("两数之商", result); } } } ] }], renderTo: Ext.getBody() }); Ext.get("btn2").on("click", function(){ window2.show()//窗口默认不显示; });
三、总结
因此,整个网页的代码如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Ext折叠、卡片</title> <script type="text/javascript" src="js/ext-all.js"></script> <script type="text/javascript" src="js/bootstrap.js"></script> <script type="text/javascript" src="js/ext-lang-zh_CN.js"></script> <link href="ext-theme-classic/ext-theme-classic-all.css" rel="stylesheet" type="text/css"> </head> <body> <button id="btn1" type="button">打开折叠框</button> <button id="btn2" type="button">打开卡片框</button> </body> </html> <script> Ext.onReady(function(){ //声明一个折叠框 var window1 = Ext.create('Ext.window.Window', { layout: 'accordion', width: 260, height: 300, title: '折叠框', resiziable: true,//表示可以自由调整折叠框的大小 titleCollapse: true, //表示点击标题折叠 renderTo: Ext.getBody(), items: [{ title: '标题1', hideCollapseTool: true, html: '内容1' }, { title: '标题2', hideCollapseTool: true,//表示隐藏所含Panel的展开/收缩工具按钮 html: '内容2' }, { title: '标题3', hideCollapseTool: true, html: '内容3' }] }); Ext.get("btn1").on("click", function(){ window1.show()//窗口默认不显示; }); //这里是卡片布局中“上一步”、“下一步”两个按钮的必要设置 var navigate = function(panel, direction){ var layout = panel.getLayout(); layout[direction](); Ext.getCmp('move-prev').setDisabled(!layout.getPrev()); Ext.getCmp('move-next').setDisabled(!layout.getNext()); }; var window2 = Ext.create('Ext.window.Window', { title: '卡片布局', width: 300, height: 200, layout: 'card', bodyStyle: 'padding:15px',//设置内容上下左右冗余15px bbar: [{ id: 'move-prev', text: '上一步', handler: function(btn){ navigate(btn.up("panel"), "prev"); }, disabled: true }, { xtype: 'tbfill' }, // 占位符,使上一步按钮、下一步按钮分居两侧 { id: 'move-next', text: '下一步', handler: function(btn){ navigate(btn.up("panel"), "next"); } }], // 布局下的各子面板 // 第0页与第1页都是使用hbox,组件一行排列的布局声明好id,为最后1页,也就是第2页的按钮所操作。 items: [{ id: 'card-0', layout:'hbox', items:[{ xtype:'label', text:'第一个数:' }, { xtype:'textfield', //与<input type="text" id="num1" />没有任何区别 id:'num1' }] }, { id: 'card-1', layout:'hbox', items:[{ xtype:'label', text:'第二个数:' }, { xtype:'textfield', id:'num2' }] }, { id: 'card-2', layout:'hbox', items:[{ xtype:'button', text:'求和', listeners: {//此乃按钮被点击的事件,与<button onclick="">求和</button>没有任何区别 click: function(){ var num1=Ext.getCmp("num1").getValue(); var num2=Ext.getCmp("num2").getValue(); var result; if(isNaN(num1)||isNaN(num2)||!num1||!num2) result="任意一个不是数!" else{ result="两数相加的结果是:"+(parseFloat(num1)+parseFloat(num2)); } Ext.Msg.alert("两数之和",result); } } },{ xtype: 'button', text: '求差', listeners: { click: function(){ var num1 = Ext.getCmp("num1").getValue(); var num2 = Ext.getCmp("num2").getValue(); var result; if (isNaN(num1) || isNaN(num2) || !num1 || !num2) result = "任意一个不是数!" else { result = "两数相减的结果是:" + (parseFloat(num1) - parseFloat(num2)); } Ext.Msg.alert("两数之差", result); } } },{ xtype: 'button', text: '求积', listeners: { click: function(){ var num1 = Ext.getCmp("num1").getValue(); var num2 = Ext.getCmp("num2").getValue(); var result; if (isNaN(num1) || isNaN(num2) || !num1 || !num2) result = "任意一个不是数!" else { result = "两数相乘的结果是:" + (parseFloat(num1) * parseFloat(num2)); } Ext.Msg.alert("两数之积", result); } } },{ xtype: 'button', text: '求商', listeners: { click: function(){ var num1 = Ext.getCmp("num1").getValue(); var num2 = Ext.getCmp("num2").getValue(); var result; if (isNaN(num1) || isNaN(num2) || !num1 || !num2) result = "任意一个不是数!" else { result = "两数相除的结果是:" + (parseFloat(num1) / parseFloat(num2)); } Ext.Msg.alert("两数之商", result); } } } ] }], renderTo: Ext.getBody() }); Ext.get("btn2").on("click", function(){ window2.show()//窗口默认不显示; }); }) </script>