Elcascader.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. o2.xDesktop.requireApp("process.Xform", "$Elinput", null, false);
  2. /** @class Elcascader 基于Element UI的级联选择框组件。
  3. * @o2cn 级联选择框
  4. * @example
  5. * //可以在脚本中获取该组件
  6. * //方法1:
  7. * var input = this.form.get("name"); //获取组件
  8. * //方法2
  9. * var input = this.target; //在组件事件脚本中获取
  10. * @extends MWF.xApplication.process.Xform.$Module
  11. * @o2category FormComponents
  12. * @o2range {Process|CMS|Portal}
  13. * @hideconstructor
  14. * @see {@link https://element.eleme.cn/#/zh-CN/component/cascader|Element UI Cascader 级联选择器}
  15. */
  16. MWF.xApplication.process.Xform.Elcascader = MWF.APPElcascader = new Class(
  17. /** @lends MWF.xApplication.process.Xform.Elcascader# */
  18. {
  19. Implements: [Events],
  20. Extends: MWF.APP$Elinput,
  21. options: {
  22. /**
  23. * 组件加载后触发。如果选项加载为异步,则异步处理完成后触发此事件
  24. * @event MWF.xApplication.process.Xform.Elcascader#load
  25. */
  26. "moduleEvents": ["load", "queryLoad", "postLoad"],
  27. /**
  28. * 当获得焦点时触发。this.event[0]指向Event
  29. * @event MWF.xApplication.process.Xform.Elcascader#focus
  30. * @see {@link https://element.eleme.cn/#/zh-CN/component/cascader|级联选择框的Cascader Events章节}
  31. */
  32. /**
  33. * 当失去焦点时触发。this.event[0]指向Event
  34. * @event MWF.xApplication.process.Xform.Elcascader#blur
  35. * @see {@link https://element.eleme.cn/#/zh-CN/component/cascader|级联选择框的Cascader Events章节}
  36. */
  37. /**
  38. * 当选中节点变化时触发。this.event[0]为选中节点的值
  39. * @event MWF.xApplication.process.Xform.Elcascader#change
  40. * @see {@link https://element.eleme.cn/#/zh-CN/component/cascader|级联选择框的Cascader Events章节}
  41. */
  42. /**
  43. * 下拉框出现/隐藏时触发。this.event[0]的值:出现则为 true,隐藏则为 false
  44. * @event MWF.xApplication.process.Xform.Elcascader#visible-change
  45. * @see {@link https://element.eleme.cn/#/zh-CN/component/cascader|级联选择框的Cascader Events章节}
  46. */
  47. /**
  48. * 在多选模式下,移除Tag时触发。this.event[0]为移除的Tag对应的节点的值
  49. * @event MWF.xApplication.process.Xform.Elcascader#remove-tag
  50. * @see {@link https://element.eleme.cn/#/zh-CN/component/cascader|级联选择框的Cascader Events章节}
  51. */
  52. /**
  53. * 当展开节点发生变化时触发。this.event[0]指向各父级选项值组成的数组
  54. * @event MWF.xApplication.process.Xform.Elcascader#expand-change
  55. * @see {@link https://element.eleme.cn/#/zh-CN/component/cascader|级联选择框的Cascader Events章节}
  56. */
  57. /**
  58. * 过滤函数调用之前的钩子函数。this.event[0]指向value参数:如果该函数的返回值是 false 或者是一个被拒绝的Promise,那么接下来的过滤便不会执行。
  59. * @event MWF.xApplication.process.Xform.Elcascader#before-filter
  60. * @see {@link https://element.eleme.cn/#/zh-CN/component/cascader|级联选择框的Cascader Events章节}
  61. */
  62. "elEvents": ["focus", "blur", "change", "visible-change", "remove-tag", "expand-change", "before-filter"]
  63. },
  64. // _loadNode: function(){
  65. // if (this.isReadonly()) this.json.disabled = true;
  66. // this._loadNodeEdit();
  67. // },
  68. resetOption: function(){
  69. this.reload();
  70. },
  71. _loadMergeReadContentNode: function( contentNode, data ){
  72. this._loadOptions();
  73. Promise.resolve(this.json.options).then(function(options){
  74. if (data.data){
  75. var text = this.__getOptionsText(options, data.data);
  76. contentNode.set("text", text);
  77. }
  78. }.bind(this));
  79. },
  80. _appendVueData: function(){
  81. this.form.Macro.environment.data.check(this.json.id);
  82. this.json[this.json.id] = this._getBusinessData();
  83. if (!this.json.options) this.json.options = [];
  84. if (!this.json.clearable) this.json.clearable = false;
  85. if (!this.json.size) this.json.size = "";
  86. if (!this.json.popperClass) this.json.popperClass = "";
  87. if (this.json.showAllLevels!==false) this.json.showAllLevels = true;
  88. if (!this.json.separator) this.json.separator = "/";
  89. if (!this.json.disabled) this.json.disabled = false;
  90. if (!this.json.description) this.json.description = "";
  91. if (!this.json.filterable) this.json.filterable = false;
  92. if (!this.json.collapseTags) this.json.collapseTags = false;
  93. if (!this.json.props) this.json.props = {};
  94. if (!this.json.props.expandTrigger) this.json.props.expandTrigger = "click";
  95. if (!this.json.props.multiple) this.json.props.multiple = false;
  96. if (this.json.props.emitPath!==false) this.json.props.emitPath = true;
  97. if (!this.json.props.lazy) this.json.props.lazy = false;
  98. if (!this.json.props.lazyLoad) this.json.props.lazyLoad = null;
  99. if (!this.json.props.value) this.json.props.value = "value";
  100. if (!this.json.props.label) this.json.props.label = "label";
  101. if (!this.json.props.children) this.json.props.children = "children";
  102. if (!this.json.props.disabled) this.json.props.disabled = "disabled";
  103. if (!this.json.props.leaf) this.json.props.leaf = "leaf";
  104. this._loadOptions();
  105. //if (this.json.props.multiple===true) if (!this.json[this.json.id] || !this.json[this.json.id].length) this.json[this.json.id] = [];
  106. if (this.json.props.multiple===true) if (!this.json[this.json.$id] || !this.json[this.json.$id].length) this.json[this.json.$id] = [];
  107. },
  108. appendVueMethods: function(methods){
  109. if (this.json.filterMethod && this.json.filterMethod.code){
  110. var fn = this.form.Macro.exec(this.json.filterMethod.code, this);
  111. methods.$filterMethod = function(){
  112. fn.apply(this, arguments);
  113. }.bind(this);
  114. }
  115. if (this.json.lazyLoadScript && this.json.lazyLoadScript.code){
  116. var fn = this.form.Macro.exec(this.json.lazyLoadScript.code, this);
  117. this.json.props.lazyLoad = function(){
  118. fn.apply(this, arguments);
  119. }.bind(this);
  120. }
  121. if (this.json.beforeFilter && this.json.beforeFilter.code){
  122. var fn = this.form.Macro.exec(this.json.beforeFilter.code, this);
  123. methods.$beforeFilter = function(){
  124. fn.apply(this, arguments);
  125. }.bind(this);
  126. }
  127. },
  128. _setOptionsWithCode: function(code){
  129. var v = this.form.Macro.exec(code, this);
  130. if (v.then){
  131. this.moduleSelectAG = v.then(function(o){
  132. if (o2.typeOf(o)==="array"){
  133. this.json.options = o;
  134. this.json.$options = o;
  135. }
  136. return this.json.options || [];
  137. }.bind(this));
  138. }else if (o2.typeOf(v)==="array"){
  139. this.json.options = v;
  140. this.json.$options = v;
  141. }
  142. },
  143. _loadOptions: function(){
  144. if (this.json.itemsScript && this.json.itemsScript.code) this._setOptionsWithCode(this.json.itemsScript.code);
  145. },
  146. _createElementHtml: function(){
  147. if (!this.json.options) this.json.options = [];
  148. if (!this.json.clearable) this.json.clearable = false;
  149. if (!this.json.size) this.json.size = "";
  150. if (!this.json.popperClass) this.json.popperClass = "";
  151. if (this.json.showAllLevels!==false) this.json.showAllLevels = true;
  152. if (!this.json.separator) this.json.separator = "/";
  153. if (!this.json.disabled) this.json.disabled = false;
  154. if (!this.json.description) this.json.description = "";
  155. if (!this.json.filterable) this.json.filterable = false;
  156. if (!this.json.props) this.json.props = {};
  157. var html = "<el-cascader ";
  158. html += " v-model=\""+this.json.$id+"\"";
  159. html += " :clearable=\"clearable\"";
  160. html += " :size=\"size\"";
  161. html += " :filterable=\"filterable\"";
  162. html += " :disabled=\"disabled\"";
  163. html += " :placeholder=\"description\"";
  164. html += " :options=\"options\"";
  165. html += " :collapse-tags=\"collapseTags\"";
  166. html += " :show-all-levels=\"showAllLevels\"";
  167. html += " :separator=\"separator\"";
  168. html += " :popper-class=\"popperClass\"";
  169. html += " :props=\"props\"";
  170. if (this.json.filterMethod && this.json.filterMethod.code){
  171. html += " :filter-method=\"$filterMethod\"";
  172. }
  173. if (this.json.beforeFilter && this.json.beforeFilter.code){
  174. html += " :before-filter=\"$beforeFilter\"";
  175. }
  176. this.options.elEvents.forEach(function(k){
  177. html += " @"+k+"=\"$loadElEvent_"+k.camelCase()+"\"";
  178. });
  179. if (this.json.elProperties){
  180. Object.keys(this.json.elProperties).forEach(function(k){
  181. if (this.json.elProperties[k]) html += " "+k+"=\""+this.json.elProperties[k]+"\"";
  182. }, this);
  183. }
  184. if (this.json.elStyles) html += " :style=\"elStyles\"";
  185. html += ">";
  186. if (this.json.vueSlot) html += this.json.vueSlot;
  187. html += "</el-cascader >";
  188. return html;
  189. },
  190. //__setReadonly: function(data){},
  191. getCheckedNodes: function(leafOnly){
  192. return (this.vm) ? this.vm.getCheckedNodes(leafOnly) : null;
  193. },
  194. __setReadonly: function(data){
  195. if (this.isReadonly()){
  196. this._loadOptions();
  197. this.fireEvent("postLoad");
  198. Promise.resolve(this.json.options || this.moduleSelectAG).then(function(options){
  199. if (data){
  200. var text = this.__getOptionsText(options, data);
  201. this.node.set("text", text);
  202. if( this.json.elProperties ){
  203. this.node.set(this.json.elProperties );
  204. }
  205. if (this.json.elStyles){
  206. this.node.setStyles( this._parseStyles(this.json.elStyles) );
  207. }
  208. if( !this.eventLoaded ){
  209. this._loadDomEvents();
  210. this.eventLoaded = true;
  211. }
  212. this.fireEvent("load");
  213. this.isLoaded = true;
  214. }
  215. }.bind(this));
  216. }
  217. },
  218. __getOptionsText: function(options, values, isGetArray){
  219. if (!!this.json.props.multiple){
  220. var text = [];
  221. values.forEach(function(v){
  222. if( typeOf( v ) === "array" ){
  223. text = text.concat(this.__getOptionsTextValue(options, v));
  224. }else{
  225. text = text.concat(this.__getLastOptionsTextValue(options, v));
  226. }
  227. }.bind(this));
  228. return isGetArray ? text : text.join(",");
  229. }else{
  230. if( typeOf( values ) === "array" ){
  231. var arr = this.__getOptionsTextValue(options, values);
  232. return isGetArray ? arr : arr.join(",");
  233. }else{
  234. return this.__getLastOptionsTextValue(options, values)
  235. }
  236. }
  237. },
  238. __getOptionsTextValue: function(options, values, prefix, prefixLabel){
  239. var separator = this.json.separator || "/";
  240. var text = [];
  241. var v = typeOf( values ) === "string" ? values : values.join(separator);
  242. options.forEach(function(op){
  243. var opValue = (prefix) ? prefix + separator + op[this.json.props.value] : op[this.json.props.value];
  244. var opLabel = (prefixLabel) ? prefixLabel + separator + op[this.json.props.label] : op[this.json.props.label];
  245. if (opValue == v) {
  246. text.push(opLabel);
  247. }else if (v.startsWith(opValue) && op[this.json.props.children] && op[this.json.props.children].length){
  248. text = text.concat(this.__getOptionsTextValue(op[this.json.props.children], values, opValue, opLabel));
  249. }
  250. }.bind(this));
  251. if (!this.json.showAllLevels){
  252. return text.map(function(t){
  253. return t.substring(t.indexOf(separator)+1, t.length);
  254. });
  255. }else{
  256. return text;
  257. }
  258. },
  259. __getLastOptionsTextValue: function (options, value) {
  260. var text;
  261. for( var i=0; i<options.length; i++ ){
  262. var op = options[i];
  263. if( op[this.json.props.children] && op[this.json.props.children].length ){
  264. text = this.__getLastOptionsTextValue( op[this.json.props.children], value );
  265. if( text )return text;
  266. }else{
  267. var opValue = op[this.json.props.value];
  268. var opLabel = op[this.json.props.label];
  269. if( opValue === value ){
  270. text = opLabel;
  271. }
  272. }
  273. }
  274. return text;
  275. },
  276. getDataByText: function(text){
  277. this._loadOptions();
  278. var opt = this.json.options;
  279. if( !opt )return "";
  280. if( o2.typeOf(opt.then)==="function" ){
  281. return Promise.resolve(opt).then(function(options){
  282. return this._getDataByText(options, text);
  283. }.bind(this));
  284. }else{
  285. return this._getDataByText(opt, text);
  286. }
  287. },
  288. _getDataByText: function(options, text){
  289. var values = [];
  290. if (!!this.json.props.multiple){
  291. var texts = typeOf( text ) === "array" ? text : [text];
  292. texts.forEach(function(t){
  293. if( typeOf( t ) === "array" && t.length > 1 ){
  294. values = values.concat(this._getEachDataByText(options, t));
  295. }else{
  296. values = values.concat(this._getLastDataByText(options, typeOf( t ) === "array" ? (t[0] || "") : t));
  297. }
  298. }.bind(this));
  299. return values;
  300. }else{
  301. if( typeOf( text ) === "array" && typeOf( text[0] ) === "array" ){
  302. text = text[0];
  303. }
  304. if( typeOf( text ) === "array" && text.length > 1 ){
  305. values = this._getEachDataByText(options, text);
  306. return values.length ? values[0] : [];
  307. }else{
  308. return this._getLastDataByText(options, typeOf( text ) === "array" ? (text[0] || "") : text);
  309. }
  310. }
  311. },
  312. _getEachDataByText: function(options, texts, prefix, prefixLabel){
  313. var separator = this.json.separator || "/";
  314. var value = [];
  315. var t = typeOf( texts ) === "string" ? texts : texts.join(separator);
  316. options.forEach(function(op){
  317. var opValue = (prefix) ? prefix + separator + op[this.json.props.value] : op[this.json.props.value];
  318. var opLabel = (prefixLabel) ? prefixLabel + separator + op[this.json.props.label] : op[this.json.props.label];
  319. if (opLabel === t) {
  320. value.push(opValue.split(separator));
  321. }else if (t.startsWith(opLabel) && op[this.json.props.children] && op[this.json.props.children].length){
  322. value = value.concat(this._getEachDataByText(op[this.json.props.children], texts, opValue, opLabel));
  323. }
  324. }.bind(this));
  325. if (!this.json.showAllLevels){
  326. return value.map(function(t){
  327. return typeOf( t ) === "array" ? t.getLast() : t;
  328. });
  329. }else{
  330. return value;
  331. }
  332. },
  333. _getLastDataByText: function (options, text) {
  334. var value;
  335. for( var i=0; i<options.length; i++ ){
  336. var op = options[i];
  337. if( op[this.json.props.children] && op[this.json.props.children].length ){
  338. value = this._getLastDataByText( op[this.json.props.children], text );
  339. if( value )return value;
  340. }else{
  341. var opValue = op[this.json.props.value];
  342. var opLabel = op[this.json.props.label];
  343. if( opLabel === text ){
  344. value = opValue;
  345. }
  346. }
  347. }
  348. return value;
  349. },
  350. /**
  351. * @summary 获取选中项的text。
  352. * @return {Array} 返回选中项的text数组
  353. * @example
  354. * var texts = this.form.get('fieldId').getText(); //获取选中项的文本数组
  355. */
  356. getText: function(){
  357. return this._getText( true );
  358. },
  359. _getText: function( isGetArray ){
  360. var data = this.json[this.json.$id];
  361. if( !data )return "";
  362. var opt = this.json.options;
  363. if( !opt )return "";
  364. if( o2.typeOf(opt.then)==="function" ){
  365. return Promise.resolve(opt).then(function(options){
  366. return this.__getOptionsText(options, data, isGetArray);
  367. }.bind(this));
  368. }else{
  369. return this.__getOptionsText(opt, data, isGetArray);
  370. }
  371. },
  372. getExcelData: function( type ){
  373. var data = this.json[this.json.$id];
  374. if( !data )return "";
  375. if( type === "value" )return data;
  376. var text = this._getText();
  377. return typeOf(text) === "array" ? text.join(", ") : (text || "");
  378. },
  379. setExcelData: function(d, type){
  380. var separator = this.json.separator || "/";
  381. var arr = this.stringToArray(d);
  382. this.excelData = arr;
  383. arr = arr.map(function (a) {
  384. return a.contains(separator) ? a.split(separator) : a;
  385. });
  386. if( type === "value" ){
  387. this.setData(arr);
  388. }else{
  389. var data = this.getDataByText( arr );
  390. this.setData(data);
  391. }
  392. }
  393. });