$Selector.js 17 KB

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