5.按钮控件
1.按钮简介
<Input type="button" ...>即为按钮控件,Freeform支持的按钮种类比较多,可以有如下几种:
1.平坦按钮,即无凸出边界的按钮,语法为<Input type="button" style="flat" ...>;
2.平坦全透明按钮,和平坦按钮类似,但鼠标滑过时是透明的,语法为<Input type="button" style="flat,transparent" ...>;
3.带图标的按钮,按钮中可以有一个小图标,语法为<Input type="button" icon="../res/btn.zip#33.bmp" ...>,只要该icon指向有效的url, 就是带图标按钮;
4.下拉菜单按钮,和<Menus>下某Menu关联, 其外观如下图,语法为<Input type="button" menuID="menu1" ...>;
下拉菜单按钮可以是平坦按钮,也可以是非平坦按钮,只要定义了menuID,就是下拉菜单按钮。
5.动态下拉菜单按钮,和下拉菜单按钮类似,但是其弹出的菜单是需要js动态生成或修改的,语法为<Input type="button" menuID="menu1" isDynamicMenu="true" ...>;
6.普通按钮,无平坦效果、无背景色定义、无图标、无下拉菜单的按钮就是普通按钮,普通按钮的外观由操作系统决定;
按钮按下时会触发ButtonClicked事件,对于下拉菜单按钮,当鼠标选中弹出菜单的某个菜单项,则触发MenuClicked事件。
2.动态下拉菜单按钮
下拉菜单按钮的弹出菜单是和XML描述文件中内置的<Menus>资源相关联的,但是在很多情况下,弹出什么样的下拉菜单并非事先能预知,而是需要在菜单弹出前的瞬间,收集某些状态,然后再来动态修改、或生成具体的下拉菜单。在这种情况下,必须采用动态下拉菜单按钮。
属性 isDynamicMenu 为 true 就表示是动态下拉菜单按钮, 动态下拉菜单按钮的原理分析如下:
1.当用户点击该按钮时,并不弹出菜单,而是触发MenuBeforePopup页面事件;
2.页面js须考虑修改或生成菜单,可以调用如下函数:
SetMenu() - 动态生成菜单
SetMenuItemProp() - 修改菜单项
DeleteMenuItem() - 删除菜单项
3.js最后必须调用PopupMenu( )函数,表示菜单可以弹出:
在Demo页中有具体的实例可供参考.
6.RadioButton控件
RadioButton即单选框按钮,单选框按钮必须是分组的,在每一组单选框中,各个按钮之间相互排斥,例如下面就有2组独立的单选框:
XML描述文件中假设为如下:
//第一组
<input GroupID="by" id="by1" selectValue="air" type="radiobutton" text="空运" value="1"/>
<input GroupID="by" id="by2" selectValue="sea" type="radiobutton" text="水运" />
//第二组
<input GroupID="db" id="db1" selectValue="lon" type="radiobutton" text="银行贷款" />
<input GroupID="db" id="db2" selectValue="pay" type="radiobutton" text="货款付乞" />
可见这2组单选框的GroupID分别为"by"、"db". 此外,每个RadioButton通常还需要定义"SelectValue"属性,表示真实的值,这样调用 GetChangedXML( ) 函数取得XML串时,结果为:
<form level="0">
<row>
<by>air</by> //"by" 是第一组的GroupID
<db>lon</db> //"db" 是第二组的GroupID
...
</row>
</form>
如果调用Load( )加载XML数据,同样也应该采用类似格式。
7.文件上传控件
<Input type="upload" ...>即为文件上传控件,该控件能让用户选择本地文件并上传到服务器。
文件上传有Ftp、Http二种可选途经,以下将简述二者实现原理:
1.通过Ftp上传
通过Ftp上传是最简单的实现方式,程序员不必开发服务端程序,只要部署Ftp服务器就行。在客户端的页面中,只要调用方法FtpUpload( )就能轻松完成。
2.通过Http上传
通过Http上传有三种方法:
2.1.通过Http Put直接上传
和Ftp类似,程序员也不必开发服务端程序,只要开放目标目录的写入权限即可,通过函数httpUpload()上传。
备注: 应该指定有写入权限的帐号和密码,因为权限完全开放的虚拟目录是十分不安全的。
2.2.通过Http Post发送请求
Upload控件将本地文件通过POST方式Request给服务器,服务器端需要程序员开发服务响应程序。
备注: Http Header中的Content-Type是application/octet-stream,Http Body是文件的二进制内容。
2.3.间接上传
所谓间接上传,即Upload控件只是取得文件的Base64大串,并返回给页面,由页面来处理如何发送。如果文件比较小,可以简单地以GET方式发送Base64串。
8.内嵌Freeform树
<FreeformTree dataURL="?">是内嵌的Freeform树,组件是根据加载dataURL的数据创建树的,数据格式为XML/JSON,规范如下:
1.数据本身为普通的平面、多记录结果集;
2.每条记录须有唯一的id号;
3.每条记录允许有pid(或parantID),指向父节点的id,以确定父子从属关系;
4.如果pid为空、或pid所指的记录不存在,则作为顶级节点;
5.每条记录必须有"freeform"属性,指向一个URL,表示以该Freeform 的XML文档创建嵌入的Freeform,该URL如果是相对URL,则是相对于本数据的URL的;
6.记录中必须以和嵌入的Feeform的Object的id同名的属性,为嵌入的Freeform对象赋值;
数据举例如下:
<root>
<!-- landname、countryname、imgname是嵌入的freeform中的对象id,为其赋值 -->
<record pid="" id="01" freeform="treeland.xml" landname="欧洲"/>
<record pid="01" id="0101" freeform="reecountry.xml" countryname="英国" imgname="uk"/>
</root>
上例中, id、pid(或parentID)、freeform这3个属性是必需的,是系统保留词;其余的是数据,用于嵌入的freeform.
此外,FreeformTree对象支持鼠标单击、双击事件.
嵌入的Freeform不支持Menus、Upload、Pager、ImageFlow类型的Object;
嵌入的Freeform不支持输入功能.;
9.事件
Supcan FreeForm的OnEvent( id, Event, p1, p2, p3, p4 )事件含义及参数分别如下:
事件的js用法可参见“事件、按钮、菜单、工具条”Demo页。
备注1:EditKeydown和EditChar均为在输入框中的键盘事件,EditKeydown能捕获几乎所有键盘动作,包括非字符的回车、Tab等;而EditChar则以输入的字符为主,包括中文.
您可以用全局函数 CancelEvent( ) 去阻止继续执行,就如事件没有发生过那样,但不同的ASCII码,您需要在这二个事件中挑选一个执行CancelEvent( ),具体请在树列表的演示页“12.事件”中去测试;
备注2:1-Ctrl键也按下了; 2-Shift键也按下了; 3-二者一起按下了.
备注3:如果是分块上传,是类似这样的串:"FileParts=33;CurrentFilePart=2;PassTime=00:02:33;RemainTime=00:01:30;Speed=50",其含义如下:
FileParts - 总块数;
CurrentFilePart - 刚上传的块序号;
PassTime - 已耗用的时间(时:分:秒);
RemainTime - 估计还需要时间(时:分:秒);
Speed - 测算到的网速,单位为 千字节/秒;
此外,如果是将一个目录压缩成zip包上传,那么第一个Upload消息肯定是“Compressed=true”.
备注4:类似这样的串:"FileSize=1002034;CurrentSize=200030;PassTime=00:02:33;RemainTime=00:01:30;Speed=50",其含义如下:
FileSize - 文件总长度(字节);
CurrentSize - 已下载的长度(字节);
PassTime - 已耗用的时间(时:分:秒);
RemainTime - 估计还需要时间(时:分:秒);
Speed - 测算到的网速,单位为 千字节/秒;
10.XML提交格式规范
和Treelist类似,通过调用函数GetChangedXML( ),能取得输入内容的XML包,使得应用服务器能作相应处理,函数中参数level为提交级别,分如下3种:
级别0:生成当前全部、最新内容(不包括修改前的原始内容);
级别1:仅生成被修改过的Input的内容(包括原始内容);
级别2:生成全部Input的内容(包括原始内容);
级别0最常用,并且XML规范最简单,如下所示:
<?xml version="1.0" encoding="UTF-8"?">
<!-- id在XML描述文件中定义 -->
<form level="0" id="?" key="?" 自定义属性="?" >
<row>
<!-- id处为input真实的id,Text为输入的内容 -->
<id>Text</id>
...
</row>
</form>
级别1、2的内容规定如下:
<?xml version="1.0" encoding="UTF-8"?">
<!-- id 在XML描述文件中定义 -->
<form level="?" id="?" key="?" 自定义属性="?" >
<!-- 通过Load( )加载的是<modifiedRow>、否则就是<newRow> -->
<modifiedRow、newRow>
<row key="?">
<!-- id处为input的id, origin为原始值(被修改前),isModified仅用于级别2, Text为修改后的值 -->
<id origin="?" isModified="false">Text</id>
...
</row>
</modifiedRow、newRow>
</form>
警告:应用服务器端开发的程序不应过于依赖级别1/2中的origin的内容(被修改前),因为需要考虑并发.