$Selector.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. o2.xDesktop.requireApp("process.Xform", "$Input", null, false);
  2. /** @classdesc $Selector 组件类,此类为所有可选组件的父类
  3. * @class
  4. * @hideconstructor
  5. * @o2category FormComponents
  6. * @extends MWF.xApplication.process.Xform.$Input
  7. * @abstract
  8. */
  9. MWF.xApplication.process.Xform.$Selector = MWF.APP$Selector = new Class(
  10. /** @lends MWF.xApplication.process.Xform.$Selector# */
  11. {
  12. Extends: MWF.APP$Input,
  13. /**
  14. * 组件加载后触发。如果选项加载为异步,则异步处理完成后触发此事件
  15. * @event MWF.xApplication.process.Xform.$Selector#load
  16. * @see {@link https://www.yuque.com/o2oa/ixsnyt/hm5uft#i0zTS|组件事件说明}
  17. */
  18. _showValue: function (node, value) {
  19. var optionItems = this.getOptions();
  20. if (optionItems && typeOf(optionItems.then) === "function") {
  21. optionItems.then(function (opt) {
  22. this.__showValue(node, value, opt)
  23. }.bind(this));
  24. } else {
  25. this.__showValue(node, value, optionItems)
  26. }
  27. },
  28. /**
  29. * @summary 刷新选择项,如果选择项是脚本,重新计算。
  30. * @example
  31. * this.form.get('fieldId').resetOption();
  32. */
  33. resetOption: function () {
  34. this.node.empty();
  35. this.setOptions();
  36. this.fireEvent("resetOption");
  37. },
  38. /**
  39. * @summary 获取选择项。
  40. * @return {Array | Promise} 返回选择项数组或Promise,如:<pre><code class='language-js'>[
  41. * "女|female",
  42. * "男|male"
  43. * ]</code></pre>
  44. * @example
  45. * this.form.get('fieldId').getOptions();
  46. * @example
  47. * //异步
  48. * var opt = this.form.get('fieldId').getOptions();
  49. * Promise.resolve(opt).then(function(options){
  50. * //options为选择项数组
  51. * })
  52. */
  53. getOptions: function (async, refresh) {
  54. this.optionsCache = null;
  55. var opt = this._getOptions(async, refresh);
  56. if ((opt && typeOf(opt.then) === "function")) {
  57. var p = Promise.resolve(opt).then(function (option) {
  58. this.moduleSelectAG = null;
  59. this.optionsCache = (option || []);
  60. return this.optionsCache;
  61. }.bind(this));
  62. this.moduleSelectAG = p;
  63. return p;
  64. } else {
  65. this.optionsCache = (opt || []);
  66. return this.optionsCache;
  67. }
  68. },
  69. _getOptions: function (async, refresh) {
  70. switch (this.json.itemType) {
  71. case "values":
  72. return this.json.itemValues;
  73. case "script":
  74. return this.form.Macro.exec(((this.json.itemScript) ? this.json.itemScript.code : ""), this);
  75. default:
  76. break;
  77. }
  78. var opts, firstOpts = this.getFirstOption();
  79. switch (this.json.itemType) {
  80. case "dict":
  81. opts = this.getOptionsWithDict(async, refresh);
  82. break;
  83. case "view":
  84. opts = this.getOptionsWithView(async, refresh);
  85. break;
  86. case "statement":
  87. opts = this.getOptionsWithStatement(async, refresh);
  88. break;
  89. }
  90. if (opts && typeOf(opts.then) === "function") {
  91. return Promise.resolve(opts).then(function (opts) {
  92. return this._contactOption(firstOpts, opts);
  93. }.bind(this));
  94. } else {
  95. return this._contactOption(firstOpts, opts);
  96. }
  97. // if( (defaultOpts && typeOf(defaultOpts.then) === "function" ) || (opts && typeOf(opts.then) === "function" ) ){
  98. // return Promise.all( [defaultOpts, opts] ).then(function (arr) {
  99. // return this._contactOption( arr[0], arr[1] );
  100. // }.bind(this));
  101. // }else{
  102. // return this._contactOption( defaultOpts, opts );
  103. // }
  104. },
  105. _contactOption: function (opt1, opt2) {
  106. var optA, optB;
  107. if (!opt1) opt1 = [];
  108. if (!opt2) opt2 = [];
  109. optA = typeOf(opt1) !== "array" ? [opt1] : opt1;
  110. optB = typeOf(opt2) !== "array" ? [opt2] : opt2;
  111. optA.each(function (o) {
  112. if (o) optB.unshift(o);
  113. });
  114. return optB;
  115. },
  116. getFirstOption: function () {
  117. //return this.form.Macro.exec(((this.json.defaultOptionsScript) ? this.json.defaultOptionsScript.code : ""), this);
  118. if (!this.json.firstOptionEnable) return [];
  119. return [this.json.firstOption || "|"];
  120. },
  121. /**
  122. * @summary 获取整理后的选择项。
  123. * @param {Boolean} [refresh] 是否忽略缓存重新计算可选项。
  124. * @return {Object} 返回整理后的选择项数组或Promise,如:
  125. * <pre><code class='language-js'>{"valueList": ["","female","male"], "textList": ["","女","男"]}
  126. * </code></pre>
  127. * @example
  128. * var optionData = this.form.get('fieldId').getOptionsObj();
  129. * @example
  130. * //异步
  131. * var opt = this.form.get('fieldId').getOptionsObj(true);
  132. * Promise.resolve(opt).then(function(optionData){
  133. * //optionData为选择项
  134. * })
  135. */
  136. getOptionsObj: function (refresh) {
  137. var optionItems = (refresh !== true && this.optionsCache) ? this.optionsCache : this.getOptions();
  138. if (optionItems && typeOf(optionItems.then) === "function") {
  139. return Promise.resolve(optionItems).then(function (optItems) {
  140. return this._getOptionsObj(optItems);
  141. }.bind(this));
  142. } else {
  143. return this._getOptionsObj(optionItems);
  144. }
  145. },
  146. _getOptionsObj: function (optItems) {
  147. var textList = [];
  148. var valueList = [];
  149. optItems.each(function (item) {
  150. var tmps = item.split("|");
  151. textList.push(tmps[0]);
  152. valueList.push(tmps[1] || tmps[0]);
  153. });
  154. return {textList: textList, valueList: valueList};
  155. },
  156. setOptions: function () {
  157. var optionItems = this.getOptions();
  158. this._setOptions(optionItems);
  159. },
  160. /**
  161. * @summary 获取选中项的value和text。
  162. * @return {Object} 返回选中项的value和text,如:
  163. * <pre><code class='language-js'>{"value": ["male"], "text": ["男"]}
  164. * {"value": [""], "text": [""]}
  165. * </code></pre>
  166. * @example
  167. * var data = this.form.get('fieldId').getTextData();
  168. * var text = data.text[0] //获取选中项的文本
  169. */
  170. getTextData: function () {
  171. var ops;
  172. if (this.isReadonly() || !this._getInputTextData ) {
  173. ops = this.getOptionsObj();
  174. var data = this._getBusinessData();
  175. var d = typeOf(data) === "array" ? data : [data];
  176. if (ops && typeOf(ops.then) === "function") {
  177. return Promise.resolve(ops).then(function (opts) {
  178. return this._getTextData(d, opts)
  179. }.bind(this));
  180. } else {
  181. return this._getTextData(d, ops)
  182. }
  183. } else {
  184. return this._getInputTextData();
  185. }
  186. },
  187. _getTextData: function (d, opts) {
  188. var value = [], text = [];
  189. d.each(function (v) {
  190. var idx = opts.valueList.indexOf(v);
  191. value.push(v || "");
  192. text.push(idx > -1 ? opts.textList[idx] : (v || ""));
  193. });
  194. if (!value.length) value = [""];
  195. if (!text.length) text = [""];
  196. return {"value": value, "text": text};
  197. },
  198. getOptionsWithDict: function (async, refresh) {
  199. if (!this.json.itemDict || !this.json.itemDict.length) return [];
  200. var obj = this.json.itemDict[0];
  201. var dict = new this.form.Macro.environment.Dict({
  202. "type": obj.appType,
  203. "application": obj.appId,
  204. "name": obj.id
  205. });
  206. var paths = (this.json.itemDictPath || "").split("/");
  207. paths.splice(0, 1); //第一个是root,删掉
  208. var path = paths.length ? paths.join(".") : null;
  209. var asy = o2.typeOf(async) === "boolean" ? async : (this.json.itemDictAsync !== false);
  210. var data = dict.get(path, null, null, asy, !this.json.dictUseCache);
  211. if (data && typeOf(data.then) === "function") {
  212. return data.then(function (data) {
  213. return this.parseDictOptions(data);
  214. }.bind(this));
  215. } else {
  216. return this.parseDictOptions(data);
  217. }
  218. },
  219. getString: function (d) {
  220. switch (o2.typeOf(d)) {
  221. case "null":
  222. return "";
  223. case "string":
  224. return d;
  225. case "boolean":
  226. case "number":
  227. case "date":
  228. return d.toString();
  229. default:
  230. return "";
  231. }
  232. },
  233. parseDictOptions: function (d) {
  234. var arr = [], value, text, valuekey = this.json.dictValueKey, textkey = this.json.dictTextKey;
  235. switch (o2.typeOf(d)) {
  236. case "array":
  237. d.each(function (i) {
  238. switch (o2.typeOf(i)) {
  239. case "object":
  240. if (valuekey && textkey) {
  241. value = this.getString(i[valuekey]);
  242. text = this.getString(i[textkey]);
  243. arr.push(text + "|" + value);
  244. } else if (valuekey) {
  245. arr.push(this.getString(i[valuekey]));
  246. } else if (textkey) {
  247. arr.push(this.getString(i[textkey]));
  248. }
  249. break;
  250. case "null":
  251. break;
  252. default:
  253. arr.push(i.toString());
  254. break;
  255. }
  256. }.bind(this));
  257. return arr;
  258. case "object":
  259. Object.each(d, function (i, key) {
  260. switch (o2.typeOf(i)) {
  261. case "object":
  262. if (valuekey && textkey) {
  263. value = this.getString(i[valuekey]);
  264. text = this.getString(i[textkey]);
  265. arr.push(value + "|" + text);
  266. } else if (valuekey) {
  267. arr.push(this.getString(i[valuekey]));
  268. } else if (textkey) {
  269. arr.push(this.getString(i[textkey]));
  270. }
  271. break;
  272. case "null":
  273. break;
  274. default:
  275. arr.push(i.toString() + "|" + key.toString());
  276. break;
  277. }
  278. }.bind(this))
  279. return arr;
  280. case "null":
  281. return [];
  282. default:
  283. return [d.toString()];
  284. }
  285. },
  286. getOptionsWithView: function (async, refresh) {
  287. if (!this.json.itemView) return [];
  288. var obj = this.json.itemView;
  289. var asy = o2.typeOf(async) === "boolean" ? async : (this.json.itemViewAsync !== false);
  290. var filter = [];
  291. if (this.json.viewFilterList && this.json.viewFilterList.length) {
  292. this.json.viewFilterList.each(function (entry) {
  293. entry.value = this.form.Macro.exec(entry.code.code, this);
  294. filter.push(entry);
  295. }.bind(this));
  296. }
  297. var data = this.form.Macro.environment.view.lookup({
  298. "view": obj.id,
  299. "application": obj.application,
  300. "filter": filter
  301. }, null, asy);
  302. if (data && typeOf(data.then) === "function") {
  303. return data.then(function (data) {
  304. return this.parseViewOptions(data);
  305. }.bind(this));
  306. } else {
  307. return this.parseViewOptions(data);
  308. }
  309. },
  310. parseViewOptions: function (json) {
  311. var arr = [], value, text, valuekey = this.json.viewValueColumn, textkey = this.json.viewTextColumn;
  312. json.grid.each(function (d) {
  313. var i = d.data || {};
  314. if (valuekey && textkey) {
  315. value = valuekey === "bundle" ? d.bundle : (this.getString(i[valuekey]));
  316. text = textkey === "bundle" ? d.bundle : (this.getString(i[textkey]));
  317. arr.push(text + "|" + value);
  318. } else if (valuekey) {
  319. arr.push(valuekey === "bundle" ? d.bundle : (this.getString(i[valuekey])));
  320. } else if (textkey) {
  321. arr.push(textkey === "bundle" ? d.bundle : (this.getString(i[textkey])));
  322. }
  323. }.bind(this))
  324. return arr.unique();
  325. },
  326. getOptionsWithStatement: function (async, refresh) {
  327. if (!this.json.itemStatement) return [];
  328. var obj = this.json.itemStatement;
  329. var asy = o2.typeOf(async) === "boolean" ? async : (this.json.itemViewAsync !== false);
  330. var filter = [];
  331. if (this.json.statementFilterList && this.json.statementFilterList.length) {
  332. this.json.statementFilterList.each(function (entry) {
  333. entry.value = this.form.Macro.exec(entry.code.code, this);
  334. filter.push(entry);
  335. }.bind(this));
  336. }
  337. var parameter = {};
  338. if(this.json.statementParameterList && this.json.statementParameterList.length) {
  339. this.json.statementParameterList.each(function (entry) {
  340. parameter[entry.parameter] = this.parseParameter(entry);
  341. }.bind(this));
  342. }
  343. var data = this.form.Macro.environment.statement.execute({
  344. "name": obj.name,
  345. "mode": "data",
  346. "page": 1, //(number)可选,当前页码,默认为1
  347. "pageSize": 1000, //(number)可选,每页的数据条数,默认为20
  348. "filter": filter,
  349. "parameter": parameter,
  350. "parameterList": this.json.parameterList
  351. }, null, asy);
  352. if (data && typeOf(data.then) === "function") {
  353. return data.then(function (data) {
  354. return this.parseStatementOptions(data);
  355. }.bind(this));
  356. } else {
  357. return this.parseStatementOptions(data);
  358. }
  359. },
  360. parseStatementOptions: function (json) {
  361. var arr = [], value, text, valuekey = this.json.statementValueColumn,
  362. textkey = this.json.statementTextColumn;
  363. json.data.each(function (d) {
  364. if (valuekey && textkey) {
  365. value = this.getDataByPath(d, valuekey);
  366. text = this.getDataByPath(d, textkey);
  367. arr.push(text + "|" + value);
  368. } else if (valuekey) {
  369. value = this.getDataByPath(d, valuekey);
  370. arr.push(value);
  371. } else if (textkey) {
  372. text = this.getDataByPath(d, textkey);
  373. arr.push(text);
  374. }
  375. }.bind(this));
  376. return arr.unique();
  377. },
  378. parseParameter: function (f) {
  379. var value = f.value;
  380. if (f.valueType === "script") {
  381. value = this.form.Macro.exec(f.valueScript ? f.valueScript.code : "", this);
  382. }
  383. if (typeOf(value) === "date") {
  384. value = value.format("db");
  385. }
  386. var user = layout.user;
  387. switch (value) {
  388. case "@year":
  389. value = (new Date().getFullYear()).toString();
  390. break;
  391. case "@season":
  392. var m = new Date().format("%m");
  393. if (["01", "02", "03"].contains(m)) {
  394. value = "1"
  395. } else if (["04", "05", "06"].contains(m)) {
  396. value = "2"
  397. } else if (["07", "08", "09"].contains(m)) {
  398. value = "3"
  399. } else {
  400. value = "4"
  401. }
  402. break;
  403. case "@month":
  404. value = new Date().format("%Y-%m");
  405. break;
  406. case "@time":
  407. value = new Date().format("db");
  408. break;
  409. case "@date":
  410. value = new Date().format("%Y-%m-%d");
  411. break;
  412. default:
  413. }
  414. if (f.formatType === "dateTimeValue" || f.formatType === "datetimeValue") {
  415. value = "{ts '" + value + "'}"
  416. } else if (f.formatType === "dateValue") {
  417. value = "{d '" + value + "'}"
  418. } else if (f.formatType === "timeValue") {
  419. value = "{t '" + value + "'}"
  420. }
  421. return value;
  422. },
  423. getDataByPath: function (obj, path, isUppcase) {
  424. var pathList = isUppcase ? path.toUpperCase().split(".") : path.split(".");
  425. for (var i = 0; i < pathList.length; i++) {
  426. var p = pathList[i];
  427. if ((/(^[1-9]\d*$)/.test(p))) p = p.toInt();
  428. if (obj[p]) {
  429. obj = obj[p];
  430. } else if (obj[p] === undefined || obj[p] === null) {
  431. if (!isUppcase && i === 0) {
  432. return this.getDataByPath(obj, path, true);
  433. } else {
  434. obj = "";
  435. }
  436. break;
  437. } else {
  438. obj = obj[p];
  439. break;
  440. }
  441. }
  442. return this.getString(obj);
  443. }
  444. });