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 οnclick="">求和</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 οnclick="">求和</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>