综合使用JavaScript、LotusScript Agent和Formula的技巧
一 概述
在使用 Designer开发B/S模式的应用时,JavaScript、LotusScript和Formula是我们主要用到的三种开发语言。它们在各自的位置都有着很强劲的优势。
1. JavaScript因为只能取得浏览器端的数据,不能访问Notes DOM;所以,主要用在浏览器端的数据验证、信息提示等对当前
Brows窗口操作易的用性功能。
2. LotusScript能访问Notes DOM。在Notes客户端可以取得当前文档的数据,但是,因为其无法直接在浏览器端工作;所以在B/S模式的应用中LotusScript只能在服务器端工作,我们通过编写LotusScript代理来实现其强大的文档处理能力。
3. Formula能访问后台数据,语言简洁,数据处理能力较弱,不能在浏览器端工作。Formula主要使用在元素的显示控制以及域值的计算公式及简单的数据处理方面。
这三者使用的范围和处理能力各不相同。在应用中将其三者综合起来使用,会使应用的各方面功能大大增强。
二 由JavaScript向代理(LS\FL)通信
一般情况下JavaScript向代理的通信,使用url command。即如下格式:http://Host/Database/AgentName?OpenAgent&参数。这类操作可以用来解决数据查询、文档删除等任务。这类操作的特点是可以带参数,但是取不到浏览器端的当前文档,无法对浏览器端的文档进行处理。
那么,为什么要使用JavaScript向代理通信,并让代理取得浏览器端的当前文档呢?先看一个例子:
在某申请系统中,用户创建新申请可以这样做:打开新的申请单,填写各项目后,点击操作按钮“提交申请”,就完成了操作。对设计者而言触发“提交”操作必定运行一个代理或一段公式(此处我们先假定提交操作运行的是代理,后面将介绍提交操作运行公式的情况)。在真正运行代理的“提交”之前,系统一定要进行数据合法性的验证。最简单的做法是在每个域里面写入验证公式,或者在代理里写入验证数据合法性的代码。但是,这类做法的共同的缺点是:即使数据不合法,服务器端和浏览器端也发生了交互,占用带宽、影响网络速度。并且,出错提示信息只能以网页形式输出在原窗口上。这样,就会使原窗口中的信息丢失,不方便用户修改原来的数据。
针对这种情况,我们想让域的验证工作在浏览器端执行。并且,出错提示使用弹出窗口。JavaScript正能符合要求,但是难点就在:一旦验证通过怎样调用代理?
解决的办法是:
1. 保持“提交申请”操作按钮和提交代理不变。在浏览器端预览表单,点击右键查看源文件,找出“提交申请”操作按钮的onclick事件中的代码。
2. 新建一个同样名为“提交申请”操作按钮,将原来的“提交申请”操作按钮隐藏。在新建的操作按钮中写入域验证信息JavaScript代码,如果验证通过则执行第一步的代码。如果不通过则使用alert弹出窗口,提示出错信息。
3. 注意:每增减一次操作按钮,都会影响原“提交申请”操作按钮的onclick事件代码。所以,比较好的办法是将原来的“提交申请”操作按钮作成共享操作。
以上做法是我们在工作流模版里使用的方法。现在,我们有一种改进方法:
1。不用原来的操作按钮,把触发提交代理的写在一个按钮(button)里,给该按钮命名(假设为“b1”,在其属性框中找到html选项卡“name”栏中填为“b1”),用css将该按钮隐藏。(同样在tml选项卡中,在“style”栏填入“visibility: hidden”)
2。新建一个名为“提交申请”的操作按钮,在按钮中写入域验证信息JavaScript代码,如果验证通过则执行“ document.forms[0].b1.onclick()”(此处的b1是上一步我们假设的按钮name)。如果不通过则使用alert弹出窗口,提示出错信息。
3。注意如果有多个这种操作在同一个表单里,那么按钮的name必须不同。对按钮的调用显然也应该根据其name。
纵观两种用JavaScript调用代理的方法,各有特点。使用urlcommand比较方便易用,但缺点是取不到浏览器端的当前文档,代理很多强大的功能无法展开。使用第二种方法,实际上是JavaScript通过调用操作按钮,间接调用了代理。这种方法功能强大,但是,创建和维护都稍显复杂。最后指出:所谓使用JavaScript调用Formula,也就是指用JavaScript调用操作按钮,而操作按钮则中执行的是各类对文档进行操作的Formula。即用JavaScript间接调用了Formula。
三 由代理向JavaScript通信
使用代理向JavaScript通信,可以分为用代理写出JavaScript程序和用代理设置JavaScript参数。
[一]用代理写出JavaScript程序。
我们可以使用代理中的print系统函数,在窗口打印信息。这些信息为浏览器认做HTML语句来解释。这样我们就可以用print函数在代理中写JavaScript程序。
例如以下代码片段:
If dc.count=0 then
‘dc为在前面程序里使用database.search得到的DocumentCollection
Print "<SCRIPT LANGUAGE=JavaScript>"
Print "alert(""没有找到相关文档,请和管理员联系。"")"
Print "location.href = ""/Web+test.nsf/Main+View?OpenView"""
Print "</SCRIPT>"
End if
该段代码执行如下功能,判断如果当前搜索得到的文档集为空,就在浏览器端显示出错信息,然后将窗口路径指向某视图。
再看一个代码片段:
flag =curdoc.save(True,False)
If flag Then
Print "<OBJECT id=closes type=""application/x-oleobject""classid=""clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"">"
Print " <param name=""Command"" value=""Close""> </object>"
Print "<script>"
Print "window.setTimeout('closes.Click()',1000)"
Print "</script>"
Print "<h4>个人选项保存成功。</h4>"
End If
该段代码执行如下功能,判断如果当前文档保存成功,就在浏览器端显示确认信息,随即关闭窗口。
使用代理写JavaScript程序我们可以做出许多有效、方便的功能来。比如动态的信息展播等。
[二]用代理设置JavaScript参数。
这里JavaScript是表单中写好的,但是JavaScript的某些参数可能使用表单中某些域的值。这样用代理设置了该域的值也就设置了JavaScript参数。
例如:某系统用户要求在申请单中的“编号”字段用户能手动填写,但是又要能保证:如有重复的号码,系统要给与提醒。
解决办法就是:
1. 使用webquaryopen事件运行代理,使其将所有已经编号文挡的编号值都以逗号隔开,放入文档的某域中。
2. 而在表单内则写入JavaScript代码。将该域的值取出作参数,再将该参数以逗号隔开取得字符串数组。
3. 最后在域有效性验证时,比较当前的编号是否存在于数组中,若是则返回出错,否则成功。
比较以上介绍的两种方法。第一种方法:因为JS代码都由代理写出来,所以形式更灵活、功能更强大。但是,由于代码是Print出来的,无法和文档在窗口共存;所以,这种方法一般使用在信息展示方面。第二种方法:由于大部分代码是在浏览器端写好的,所以功能相对单一。因为代理通过修改域值影响JavaScript代码;所以,一般用在文档处理方面。
四 由Formula向JavaScript通信
Formula调用JavaScript。与代理调用JavaScript的第2条十分相似。但是,因为Formula能控制表单元素的显示属性。而Agent能访问更多的数据,所以Formula与Agent各有千秋。
这里介绍一个比较有趣的例子,就是怎样使文挡按条件自动编辑。即某些情况下文挡打开时为阅读状态。另一些情况,文档打开时则为编辑状态。显然,设置表单的自动编辑功能是无法完成功能的。
做法:
1. 在表单建立JavaScript函数autoedit。
2. 函数中写入代码取得当前窗口路径,将路径最后几个字符opendocument替换成editdocument,然后存在变量mypath中。
3. 假设文档是否自动编辑的判断条件是当前用户在公共通讯录里的个人文档的“myauto”字段是否为“yes”。那么在JavaScript函数“autoedit”中写JavaScript代码:t=<此处为计算文本>,计算文本的公式为“@dblookup(""; "" : "names.nsf" ; "people"; @name([ cn ] ; @username) ; "myauto")”。
4. 在JavaScript函数“autoedit”中加入代码,判断t是否为“yes”,若是则为将window.location置为mypath。然后将本段代码设置为在编辑状态下隐藏。
5. form的onload事件中加入JavaScript代码,调用autoload函数。