Dorado 5 : 2.3.6.TabSet(标签页) (RF2)

简述

提供标签页功能,如下图:

图表 56

使用说明

利用X-insert在Jsp中添加TabSet模版代码:

<d:TabSet id="" currentTab="">
<d:Tab name="tab1" label="">
</d:Tab>
<d:Tab name="tab2" label="">
</d:Tab>
</d:TabSet>

将需要显示的页面组件拷贝到不同的<d:Tab>中:

<d:TabSet id="tabset1" height="100%">
<d:Tab name="tab1" label="组合框样式" padding="12">
<d:AutoForm id="formGroupBox" />
</d:Tab>
<d:Tab name="tab2" label="子窗体样式" padding="8">
<d:AutoForm id="formSubWindow" />
</d:Tab>
</d:TabSet>

TabSet使用时需要注意即使你已经在View中定义过TabSet对象,但是在JSP标签申明的时候还必须申明Tab标签,并且Tab标签的内部元素是无法在View中定义的,而必须在JSP中将其他的标签元素放置到不同的Tab标签内部。Tab标签之间不允许有其他的内容。
TabSet一般通过Tab标签对象将不同的组件分开管理。这种使用方式对于JSP技术来说是属于同一个页面的生命周期的。另外TabSet还支持FrameTab,用于将一个外部的jsp引入TabSet。使用方法就是在视图模型的TabSet的xml定义中添加FrameTab:

<Control id="tabset1" type="TabSet">
<Tab name="tab1" label="动态标签页" />
<FrameTab name="tab6" label="Google" path="http://www.google.com" />
<FrameTab name="tab7" label="Baidu" path="http://www.baidu.com" />
<FrameTab name="tab8" path="http://www.bstek.com" label="锐道网站" />
<FrameTab name="tab9" label="dorado控制台" path="/dorado/console.d" />
<Events />
</Control>

FrameTab使用时需要注意,我们只要在View中配置TabSet的FrameTab对象,而无需在JSP中添加FrameTab标签(实际上也没有提供该标签对象),这一点与Tab对象的使用方式有所不同。FrameTab的输出由TabSet管理,根据TabSet的位置自动生成。
如下的视图模型配置中xml代码配置:

<Control id="tabset1" type="TabSet" currentTab="tab6">
<Tab name="tab1" label="动态标签页" />
<Tab name="tab2" label="隐藏按钮的标签页" />
<Tab name="tab3" label="标签3" />
<Tab name="tab4" label="标签4" />
<Tab name="tab5" label="标签5" />
<FrameTab name="tab6" label="Google" path="http://www.google.com" />
<FrameTab name="tab7" label="Baidu" path="http://www.baidu.com" />
<FrameTab name="tab8" path="http://www.bstek.com" label="锐道网站" />
<FrameTab name="tab9" label="dorado控制台" path="/dorado/console.d" />
<Events />
</Control>

则在JSP的标签设定时,代码如下:

<d:TabSet id="tabset1">
<d:Tab name="tab1">
..
</d:Tab>
<d:Tab name="tab2">
..
</d:Tab>
<d:Tab name="tab3">
<div style="width: 100%; height: 100%; background-color: #FFDDFF"></div>
</d:Tab>
<d:Tab name="tab4">
<div style="width: 100%; height: 100%; background-color: #FFFFB3"></div>
</d:Tab>
<d:Tab name="tab5">
<div style="width: 100%; height: 100%; background-color: #CCFFFF"></div>
</d:Tab>
</d:TabSet>

运行效果如下图:

图表 57

TabSet属性说明

属性

说明

currentTab

TabSet对象激活时默认切换到指定Tab或FrameTab 上,如上图的Google标签页

showFrame

是否显示TabSet的边框线, 可选值为true/false

tabPlacement

TabSet的标签头所处的位置,目前支持的有两种:
top:标签头处于标签页的最上面
bottom: 标签头处于标签页的最下面

Tab属性说明

属性

说明

autoCreateDiv

是否自动创建Div,可选值为true/false

autoScroll

当页面元素较多无法在页面中完全展示时,是否自动出现滚动栏true/false

disabled

将Tab设置为禁止状态,设置为禁止状态的Tab页上所有的元素都变的不可操作, 可选值为true/false

label

Tab的标题

name

Tab的名字,按照java变量名的命名规则命名

padding

标签Div的padding属性

visible

用于隐藏Tab,可选值为true/false

FrameTab

属性

说明

cachable

是否允许缓存,可选值为true/false

disabled

是否禁止该FrameTab,被禁止的FrameTab上将无法操作,可选值为true/false

label

FrameTab的标题

name

FrameTab的名字,按照java变量名的命名规则命名

padding

标签Div的padding属性

path

引用页面的url

visible

用于隐藏FrameTab,可选值为true/false

使用技巧

技巧一:FrameTab的动态刷新

FrameTab对象用于关联一个独立URL,FrameTab的Client-API提供了setPath()方法动态的设定其关联的URL,并调用refresh方法刷新FrameTab。范例代码如下:

tabset1.setCurrentTab("tab5"); //将当前tab切换到指定的FrameTab对象上
var tab=tabset1.getCurrentTab();//获取当前激活的tab页对象
tab.setPath("http://www.javaeye.com");//利用setPath重新设定path属性
tab.refresh();//刷新FrameTab

技巧二:向导窗体制作

巧用Tab或FrameTab的visible属性,看如下的一个页面,

图表 58
页面功能是选择右侧不同的行,左侧激活不同的标签页。
JSP定义代码如下:

<d:TabSet id="tabset3">
<d:Tab name="tab1" >
<p style="margin: 20">
标签1中的文字
</p>
</d:Tab>
<d:Tab name="tab2" >
<p style="margin: 20">
标签2中的文字
</p>
</d:Tab>
<d:Tab name="tab3" >
<p style="margin: 20">
标签3中的文字
</p>
</d:Tab>
<d:Tab name="tab4" >
<p style="margin: 20">
标签4中的文字
</p>
</d:Tab>
<d:Tab name="tab5" >
<p style="margin: 20">
标签5中的文字
</p>
</d:Tab>
</d:TabSet>

上例在不同的Tab中加加了不同的文字说明,用以区分(本例主要说明开发技巧,因此Tab中的内容较为简单,实际运行可加入复杂的dorado标签对象或JSP支持的各种代码)。
在该例右侧使用了表格,其功能为选择不同的表格行,左侧TabSet激活不同的Tab对象(利用DataTable的onRecordClick事件,可参考DataTable的使用说明),当然这儿也可以将右侧表格替换为按钮。我们可以在不同按钮的onClick事件中,指定标签页的切换,标签页切换功能是由TabSet的setCurrentTab方法提供,范例代码如下:

tabset1.setCurrentTab("tab4");

如果我们将上面的画面的Tab或FrameTab的visible属性全部设置为false。最终的代码如下:
JSP定义代码如下:

<d:TabSet id="tabset3">
<d:Tab name="tab1" visible="false">
<p style="margin: 20">
标签1中的文字
</p>
</d:Tab>
<d:Tab name="tab2" visible="false">
<p style="margin: 20">
标签2中的文字
</p>
</d:Tab>
<d:Tab name="tab3" visible="false">
<p style="margin: 20">
标签3中的文字
</p>
</d:Tab>
<d:Tab name="tab4" visible="false">
<p style="margin: 20">
标签4中的文字
</p>
</d:Tab>
<d:Tab name="tab5" visible="false">
<p style="margin: 20">
标签5中的文字
</p>
</d:Tab>
</d:TabSet>

则运行效果图:

图表 59
选择表格中的不同行(如果使用按钮实现就是单击不同的按钮对象),例如选择标签4,则可以得到如下的效果:

图表 60
该开发技巧在很多ERP系统中被用来制作向导类型的页面开发,例如ODBC配置中的向导界面:

图表 61
其中包含上一步,下一步的向导操作。很显然使用TabSet的这种技术实现会大大优于传统的WEB开发技术。

技巧三:复杂维护界面的界面布局管理

技巧二的另一种应用,可以参考Doradosample中的产品维护范例:
http://www.bstek.com/dorado5/training/ui/product-tree.jsp
注意该页面上选择产品分类维护分类信息以及选择产品维护产品信息的时候都在同一个区域使用AutoForm修改和保存信息,并且两个AutoForm是完全不一样的。
该范例中的产品分类信息维护以及产品信息维护的所有页面元素都是在一个jsp页面上制作的,而不是通过Iframe等技术复合而成。其中就充分利用的Tab的Visible属性。实现方式简要说明如下:

功能描述

该页面的功能是对树的节点做维护,其中选择产品分类,右侧要显示产品分类信息的formCategory输入界面:

图表 62
而选择树中的具体产品时,希望可以在右侧实现产品详细信息的录入:显示formProduct

图表 63

设定Tab的Visible属性

TabSet的定义如下(每一个tab都设定了visible为false,表示隐藏标签按钮):

<d:TabSet id="tabsetDetail" showFrame="false">
<d:Tab name="category" visible="false">
..//显示产品分类信息的AutoFrom:formCategory
</d:Tab>
<d:Tab name="product" visible="false">
..//显示产品详细信息的AutoFrom:formProduct
</d:Tab>
</d:TabSet>

定义树节点的afterCurrentChange事件

DataTree的定义如下

图表 64
注意其中treeProduct的TreeLevel,包含了category,product两种类型。则我们就可以在tree的afterCurrentChange事件中通过TreeLevel的名称区分当前节点是category还是product。
afterCurrentChange事件是Tree中聚焦节点发生变化的时候触发。我们利用这个事件来动态的决定界面右侧应该出现哪个AutoForm来显示产品分类信息或产品信息。关于afterCurrentChange事件的详细说明参考Tree的使用详解。
在树节点的afterCurrentChange事件(当用户选中节点发生变化时触发)中,添加代码:

图表 65
以上代码通过判断afterCurrentChange事件中的node.getTreeLevel().getName()方法获得当前节点的TreeLevel信息。并根据该信息决定调用tabsetDetail对象的setCurrentTab方法设定TabSet对象当前需要激活的Tab。

TabSet常用事件

TabSet常用的事件是,控制和管理Tab或FrameTab的切换事件,其它详细的事件以及方法说明参考client-api中的内容。以下说明主要的事件和方法:

beforeTabChange

public String beforeTabChange(TabElement tab, TabSet tabset)

在当前标签被切换之前被触发
说明:如果您返回了一个异常,那么系统将显示此异常信息并终止后续默认的操作.
如果您返回null或者没有定义任何返回值,那么系统将继续执行后续默认的操作.
如果您希望终止后续默认的操作但又不希望显示任何异常信息,那么请返回一个AbortException对象.
Parameters
tab - TabElement - 要切换到的标签项
tabset - TabSet - 触发事件的多页控件对象
Returns:
String

afterTabChange

Public String afterTabChange(TabSet tabset, TabElement tab)

在当前标签被切换之后被触发
Parameters
tabset - TabSet - 触发事件的多页控件对象
tab - TabElement - 切换前的标签项
Returns:
String

getCurrentTab

public TabElement getCurrentTab()

获取当前激活的标签对象
Returns:
TabElement

setCurrentTab

public TabElement setCurrentTab(String/int name/index)

设置当前标签项并返回新的当前标签项
Parameters
name/index - String/int - 标签项的名字或序号

此处的序号是指从0开始的序号
Returns:
TabElement

实现范例

在标签页切换之前,先判断当前页面的记录状态,根据状态决定是否允许标签页切换。
程序范例:

function beforeTabChange(tabset, newTab, oldTab){
//如果记录处于编辑状态,则不允许标签切换
if (oldTab.getName()=="tab1" && datasetEmployee.getState() == "modify"){
return new DoradoException("请先保存当前员工信息!");
}
}

系统css文件

.TabSet {
table-layout: fixed;
}

.TabSet .Tab_top {
cursor: hand;
}

.TabSet .DisabledTab_top {
cursor: hand;
color: gray;
}

.TabSet .CurrentTab_top {
padding-top: 4;
cursor: hand;
}

.TabSetContentContainer_top {
background-color: white;
border-width: 1;
border-color: #AAAAAA;
border-left-style: solid;
border-right-style: solid;
border-top-style: none;
border-bottom-style: solid;
}

.TabSet .Tab_bottom {
cursor: hand;
}

.TabSet .DisabledTab_bottom {
cursor: hand;
color: gray;
}

.TabSet .CurrentTab_bottom {
padding-bottom: 4;
cursor: hand;
}

.TabSetContentContainer_bottom {
background-color: white;
border-width: 1;
border-color: #AAAAAA;
border-left-style: solid;
border-right-style: solid;
border-top-style: solid;
border-bottom-style: none;
}

.TabSetTabDiv {
padding: 2;
}