開源O2OA辦公平臺搭建教程:表單中的事件

1. 概述

我們設計表單的時候經常會有這樣的需求:在表單或者組件加載前/加載後,能夠執行一些腳本來改變表單或組件的樣式和行爲。或者用戶在點擊組件的時候能夠執行腳本。表單的事件就是爲這樣的場景而設計。

在表單中有兩類事件:組件事件和Element事件。

當我們打開表單設計器,在表單屬性或組件屬性中的“事件”附籤中可以看到一組事件,這組事件即包含了兩種事件。表單事件見下圖

QQ圖片20201225134749.png

開發人員可以在事件編輯器中編寫腳本,也可以添加或刪除事件。

添加的組件事件需要在API的列表中才有效。

image.png

2 Element 事件

2.1 簡介

Element 是經過Mootools框架封裝後的HTML DOM對象,參考 http://www.chinamootools.com/element.html

Element 的事件類型和 HTML DOM 對象一致,比如"focus、click、blur"等。

本平臺的Element事件,是基於Mootools的 Element.Event 類進行封裝的。Element.Event類參考http://www.chinamootools.com/element_event.html

2.2 表單設計器中的使用

表單設計器中的事件,this對象指向平臺的MWF.xScript.Environment對象,這是平臺腳本的上下文,可以執行類似於"this.form"的腳本,上下文API請查看:鏈接

平臺在每次運行事件的時候,都會爲 this 對象添加一個屬性"target"。我們可以通過 this.target 來獲取當前組件。

//獲取當前組件對象
this.target;
//等價於
this.form.get("fieldName");

當我們在表單設計器的各種組件中添加了事件,在表單加載的時候,平臺會把事件添加到相應的Element對象。下表是各種組件對應的Element事件對象。

組件類型

Element事件對象

獲取Element腳本

Checkbox

多選按鈕

input[type='checkbox']

this.form.get("fieldName").node.getElements("input['type='checkbox']")

Radio

單選按鈕

input[type='radio']

this.form.get("fieldName").node.getElements("input['type='radio']")

Textarea

多行文本

textarea

this.form.get("fieldName").node.getFirst() || this.form.get("fieldName").node

Textfield

單行文本

input

this.form.get("fieldName").node.getFirst() || this.form.get("fieldName").node

Org

人員

第一個子div

this.form.get("fieldName").node.getFirst() || this.form.get("fieldName").node

Calendar

日期

input

this.form.get("fieldName").node.getFirst() || this.form.get("fieldName").node

Combox

組合框

第一個子div

this.form.get("fieldName").node.getFirst() || this.form.get("fieldName").node

Opinion

意見框

第一個子對象

this.form.get("fieldName").node.getFirst() || this.form.get("fieldName").node

Address

地址選擇

第一個子對象

this.form.get("fieldName").node.getFirst() || this.form.get("fieldName").node

Number

數字

input

this.form.get("fieldName").node.getFirst() || this.form.get("fieldName").node

其他

node

this.form.get("fieldName").node

  • 樣例:

在一個標識爲"subject"的文本組件的 focus 事件中增加了腳本。

image.png

對於上面的腳本,當光標進入輸入框的時候被執行。

 

如果希望由其他條件來觸發這個事件,也可以通過下面的腳本來執行:

var node = this.form.get("subject").node; //獲取組件節點
( node.getFirst() || node ).fireEvent("focus"); //觸發focus事件

 

2.3 在腳本中的使用

 

在上面的例子中,我們都是通過組件屬性中的事件區域來添加事件。除了這種方法,還可以在腳本中增加事件。

 

  • 使用 addEvent 對元素設置一個偵聽器。
myElement.addEvent(type, fn);

參數:

type - (string) 事件名,沒有'on'。

fn - (function) 事件函數。

返回:

(element)當前元素。

 

 

樣例:

下面的腳本可以實現上一個樣例的功能,在一個標識爲"subject"的文本組件的 focus 事件中增加腳本

var node = this.form.get("subject").node;
node.getElement("input").addEvent("focus", function(ev){
  //ev 是Mootools Element的Event對象,參考http://www.chinamootools.com/event.html
  //這裏的this指向input
  this.setStyle("border","1px solid blue");
})

 

  • 使用 addEvents 對元素設置多個偵聽器。
myElement.addEvents(events);

參數:

events - (object) 包含多個事件的對象(對象的key爲事件名,value爲事件函數)。

返回:

(element)當前元素。

 

樣例:

var node = this.form.get("subject").node;
node.getElement("input").addEvents({
  "focus" : function(ev){
    //ev 是Mootools Element的Event對象,參考http://www.chinamootools.com/event.html
    //這裏的this指向input
    this.setStyle("border","1px solid blue");
  },
  "blur": function(ev){
    //ev 是Mootools Element的Event對象,參考http://www.chinamootools.com/event.html
    //這裏的this指向input
    this.setStyle("border","1px solid gray");
  }
})

 

  • 使用fireEvent 觸發一個或多個事件
myElement.fireEvent(type[, args[, delay]]);

參數:

type - (string) 事件名稱(例如"click" )

args - (mixed, optional) 事件函數的參數,數組或單個對象,如果超過一個參數,必須是一個數組。

delay - (number, optional) 延遲(ms)執行時間。

返回:

(element)當前元素。

 

樣例:

var node = this.form.get("subject").node; //獲取組件節點
( node.getFirst() || node ).fireEvent("focus"); //觸發focus事件

 

3 組件事件

 

3.1 簡介

 

平臺中的組件是一組基於Mootools Class生成的對象。Mootools Class是MooTools框架的基類,參考http://www.chinamootools.com/class.html

 

在Mootools Class中有一系列的特性,其中就包括了 Class:Event,參考http://www.chinamootools.com/class_extras.html 中的 Event章節。

 

當我們在表單設計器的各種組件中添加了事件腳本,在表單加載的時候,代碼運行到相應的位置,這些腳本就會被觸發。比如平臺在加載組件(包括生成Html Dom,賦值等等)之前,會去執行queryLoad事件中的腳本;加載組件以後,會去執行postLoad中的事件。

 

3.2 表單設計器中的使用

 

表單設計器中的事件,this對象指向平臺的MWF.xScript.Environment對象,這是平臺腳本的上下文,可以執行類似於"this.form"的腳本,上下文API請查看:鏈接

 

平臺在每次運行事件的時候,都會爲 this 對象添加一個屬性"target"。我們可以通過 this.target 來獲取當前組件。

//獲取當前組件對象
this.target;
//等價於
this.form.get("fieldName");

 

某些需要參數的事件,平臺在每次運行的時候,爲 this 對象添加一個屬性"event "。我們可以通過 this.event 來獲取參數。

//有時候可以通過this.event獲取參數
this.event;

 

 

  • 樣例:在queryLoad腳本中根據流程活動名稱把當前組件設置爲只讀。

image.png

系統在加載組件的時候,會根據json的isReadonly判斷生成輸入框還是div節點。

 

如果希望由其他條件來觸發這個事件,也可以通過下面的腳本來執行:

var field = this.form.get("subject"); //獲取組件
field.fireEvent("queryLoad"); //觸發queryLoad事件

 

3.3 在腳本中的使用

在上面的例子中,我們都是通過組件屬性中的事件區域來添加事件。除了這種方法,還可以在腳本中增加事件。

 

 

 

  • 使用 addEvent 對組件設置一個事件。
myClass.addEvent(type, fn[, internal]);

參數:

type - (string)事件的類型(例如'queryLoad') ,包含在表單設計器裏組件的事件。

fn - (function)事件函數。

internal - (boolean, optional)設置函數屬性:internal爲true。internal屬性通常用來防止刪除。

返回:

(object)這個類的實例。

 

樣例:

在表單的保存的時候加一個事件,將臨時字段置空。

var form = this.form.getApp().appForm; //獲取表單組件
form.addEvent("beforeSave", function(){  //添加保存前事件
  this.form.get("tmpField").setData(''); //給臨時字段置空
}.bind(this))  //通過 bind(this), 把上下文傳到事件方法裏

 

  • 使用 addEvents 對組件設置多個偵聽器。
myClass.addEvents(events);

參數:

events - (object)一個key:value對象,key事件名稱(如"queryLoad" ) ,和值,當事件發生時要調用的函數。

返回:

(object)這個類的實例。

注: 通過這種方式添加事件,this.target 和 this.event 均爲空。

樣例:

var form = this.form.getApp().appForm; //獲取表單組件;
form.addEvents({
  "beforeSave" : function(){  //添加保存前事件
    this.form.get("tmpField").setData(''); //給臨時字段置空
  }.bind(this), //
  "beforeDelete": function(){ //增加刪除前事件
    //do something
  }
})
  • 使用fireEvent 觸發一個或多個事件
myClass.fireEvent(type[, args[, delay]]);

參數:

type - (string)事件的類型(例如'beforeSave') 。

args - (mixed,optional)傳遞給函數的參數。要傳遞多個參數,該參數必須是一個數組。

delay - ( number,optional)等待時間,單位毫秒。

返回:

(object)這個類的實例。

注: 通過這種方式添加事件,this.target 和 this.event 均爲空。

樣例一:

var form = this.form.getApp().appForm; //獲取表單組件;
form.fireEvent("beforeSave"); //觸發beforeSave事件

樣例二:假如臨時字段是觸發時傳入的,可以這樣寫

var form = this.form.getApp().appForm; //獲取表單組件;
form.fireEvent("beforeSave",["tmpFieldName1"]); //觸發beforeSave事件

則添加的事件需要改成如下:

var form = this.form.getApp().appForm; //獲取表單組件
form.addEvent("beforeSave", function( fieldName ){  //添加保存前事件
  this.form.get(fieldName").setData(''); //給臨時字段置空
}.bind(this))  //通過 bind(this), 把上下文傳到事件方法裏

3.4 表單和組件的加載順序

  • 整個表單加載時的順序遵循以下規則(a-f也是有順序的):

a、執行主表單事件 queryLoad -> beforeLoad -> beforeModulesLoad;

b、根據組件在主表單的位置從上到下,從裏到外執行組件的queryLoad->postLoad->load事件;

c、執行表單事件 postLoad;

c、子表單、子頁面、部件上的直接事件不會被執行,但子表單裏組件的事件也是根據 規則b 執行;

d、由於子表單、子頁面、部件是異步加載,這些組件內的組件事件在異步加載後分別執行;

e、執行表單事件 afterModulesLoad -> afterLoad;

f、當 Tab 組件、子表單、公文管理器等組件被設置爲延遲加載的時候,主表單加載的時候,這些組件內的子組件在不會加載。當這些組件被激活的時候,根據 規則b 執行事件。

 

  • 表單加載時觸發的直接事件說明:

表單的直接事件

說明

queryLoad

表單加載前觸發。數據(businessData)、預加載腳本和表單html已經就位。

beforeLoad

表單加載前觸發。已提示搶辦鎖定。

beforeModulesLoad

表單的所有組件加載前觸發,此時表單的樣式和js head已經加載。

postLoad

表單加載後觸發。主表單的組件加載完成,但不保證子表單、子頁面、部件加載完成。

afterModulesLoad

表單的所有組件加載後觸發。表單包含有子表單、子頁面、部件時,此事件會在這些組件加載後觸發。

afterLoad

表單加載後觸發。表單包含有子表單、子頁面、部件時,此事件會在這些組件加載後觸發。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章