动态表单插件
============

动态表单是最基本的交互界面，移动端表单、单据、基础资料、报表，都是基于动态表单，表单的视图模型、数据模型、插件模型等，会被这些业务对象继承扩展。

动态表单不与物理表格直接关联，只显示内存中的数据，可以用于：



- 显示交互信息

- 显示其他界面加工后传入的数据

- 显示来自于数据库，但需要经过加工的数据

- 纯交互界面

- 其他

动态表单相对于单据，数据来源更加的灵活，用途更加广泛。

脚本插件新建
------------

![](media/e20c4096c94ad606de982cb5883811c5.png)

脚本插件的注册
--------------

![](media/1023e037d95d32d6d5cb5895ba061bbc.png)

常用样例及方法介绍
------------------

**案例1: preOpenForm**

> 案例需求说明

- 自定义界面标题

- 自行校验界面查看权，如果未授权，不允许显示

> 实现方案

- 捕获界面显示 preOpenForm事件

a.修改显示参数，调整界面标题

b.校验权限，如果无权，取消界面显示

- 上述场景仅用于演示，实际验权由系统自动处理，不需要插件验权。

> KS实例代码
```
require("kd.bos.context.RequestContext");
require("kd.bos.servicehelp.permission.PermissionServiceHelper");
require("kd.bos.servicehelper.model.PermissionStatus");
var plugin = new FormPlugin({
    preOpenForm: function(e) {
         // 设置显示参数 - 是否触发TimerElapsed事件
		var showParameter = e.getSource();
		showParameter.setListentimerElapsed(true);
		
		// 设置显示参数 - 界面标题
		showParameter.setCaption("hello world");
		// 检查用户是否获得授权，如未授权，撤销界面显示
		if (!this.checkFunctionPermission(showParameter.getFormId(), PermissionStatus.View)){
			e.setCancel(true);
			e.setCancelMessage("对不起，您无权访问此页面！");
		}
    },
    checkFunctionPermission: function(formId, permissionItemId) {
		var userId = RequestContext.get().getUserId();
		int result = PermissionServiceHelper.checkFunctionPermission(
				userId, 
				RequestContext.get().getOrgId(), 
				formId, 
				permissionItemId);
		return result == 1;
	}
);

```

**案例2 :registerListener**

> 案例需求说明

- 响应主菜单上自定义的菜单点击事件；

- 响应自定义按钮点击事件；

- 响应单据体行点击事件；

- 响应树形控件节点点击事件；

> 实现方案

- 插件实现控件的插件事件接口，实现事件的处理方法

- 捕获表单：
refisterListener事件，侦听控件的插件事件，传入实现了事件接口的插件实例

- 略过事件处理的详细逻辑

> KS实例代码
```
var plugin = new FormPlugin({
KEY_MBAR : "tbmain",
	KEY_BARITEM1 : "baritem1",
	KEY_BUTTON1 : "buttonap1",
	KEY_ENTRYENTITY : "entryentity",
	KEY_TREEVIEW1 : "treeviewap1",
registerListener: function(e) {
// 主菜单按钮点击
		var mbar = this.getView().getControl(this.KEY_MBAR);
		mbar.addItemClickListener(this);
		
		// 按钮点击
		var button = this.getView().getControl(this.KEY_BUTTON1);
		button.addClickListener(this);
		
		// 单据体行点击
		var entryGrid = this.getView().getControl(this.KEY_ENTRYENTITY);
		entryGrid.addRowClickListener(this);
		
		// 树型控件点击
		var treeView = this.getView().getControl(this.KEY_TREEVIEW1);
		treeView.addTreeNodeClickListener(this);
},
	
itemClick : function(evt) {
		if (this.KEY_BARITEM1 == evt.getItemKey()){
			// 事件处理代码略过
		}
	},
	
click : function(evt) {
		var source = evt.getSource();
		if (this.KEY_BUTTON1==source.getKey()){
			// 事件处理代码略过
		}
	},
	
entryRowClick : function(evt) {
		var source = (Control) evt.getSource();
		if (KEY_ENTRYENTITY == source.getKey()){
			// 事件处理代码略过
		}
	},
	
treeNodeClick : function(evt) {
		// 事件处理代码略过
		var treeView = evt.getSource();
		if (KEY_TREEVIEW1 == treeView.getKey()){
			// 事件处理代码略过
		}
	}
});

```
**案例3: afterCreateNewData**

> 案例说明

- 表单加载时，给单据体默认创建10行，并设置整数字段(integerfieldap1)值为与行号相同

> 实现方案

- 处理 afterCreateNewData 事件

a.给单据体添加10行；

b.逐行填写整数字段值；

> KS实例代码
```
var plugin = new FormPlugin({
     KEY_ENTRYENTITY : "entryentity",
	KEY_INTEGERFIELD1 : "integerfieldap1",
afterCreateNewData: function(e) {
         VAR rowCount = this.getModel().getEntryRowCount(this.KEY_ENTRYENTITY);
		if (rowCount < 10){
			// 给单据体补足10行
			this.getModel().batchCreateNewEntryRow(this.KEY_ENTRYENTITY, 10 - rowCount);
			rowCount = 10;
		}
		
		// 逐行给整数字段设置默认值
		for(var row = 0; row < rowCount ; row++){
			ar fldValue = row + 1;
			this.getModel().setValue(this.KEY_INTEGERFIELD1, fldValue, row);
		}
    }
);

```

**案例4: itemClick**

> 案例说明

- 主菜单栏，增加一个自定义菜单；

- 用户点击自定义菜单时，检查名字字段有没有填写；

a.已经填写了名字时，提示"hello , xxx!"

b.没有填写名字时，提示 "hello, who are you?"

> 实现方案

- 在beforeItemClick事件，检查用户有没有填写名字

a.如果没有填写，取消后续操作，显示”hello, who are you?”

- 在itemClick事件，不需再检查名字有没有填写，直接显示”hello , xxx!”

> KS实例代码

```
var plugin = new FormPlugin({
    KEY_MAINBAR : "tbar_main",
KEY_BARITEM_HELLO : "baritem_hello",
KEY_NAME : "name",
    registerListener: function(e) {
         // 侦听主菜单按钮点击事件
		this.addItemClickListeners(this.KEY_MAINBAR);
    },
    beforeItemClick: function(evt) {
		if (this.KEY_BARITEM_HELLO == evt.getItemKey()){
			var youName = this.getModel().getValue(this.KEY_NAME);
			if (youName==null){
				this.getView().showMessage("hello, who are you?");
				evt.setCancel(true);	// 取消后续操作
			}
		}
	},
     itemClick: function(evt) {
		if (this.KEY_BARITEM_HELLO == evt.getItemKey()){
			var youName = this.getModel().getValue(this.KEY_NAME);
			this.getView().showMessage("hello, " + youName + "!");
		}
	}
);

```

场景案例详见“金蝶云苍穹KDE脚本插件开发指南-V2.0”

<https://club.kdcloud.com/school/6104>
