mwf.xdesktop.requireapp("process.xform", "$module", null, false);
/** @class $input 组件类,此类为所有输入组件的父类
* @hideconstructor
* @o2category formcomponents
* @extends mwf.xapplication.process.xform.$module
* @abstract
*/
mwf.xapplication.process.xform.$input = mwf.app$input = new class(
/** @lends mwf.xapplication.process.xform.$input# */
{
implements: [events],
extends: mwf.app$module,
iconstyle: "personfieldicon",
options: {
"moduleevents": ["change", "load", "queryload", "postload"]
},
initialize: function(node, json, form, options){
this.node = $(node);
this.node.store("module", this);
this.json = json;
this.form = form;
this.field = true;
this.fieldmoduleloaded = false;
this.nodehtml = this.node.get("html");
},
_loaduserinterface: function(){
if ( this.issectionmergeread() ) { //区段合并显示
this._loadmergereadnode();
}else{
if( this.issectionmergeedit() ){
this._loadmergeeditnode();
}else{
this._loadnode();
}
if (this.json.compute === "show"){
this._setvalue(this._computevalue());
}else{
this._loadvalue();
}
}
},
_loaddomevents: function(){
object.each(this.json.events, function(e, key){
if (e.code){
if (this.options.moduleevents.indexof(key)===-1){
(this.node.getfirst() || this.node).addevent(key, function(event){
return this.form.macro.fire(e.code, this, event);
}.bind(this));
}
}
}.bind(this));
},
_loadevents: function(){
object.each(this.json.events, function(e, key){
if (e.code){
if (this.options.moduleevents.indexof(key)!==-1){
this.addevent(key, function(event){
return this.form.macro.fire(e.code, this, event);
}.bind(this));
}else{
(this.node.getfirst() || this.node).addevent(key, function(event){
return this.form.macro.fire(e.code, this, event);
}.bind(this));
}
}
}.bind(this));
},
addmoduleevent: function(key, fun){
if (this.options.moduleevents.indexof(key)!==-1){
this.addevent(key, function(event){
return (fun) ? fun(this, event) : null;
}.bind(this));
}else{
(this.node.getfirst() || this.node).addevent(key, function(event){
return (fun) ? fun(this, event) : null;
}.bind(this));
}
},
/**
* @summary 重新加载组件。会执行postload事件。
* @example
* this.form.get("fieldid").reload(); //重新加载事件
*/
reload: function(){
if( this.iconnode ){
this.iconnode.destroy();
this.iconnode = null;
}
if( this.descriptionnode ){
this.descriptionnode.destroy();
this.descriptionnode = null;
}
this.node.empty();
this._beforereloaded();
this._loaduserinterface();
this._loadstyles();
this._afterloaded();
this._afterreloaded();
this.fireevent("postload");
},
_loadnode: function(){
if (this.isreadonly()){
this._loadnoderead();
}else{
this._loadnodeedit();
}
},
_loadnoderead: function(){
this.node.empty();
this.node.set({
"nodeid": this.json.id,
"mwftype": this.json.type
});
},
loaddescription: function(){
if (this.isreadonly())return;
var v = this._getbusinessdata();
if (!v){
if (this.json.description){
var size, w;
if( this.node.offsetparent === null ){ //隐藏
size = { y: 26 }
}else{
size = this.node.getfirst().getsize();
w = size.x-3;
if( this.hasicon() ){
if (common.browser.safari) w = w-20;
}
}
/**
* @summary 描述信息节点,允许用户手工输入的组件才有此节点,只读情况下无此节点.
* @member {element}
*/
this.descriptionnode = new element("div", {"styles": this.form.css.descriptionnode, "text": this.json.description}).inject(this.node);
this.descriptionnode.setstyles({
"height": "" size.y "px",
"line-height": "" size.y "px"
});
if( w )this.descriptionnode.setstyles({
"width": "" w "px"
});
this.setdescriptionevent();
}
}
},
setdescriptionevent: function(){
if (this.descriptionnode){
this.descriptionnode.addevents({
"mousedown": function(){
this.descriptionnode.setstyle("display", "none");
this.clickselect();
}.bind(this)
});
this.node.getfirst().addevents({
"focus": function(){
if (this.descriptionnode) this.descriptionnode.setstyle("display", "none");
}.bind(this),
"blur": function(){
if (!this.node.getfirst().get("value")) if (this.descriptionnode) this.descriptionnode.setstyle("display", "block");
}.bind(this)
});
}
},
checkdescription: function(){
if (!this.node.getfirst().get("value")){
if (this.descriptionnode) this.descriptionnode.setstyle("display", "block");
}else{
if (this.descriptionnode) this.descriptionnode.setstyle("display", "none");
}
},
_resetnodeedit: function(){
var input = new element("input", {
"styles": {
"background": "transparent",
"width": "100%",
"border": "0px"
},
"readonly": true
});
var node = new element("div", {"styles": {
"overflow": (this.json.styles && this.json.styles.overflow) ? this.json.styles.overflow : "hidden",
"position": "relative",
"margin-right": this.hasicon() ? "20px" : "0px",
"padding-right": "4px"
}}).inject(this.node, "after");
input.inject(node);
this.node.destroy();
this.node = node;
},
hasicon: function(){
return this.json.showicon!='no' && ( !this.form.json || !this.form.json.hidemoduleicon );
},
_loadnodeedit: function(){
if (!this.json.preprocessing) this._resetnodeedit();
var input = this.node.getfirst();
if( !input && this.nodehtml ){
this.node.set("html", this.nodehtml);
input = this.node.getfirst();
}
input.set(this.json.properties);
this.node.set({
"id": this.json.id,
"mwftype": this.json.type,
"readonly": true,
"events": {
"click": this.clickselect.bind(this)
}
});
if ( this.hasicon() ){
this.iconnode = new element("div", {
"styles": this.form.css[this.iconstyle],
"events": {
"click": this.clickselect.bind(this)
}
}).inject(this.node, "before");
}else if( this.form.json.nodestylewithhidemoduleicon ){
this.node.setstyles(this.form.json.nodestylewithhidemoduleicon)
}
this.node.getfirst().addevent("change", function(){
this.validationmode();
if (this.validation()) {
this._setbusinessdata(this.getinputdata("change"));
this.fireevent("change");
}
}.bind(this));
//
// var inputnode = this.node.getfirst();
// if (inputnode) inputnode.addevent("input", function(e){
// var v=e.target.get("value");
// this._setenvironmentdata(v);
// }.bind(this));
},
_loadstyles: function(){
if (this.json.styles) this.node.setstyles(this.json.styles);
if (this.json.inputstyles) if (this.node.getfirst()) this.node.getfirst().setstyles(this.json.inputstyles);
if (this.iconnode && this.iconnode.offsetparent !== null){
var size = this.node.getsize();
//if (!size.y){
// var y1 = this.node.getstyle("height");
// var y2 = this.node.getfirst().getstyle("height");
// alert(y1 "," y2);
// var y = ((y1!="auto" && y1>y2) || y2=="auto") ? y1 : y2;
// size.y = (y=="auto") ? "auto" : y.toint();
// //alert(size.y)
//}
this.iconnode.setstyle("height", "" size.y "px");
//alert(this.iconnode.getstyle("height"))
}
},
_computevalue: function(value){
return (this.json.defaultvalue && this.json.defaultvalue.code) ? this.form.macro.exec(this.json.defaultvalue.code, this): (value || "");
},
getvalue: function(){
if (this.modulevalueag) return this.modulevalueag;
var value = this._getbusinessdata();
if (!value) value = this._computevalue();
return value || "";
},
_setvalue: function(value){
// if (value && value.isag){
// var ag = o2.ag.all(value).then(function(v){
// if (o2.typeof(v)=="array") v = v[0];
// this.__setvalue(v);
// }.bind(this));
// this.modulevalueag = ag;
// ag.then(function(){
// this.modulevalueag = null;
// }.bind(this));
// }else {
if (!!value && o2.typeof(value.then)=="function"){
var p = promise.resolve(value).then(function(v){
this.__setvalue(v);
}.bind(this), function(){});
this.modulevalueag = p;
}else{
this.modulevalueag = null;
this.__setvalue(value);
}
//this.__setvalue(value);
// }
},
__setvalue: function(value){
this.modulevalueag = null;
this._setbusinessdata(value);
if (this.node.getfirst()) this.node.getfirst().set("value", value || "");
if (this.isreadonly()) this.node.set("text", value);
this.modulevalueag = null;
this.fieldmoduleloaded = true;
return value;
},
_loadvalue: function(){
this._setvalue(this.getvalue());
},
clickselect: function(){
},
_afterloaded: function(){
// if (this.iconnode){
//// var p = this.node.getposition();
//// var s = this.node.getsize();
//// var is = this.iconnode.getsize();
////
//// var y = p.y;
//// var x = p.x s.x-is.x;
// this.iconnode.setstyles({
// "top": "5px",
// "left": "-18px"
// });
// }
if (!this.isreadonly()){
this.loaddescription();
}
},
_beforereloaded: function(){},
_afterreloaded: function(){},
/**
* @summary 判断组件是否只读.
* @example
* var readonly = this.form.get('subject').isreadonly();
* @return {boolean} 是否只读.
*/
isreadonly : function(){
return !!(this.readonly || this.json.isreadonly || this.form.json.isreadonly || this.issectionmergeread());
},
gettextdata: function(){
//var value = this.node.get("value");
//var text = this.node.get("text");
var value = (this.node.getfirst()) ? this.node.getfirst().get("value") : this.node.get("text");
var text = (this.node.getfirst()) ? this.node.getfirst().get("text") : this.node.get("text");
return {"value": [value || ""] , "text": [text || value || ""]};
},
/**
* @summary 判断组件值是否为空.
* @example
* if( this.form.get('subject').isempty() ){
* this.form.notice('标题不能为空', 'warn');
* }
* @return {boolean} 值是否为空.
*/
isempty : function(){
var data = this.getdata();
return !data || !data.trim();
},
/**
* 在脚本中使用 this.data[fieldid] 也可以获取组件值。
* 区别如下:
* 1、当使用promise的时候
* 使用异步函数生成器(promise)为组件赋值的时候,用getdata方法立即获取数据,可能返回修改前的值,当promise执行完成以后,会返回修改后的值。
* this.data[fieldid] 立即获取数据,可能获取到异步函数生成器,当promise执行完成以后,会返回修改后的值。
* {@link https://www.yuque.com/o2oa/ixsnyt/ws07m0#eggil|具体差异请查看链接}
* 2、当表单上没有对应组件的时候,可以使用this.data[fieldid]获取值,但是this.form.get('fieldid')无法获取到组件。
* @summary 获取组件值。
* @example
* var data = this.form.get('fieldid').getdata(); //没有使用promise的情况、
* @example
* //如果无法确定表单上是否有组件,需要判断
* var data;
* if( this.form.get('fieldid') ){ //判断表单是否有无对应组件
* data = this.form.get('fieldid').getdata();
* }else{
* data = this.data['fieldid']; //直接从数据中获取字段值
* }
* @example
* //使用promise的情况
* var field = this.form.get("fieldid");
* var dict = new this.dict("test"); //test为数据字典名称
* var promise = dict.get("tools", true); //异步使用数据字典的get方法时返回promise,参数true表示异步
* promise.then( function(){
* var data = field.getdata(); //此时由于异步请求已经执行完毕,getdata方法获取到了数据字典的值
* })
* field.setdata( promise );
* @return 组件的数据.
*/
getdata: function(when){
if (this.json.compute == "save") this._setvalue(this._computevalue());
return this.getinputdata();
},
getinputdata: function(){
if (this.node.getfirst()){
return this.node.getfirst().get("value");
}else{
return this._getbusinessdata();
}
},
// /**
// * @summary 重置组件的值为默认值或置空。
// * @example
// * this.form.get('subject').resetdata();
// */
resetdata: function(){
this.setdata(this.getvalue());
},
/**当参数为promise的时候,请参考文档: {@link https://www.yuque.com/o2oa/ixsnyt/ws07m0|使用promise处理表单异步}
* 当表单上没有对应组件的时候,可以使用this.data.add(fieldid, data, true) 赋值。
* @summary 为组件赋值。
* @param data{string|promise} .
* @param firechange{boolean} 可选,是否触发change事件,默认false.
* @example
* this.form.get("fieldid").setdata("test"); //赋文本值
* @example
* //如果无法确定表单上是否有组件,需要判断
* if( this.form.get('fieldid') ){ //判断表单是否有无对应组件
* this.form.get('fieldid').setdata( data );
* }else{
* this.data.add(fieldid, data, true);
* }
* @example
* //使用promise
* var field = this.form.get("fieldid");
* var dict = new this.dict("test"); //test为数据字典名称
* var promise = dict.get("tools", true); //异步使用数据字典的get方法时返回promise,参数true表示异步
* field.setdata( promise );
*/
setdata: function(data, firechange){
// if (data && data.isag){
// var ag = o2.ag.all(data).then(function(v){
// if (o2.typeof(v)=="array") v = v[0];
// this.__setdata(v);
// }.bind(this));
// this.modulevalueag = ag;
// ag.then(function(){
// this.modulevalueag = null;
// }.bind(this));
// }else{
if (!!data && o2.typeof(data.then)=="function"){
var p = o2.promiseall(data).then(function(v){
this.__setdata(v, firechange);
// if (this.node.getfirst() && !this.readonly && !this.json.isreadonly) {
// this.checkdescription();
// this.validationmode();
// }
}.bind(this), function(){});
this.modulevalueag = p;
p.then(function(){
this.modulevalueag = null;
}.bind(this), function(){
this.modulevalueag = null;
}.bind(this));
}else{
this.modulevalueag = null;
this.__setdata(data, firechange);
// if (this.node.getfirst() && !this.readonly && !this.json.isreadonly) {
// this.checkdescription();
// this.validationmode();
// }
}
//this.__setdata(data);
//}
},
__setdata: function(data, firechange){
var old = this.getinputdata();
this._setbusinessdata(data);
if (this.node.getfirst()){
this.node.getfirst().set("value", data);
this.checkdescription();
this.validationmode();
}else{
this.node.set("text", data);
}
if (firechange && old!==data) this.fireevent("change");
this.modulevalueag = null;
},
createerrornode: function(text){
//var size = this.node.getfirst().getsize();
//var w = size.x-3;
//if (common.browser.safari) w = w-20;
//node.setstyles({
// "width": "" w "px",
// "height": "" size.y "px",
// "line-height": "" size.y "px",
// "position": "absolute",
// "top": "0px"
//});
var node;
if( this.form.json.errorstyle ){
if( this.form.json.errorstyle.type === "notice" ){
if( !this.form.errornoticing ){ //如果是弹出
this.form.errornoticing = true;
this.form.notice(text, "error", this.node, null, null, {
onclose : function () {
this.form.errornoticing = false;
}.bind(this)
});
}
}else{
node = new element("div",{
"styles" : this.form.json.errorstyle.node,
"text": text
});
if( this.form.json.errorstyle.close ){
var closenode = new element("div",{
"styles" : this.form.json.errorstyle.close ,
"events": {
"click" : function(){
//this.destroy();
this.validationmode();
}.bind(this)
}
}).inject(node);
}
}
}else{
node = new element("div");
var iconnode = new element("div", {
"styles": {
"width": "20px",
"height": "20px",
"float": "left",
"background": " center center no-repeat"
}
}).inject(node);
var textnode = new element("div", {
"styles": {
"height": "20px",
"line-height": "20px",
"margin-left": "20px",
"color": "red",
"word-break": "keep-all"
},
"text": text
}).inject(node);
}
return node;
},
notvalidationmode: function(text){
if (!this.isnotvalidationmode){
this.isnotvalidationmode = true;
this.node.store("borderstyle", this.node.getstyles("border-left", "border-right", "border-top", "border-bottom"));
this.node.setstyle("border-color", "red");
this.errnode = this.createerrornode(text);
//if (this.iconnode){
// this.errnode.inject(this.iconnode, "after");
//}else{
this.errnode.inject(this.node, "after");
//}
this.shownotvalidationmode(this.node);
var parentnode = this.errnode;
while( parentnode && parentnode.offsetparent === null ){
parentnode = parentnode.getparent();
}
if ( parentnode && !parentnode.isintoview()) parentnode.scrollintoview(false);
}
},
shownotvalidationmode: function(node){
var p = node.getparent("div");
if (p){
var mwftype = p.get("mwftype") || p.get("mwftype");
if (mwftype == "tab$content"){
if (p.getparent("div").getstyle("display")=="none"){
var contentareanode = p.getparent("div").getparent("div");
var tabareanode = contentareanode.getprevious("div");
var idx = contentareanode.getchildren().indexof(p.getparent("div"));
var tabnode = tabareanode.getlast().getfirst().getchildren()[idx];
tabnode.click();
p = tabareanode.getparent("div");
}
}
this.shownotvalidationmode(p);
}
},
validationmode: function(){
if (this.isnotvalidationmode){
this.isnotvalidationmode = false;
this.node.setstyles(this.node.retrieve("borderstyle"));
if (this.errnode){
this.errnode.destroy();
this.errnode = null;
}
}
},
validationconfigitem: function(routename, data){
var flag = (data.status==="all") ? true: (routename === data.decision);
if (flag){
var n = this.getinputdata();
var v = (data.valuetype==="value") ? n : n.length;
switch (data.operateor){
case "isnull":
if (!v){
this.notvalidationmode(data.prompt);
return false;
}
break;
case "notnull":
if (v){
this.notvalidationmode(data.prompt);
return false;
}
break;
case "gt":
if (v>data.value){
this.notvalidationmode(data.prompt);
return false;
}
break;
case "lt":
if (vdata.value)return data.prompt;
break;
case "lt":
if (v