formSelects-v4.js 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740
  1. /**
  2. * name: formSelects
  3. * 基于Layui Select多选
  4. * version: 4.0.0.0910
  5. * http://sun.faysunshine.com/layui/formSelects-v4/dist/formSelects-v4.js
  6. */
  7. (function(layui, window, factory) {
  8. if(typeof exports === 'object') { // 支持 CommonJS
  9. module.exports = factory();
  10. } else if(typeof define === 'function' && define.amd) { // 支持 AMD
  11. define(factory);
  12. } else if(window.layui && layui.define) { //layui加载
  13. layui.define(['jquery'], function(exports) {
  14. exports('formSelects', factory());
  15. });
  16. } else {
  17. window.formSelects = factory();
  18. }
  19. })(typeof layui == 'undefined' ? null : layui, window, function() {
  20. let v = '4.0.0.0910',
  21. NAME = 'xm-select',
  22. PNAME = 'xm-select-parent',
  23. INPUT = 'xm-select-input',
  24. TDIV = 'xm-select--suffix',
  25. THIS = 'xm-select-this',
  26. LABEL = 'xm-select-label',
  27. SEARCH = 'xm-select-search',
  28. SEARCH_TYPE = 'xm-select-search-type',
  29. SHOW_COUNT = 'xm-select-show-count',
  30. CREATE = 'xm-select-create',
  31. CREATE_LONG = 'xm-select-create-long',
  32. MAX = 'xm-select-max',
  33. SKIN = 'xm-select-skin',
  34. DIRECTION = "xm-select-direction",
  35. HEIGHT = 'xm-select-height',
  36. DISABLED = 'xm-dis-disabled',
  37. DIS = 'xm-select-dis',
  38. TEMP = 'xm-select-temp',
  39. RADIO = 'xm-select-radio',
  40. LINKAGE= 'xm-select-linkage',
  41. DL = 'xm-select-dl',
  42. DD_HIDE = 'xm-select-hide',
  43. HIDE_INPUT = 'xm-hide-input',
  44. SANJIAO = 'xm-select-sj',
  45. ICON_CLOSE = 'xm-icon-close',
  46. FORM_TITLE = 'xm-select-title',
  47. FORM_SELECT = 'xm-form-select',
  48. FORM_SELECTED = 'xm-form-selected',
  49. FORM_NONE = 'xm-select-none',
  50. FORM_EMPTY = 'xm-select-empty',
  51. FORM_INPUT = 'xm-input',
  52. FORM_DL_INPUT = 'xm-dl-input',
  53. FORM_SELECT_TIPS = 'xm-select-tips',
  54. CHECKBOX_YES = 'xm-iconfont',
  55. FORM_TEAM_PID = 'XM_PID_VALUE',
  56. CZ = 'xm-cz',
  57. CZ_GROUP = 'xm-cz-group',
  58. TIPS = '请选择',
  59. data = {},
  60. events = {
  61. on: {},
  62. endOn: {},
  63. filter: {},
  64. maxTips: {},
  65. opened: {},
  66. closed: {}
  67. },
  68. ajax = {
  69. type: 'get',
  70. header: {
  71. },
  72. first: true,
  73. data: {},
  74. searchUrl: '',
  75. searchName: 'keyword',
  76. searchVal: null,
  77. keyName: 'name',
  78. keyVal: 'value',
  79. keySel: 'selected',
  80. keyDis: 'disabled',
  81. keyChildren: 'children',
  82. dataType: '',
  83. delay: 500,
  84. beforeSuccess: null,
  85. success: null,
  86. error: null,
  87. beforeSearch: null,
  88. response: {
  89. statusCode: 0,
  90. statusName: 'code',
  91. msgName: 'msg',
  92. dataName: 'data'
  93. },
  94. tree: {
  95. nextClick: function(id, item, callback){
  96. callback([]);
  97. },
  98. folderChoose: true,
  99. lazy: true
  100. }
  101. },
  102. quickBtns = [
  103. {icon: 'xm-iconfont icon-quanxuan', name: '全选', click: function(id, cm){
  104. cm.selectAll(id, true, true);
  105. }},
  106. {icon: 'xm-iconfont icon-qingkong', name: '清空', click: function(id, cm){
  107. cm.removeAll(id, true, true);
  108. }},
  109. {icon: 'xm-iconfont icon-fanxuan', name: '反选', click: function(id, cm){
  110. cm.reverse(id, true, true);
  111. }},
  112. {icon: 'xm-iconfont icon-pifu', name: '换肤', click: function(id, cm){
  113. cm.skin(id);
  114. }}
  115. ],
  116. $ = window.$ || (window.layui && window.layui.jquery),
  117. $win = $(window),
  118. ajaxs = {},
  119. fsConfig = {},
  120. fsConfigs = {},
  121. FormSelects = function(options) {
  122. this.config = {
  123. name: null, //xm-select="xxx"
  124. max: null,
  125. maxTips: (id, vals, val, max) => {
  126. let ipt = $(`[xid="${this.config.name}"]`).prev().find(`.${NAME}`);
  127. if(ipt.parents('.layui-form-item[pane]').length) {
  128. ipt = ipt.parents('.layui-form-item[pane]');
  129. }
  130. ipt.attr('style', 'border-color: red !important');
  131. setTimeout(() => {
  132. ipt.removeAttr('style');
  133. }, 300);
  134. },
  135. init: null, //初始化的选择值,
  136. on: null, //select值发生变化
  137. opened: null,
  138. closed: null,
  139. filter: (id, inputVal, val, isDisabled) => {
  140. return val.name.indexOf(inputVal) == -1;
  141. },
  142. clearid: -1,
  143. direction: 'auto',
  144. height: null,
  145. isEmpty: false,
  146. btns: [quickBtns[0], quickBtns[1], quickBtns[2]],
  147. searchType: 0,
  148. create: (id, name) => {
  149. return Date.now();
  150. },
  151. template: (id, item) => {
  152. return item.name;
  153. },
  154. showCount: 0,
  155. isCreate: false,
  156. placeholder: TIPS,
  157. clearInput: false,
  158. };
  159. this.select = null;
  160. this.values = [];
  161. $.extend(this.config, options, {
  162. searchUrl: options.isSearch ? options.searchUrl : null,
  163. placeholder: options.optionsFirst ? (
  164. options.optionsFirst.value ? TIPS : (options.optionsFirst.innerHTML || TIPS)
  165. ) : TIPS,
  166. btns: options.radio ? [quickBtns[1]] : [quickBtns[0], quickBtns[1], quickBtns[2]],
  167. }, fsConfigs[options.name] || fsConfig);
  168. if(isNaN(this.config.showCount) || this.config.showCount <= 0) {
  169. this.config.showCount = 19921012;
  170. }
  171. };
  172. //一些简单的处理方法
  173. let Common = function(){
  174. this.appender();
  175. this.on();
  176. this.onreset();
  177. };
  178. Common.prototype.appender = function(){//针对IE做的一些拓展
  179. //拓展Array map方法
  180. if(!Array.prototype.map){Array.prototype.map=function(i,h){var b,a,c,e=Object(this),f=e.length>>>0;if(h){b=h}a=new Array(f);c=0;while(c<f){var d,g;if(c in e){d=e[c];g=i.call(b,d,c,e);a[c]=g}c++}return a}};
  181. //拓展Array foreach方法
  182. if(!Array.prototype.forEach){Array.prototype.forEach=function forEach(g,b){var d,c;if(this==null){throw new TypeError("this is null or not defined")}var f=Object(this);var a=f.length>>>0;if(typeof g!=="function"){throw new TypeError(g+" is not a function")}if(arguments.length>1){d=b}c=0;while(c<a){var e;if(c in f){e=f[c];g.call(d,e,c,f)}c++}}};
  183. //拓展Array filter方法
  184. if(!Array.prototype.filter){Array.prototype.filter=function(b){if(this===void 0||this===null){throw new TypeError()}var f=Object(this);var a=f.length>>>0;if(typeof b!=="function"){throw new TypeError()}var e=[];var d=arguments[1];for(var c=0;c<a;c++){if(c in f){var g=f[c];if(b.call(d,g,c,f)){e.push(g)}}}return e}};
  185. }
  186. Common.prototype.init = function(target){
  187. //初始化页面上已有的select
  188. $((target ? target : `select[${NAME}]`)).each((index, select) => {
  189. let othis = $(select),
  190. id = othis.attr(NAME),
  191. hasLayuiRender = othis.next(`.layui-form-select`),
  192. hasRender = othis.next(`.${PNAME}`),
  193. options = {
  194. name: id,
  195. disabled: select.disabled,
  196. max: othis.attr(MAX) - 0,
  197. isSearch: othis.attr(SEARCH) != undefined,
  198. searchUrl: othis.attr(SEARCH),
  199. isCreate: othis.attr(CREATE) != undefined,
  200. radio: othis.attr(RADIO) != undefined,
  201. skin: othis.attr(SKIN),
  202. direction: othis.attr(DIRECTION),
  203. optionsFirst: select.options[0],
  204. height: othis.attr(HEIGHT),
  205. formname: othis.attr('name') || othis.attr('_name'),
  206. layverify: othis.attr('lay-verify') || othis.attr('_lay-verify'),
  207. layverType: othis.attr('lay-verType'),
  208. searchType: othis.attr(SEARCH_TYPE) == 'dl' ? 1 : 0,
  209. showCount: othis.attr(SHOW_COUNT) - 0,
  210. },
  211. value = othis.find('option[selected]').toArray().map((option) => {//获取已选中的数据
  212. return {
  213. name: option.innerHTML,
  214. value: option.value,
  215. }
  216. }),
  217. fs = new FormSelects(options);
  218. fs.values = value;
  219. if(fs.config.init) {
  220. fs.values = fs.config.init.map(item => {
  221. if(typeof item == 'object') {
  222. return item;
  223. }
  224. return {
  225. name: othis.find(`option[value="${item}"]`).text(),
  226. value: item
  227. }
  228. }).filter(item => {
  229. return item.name;
  230. });
  231. fs.config.init = fs.values.concat([]);
  232. }else{
  233. fs.config.init = value.concat([]);
  234. }
  235. !fs.values && (fs.values = []);
  236. data[id] = fs;
  237. //先取消layui对select的渲染
  238. hasLayuiRender[0] && hasLayuiRender.remove();
  239. hasRender[0] && hasRender.remove();
  240. //构造渲染div
  241. let dinfo = this.renderSelect(id, fs.config.placeholder, select);
  242. let heightStyle = !fs.config.height || fs.config.height == 'auto' ? '' : `xm-hg style="height: 34px;"`;
  243. let inputHtml = [
  244. `<div class="${LABEL}">`,
  245. `<input type="text" fsw class="${FORM_INPUT} ${INPUT}" ${fs.config.isSearch ? '' : 'style="display: none;"'} autocomplete="off" debounce="0" />`,
  246. `</div>`
  247. ];
  248. let reElem =
  249. $(`<div class="${FORM_SELECT}" ${SKIN}="${fs.config.skin}">
  250. <input class="${HIDE_INPUT}" value="" name="${fs.config.formname}" lay-verify="${fs.config.layverify}" lay-verType="${fs.config.layverType}" type="text" style="position: absolute;bottom: 0; z-index: -1;width: 100%; height: 100%; border: none; opacity: 0;"/>
  251. <div class="${FORM_TITLE} ${fs.config.disabled ? DIS : ''}">
  252. <div class="${FORM_INPUT} ${NAME}" ${heightStyle}>
  253. ${inputHtml.join('')}
  254. <i class="${SANJIAO}"></i>
  255. </div>
  256. <div class="${TDIV}">
  257. <input type="text" autocomplete="off" placeholder="${fs.config.placeholder}" readonly="readonly" unselectable="on" class="${FORM_INPUT}">
  258. </div>
  259. <div></div>
  260. </div>
  261. <dl xid="${id}" class="${DL} ${fs.config.radio ? RADIO:''}">${dinfo}</dl>
  262. </div>`);
  263. var $parent = $(`<div class="${PNAME}" FS_ID="${id}"></div>`);
  264. $parent.append(reElem)
  265. othis.after($parent);
  266. othis.attr('lay-ignore', '');
  267. othis.removeAttr('name') && othis.attr('_name', fs.config.formname);
  268. othis.removeAttr('lay-verify') && othis.attr('_lay-verify', fs.config.layverify);
  269. //如果可搜索, 加上事件
  270. if(fs.config.isSearch){
  271. ajaxs[id] = $.extend({}, ajax, {searchUrl: fs.config.searchUrl}, ajaxs[id]);
  272. $(document).on('input', `div.${PNAME}[FS_ID="${id}"] .${INPUT}`, (e) => {
  273. this.search(id, e, fs.config.searchUrl);
  274. });
  275. if(fs.config.searchUrl){//触发第一次请求事件
  276. this.triggerSearch(reElem, true);
  277. }
  278. }else{//隐藏第二个dl
  279. reElem.find(`dl dd.${FORM_DL_INPUT}`).css('display', 'none');
  280. }
  281. });
  282. }
  283. Common.prototype.search = function(id, e, searchUrl, call){
  284. let input;
  285. if(call){
  286. input = call;
  287. }else{
  288. input = e.target;
  289. let keyCode = e.keyCode;
  290. if(keyCode === 9 || keyCode === 13 || keyCode === 37 || keyCode === 38 || keyCode === 39 || keyCode === 40) {
  291. return false;
  292. }
  293. }
  294. let inputValue = $.trim(input.value);
  295. //过滤一下tips
  296. this.changePlaceHolder($(input));
  297. let ajaxConfig = ajaxs[id] ? ajaxs[id] : ajax;
  298. searchUrl = ajaxConfig.searchUrl || searchUrl;
  299. let fs = data[id],
  300. isCreate = fs.config.isCreate,
  301. reElem = $(`dl[xid="${id}"]`).parents(`.${FORM_SELECT}`);
  302. //如果开启了远程搜索
  303. if(searchUrl){
  304. if(ajaxConfig.searchVal){
  305. inputValue = ajaxConfig.searchVal;
  306. ajaxConfig.searchVal = '';
  307. }
  308. if(!ajaxConfig.beforeSearch || (ajaxConfig.beforeSearch && ajaxConfig.beforeSearch instanceof Function && ajaxConfig.beforeSearch(id, searchUrl, inputValue))){
  309. let delay = ajaxConfig.delay;
  310. if(ajaxConfig.first){
  311. ajaxConfig.first = false;
  312. delay = 10;
  313. }
  314. clearTimeout(fs.clearid);
  315. fs.clearid = setTimeout(() => {
  316. reElem.find(`dl > *:not(.${FORM_SELECT_TIPS})`).remove();
  317. reElem.find(`dd.${FORM_NONE}`).addClass(FORM_EMPTY).text('请求中');
  318. this.ajax(id, searchUrl, inputValue, false, null, true);
  319. }, delay);
  320. }
  321. }else{
  322. reElem.find(`dl .${DD_HIDE}`).removeClass(DD_HIDE);
  323. //遍历选项, 选择可以显示的值
  324. reElem.find(`dl dd:not(.${FORM_SELECT_TIPS})`).each((idx, item) => {
  325. let _item = $(item);
  326. let searchFun = events.filter[id] || data[id].config.filter;
  327. if(searchFun && searchFun(id, inputValue, this.getItem(id, _item), _item.hasClass(DISABLED)) == true){
  328. _item.addClass(DD_HIDE);
  329. }
  330. });
  331. //控制分组名称
  332. reElem.find('dl dt').each((index, item) => {
  333. if(!$(item).nextUntil('dt', `:not(.${DD_HIDE})`).length) {
  334. $(item).addClass(DD_HIDE);
  335. }
  336. });
  337. //动态创建
  338. this.create(id, isCreate, inputValue);
  339. let shows = reElem.find(`dl dd:not(.${FORM_SELECT_TIPS}):not(.${DD_HIDE})`);
  340. if(!shows.length){
  341. reElem.find(`dd.${FORM_NONE}`).addClass(FORM_EMPTY).text('无匹配项');
  342. }else{
  343. reElem.find(`dd.${FORM_NONE}`).removeClass(FORM_EMPTY);
  344. }
  345. }
  346. }
  347. Common.prototype.isArray = function(obj){
  348. return Object.prototype.toString.call(obj) == "[object Array]";
  349. }
  350. Common.prototype.triggerSearch = function(div, isCall){
  351. (div ? [div] : $(`.${FORM_SELECT}`).toArray()).forEach((reElem, index) => {
  352. reElem = $(reElem);
  353. let id = reElem.find('dl').attr('xid')
  354. if((id && data[id] && data[id].config.isEmpty) || isCall){
  355. this.search(id, null, null, data[id].config.searchType == 0 ? reElem.find(`.${LABEL} .${INPUT}`) : reElem.find(`dl .${FORM_DL_INPUT} .${INPUT}`));
  356. }
  357. });
  358. }
  359. Common.prototype.clearInput = function(id){
  360. let div = $(`.${PNAME}[fs_id="${id}"]`);
  361. let input = data[id].config.searchType == 0 ? div.find(`.${LABEL} .${INPUT}`) : div.find(`dl .${FORM_DL_INPUT} .${INPUT}`);
  362. input.val('');
  363. }
  364. Common.prototype.ajax = function(id, searchUrl, inputValue, isLinkage, linkageWidth, isSearch, successCallback, isReplace){
  365. let reElem = $(`.${PNAME} dl[xid="${id}"]`).parents(`.${FORM_SELECT}`);
  366. if(!reElem[0] || !searchUrl){
  367. return ;
  368. }
  369. let ajaxConfig = ajaxs[id] ? ajaxs[id] : ajax;
  370. let ajaxData = $.extend(true, {}, ajaxConfig.data);
  371. ajaxData[ajaxConfig.searchName] = inputValue;
  372. //是否需要对ajax添加随机时间
  373. //ajaxData['_'] = Date.now();
  374. $.ajax({
  375. type: ajaxConfig.type,
  376. headers: ajaxConfig.header,
  377. url: searchUrl,
  378. data: ajaxConfig.dataType == 'json' ? JSON.stringify(ajaxData) : ajaxData,
  379. success: (res) => {
  380. if(typeof res == 'string'){
  381. res = JSON.parse(res);
  382. }
  383. ajaxConfig.beforeSuccess && ajaxConfig.beforeSuccess instanceof Function && (res = ajaxConfig.beforeSuccess(id, searchUrl, inputValue, res));
  384. if(this.isArray(res)){
  385. let newRes = {};
  386. newRes[ajaxConfig.response.statusName] = ajaxConfig.response.statusCode;
  387. newRes[ajaxConfig.response.msgName] = "";
  388. newRes[ajaxConfig.response.dataName] = res;
  389. res = newRes;
  390. }
  391. if(res[ajaxConfig.response.statusName] != ajaxConfig.response.statusCode) {
  392. reElem.find(`dd.${FORM_NONE}`).addClass(FORM_EMPTY).text(res[ajaxConfig.response.msgName]);
  393. }else{
  394. reElem.find(`dd.${FORM_NONE}`).removeClass(FORM_EMPTY);
  395. this.renderData(id, res[ajaxConfig.response.dataName], isLinkage, linkageWidth, isSearch, isReplace);
  396. data[id].config.isEmpty = res[ajaxConfig.response.dataName].length == 0;
  397. }
  398. successCallback && successCallback(id);
  399. ajaxConfig.success && ajaxConfig.success instanceof Function && ajaxConfig.success(id, searchUrl, inputValue, res);
  400. },
  401. error: (err) => {
  402. reElem.find(`dd[lay-value]:not(.${FORM_SELECT_TIPS})`).remove();
  403. reElem.find(`dd.${FORM_NONE}`).addClass(FORM_EMPTY).text('服务异常');
  404. ajaxConfig.error && ajaxConfig.error instanceof Function && ajaxConfig.error(id, searchUrl, inputValue, err);
  405. }
  406. });
  407. }
  408. Common.prototype.renderData = function(id, dataArr, linkage, linkageWidth, isSearch, isReplace){
  409. if(linkage){//渲染多级联动
  410. this.renderLinkage(id, dataArr, linkageWidth);
  411. return;
  412. }
  413. if(isReplace){
  414. this.renderReplace(id, dataArr);
  415. return;
  416. }
  417. let reElem = $(`.${PNAME} dl[xid="${id}"]`).parents(`.${FORM_SELECT}`);
  418. let ajaxConfig = ajaxs[id] ? ajaxs[id] : ajax;
  419. let pcInput = reElem.find(`.${TDIV} input`);
  420. dataArr = this.exchangeData(id, dataArr);
  421. let values = [];
  422. reElem.find('dl').html(this.renderSelect(id, pcInput.attr('placeholder') || pcInput.attr('back'), dataArr.map((item) => {
  423. let itemVal = $.extend({}, item, {
  424. innerHTML: item[ajaxConfig.keyName],
  425. value: item[ajaxConfig.keyVal],
  426. sel: item[ajaxConfig.keySel],
  427. disabled: item[ajaxConfig.keyDis],
  428. type: item.type,
  429. name: item[ajaxConfig.keyName]
  430. });
  431. if(itemVal.sel){
  432. values.push(itemVal);
  433. }
  434. return itemVal;
  435. })));
  436. let label = reElem.find(`.${LABEL}`);
  437. let dl = reElem.find('dl[xid]');
  438. if(isSearch){//如果是远程搜索, 这里需要判重
  439. let oldVal = data[id].values;
  440. oldVal.forEach((item, index) => {
  441. dl.find(`dd[lay-value="${item.value}"]`).addClass(THIS);
  442. });
  443. values.forEach((item, index) => {
  444. if(this.indexOf(oldVal, item) == -1){
  445. this.addLabel(id, label, item);
  446. dl.find(`dd[lay-value="${item.value}"]`).addClass(THIS);
  447. oldVal.push(item);
  448. }
  449. });
  450. }else{
  451. values.forEach((item, index) => {
  452. this.addLabel(id, label, item);
  453. dl.find(`dd[lay-value="${item.value}"]`).addClass(THIS);
  454. });
  455. data[id].values = values;
  456. }
  457. this.commonHandler(id, label);
  458. }
  459. Common.prototype.renderLinkage = function(id, dataArr, linkageWidth){
  460. let result = [],
  461. index = 0,
  462. temp = {"0": dataArr},
  463. ajaxConfig = ajaxs[id] ? ajaxs[id] : ajax;
  464. db[id] = {};
  465. do{
  466. let group = result[index ++] = [],
  467. _temp = temp;
  468. temp = {};
  469. $.each(_temp, (pid, arr) => {
  470. $.each(arr, (idx, item) => {
  471. let val = {
  472. pid: pid,
  473. name: item[ajaxConfig.keyName],
  474. value: item[ajaxConfig.keyVal],
  475. };
  476. db[id][val.value] = $.extend(item, val);
  477. group.push(val);
  478. let children = item[ajaxConfig.keyChildren];
  479. if(children && children.length){
  480. temp[val.value] = children;
  481. }
  482. });
  483. });
  484. }while(Object.getOwnPropertyNames(temp).length);
  485. let reElem = $(`.${PNAME} dl[xid="${id}"]`).parents(`.${FORM_SELECT}`);
  486. let html = ['<div class="xm-select-linkage">'];
  487. $.each(result, (idx, arr) => {
  488. let groupDiv = [`<div style="left: ${(linkageWidth-0) * idx}px;" class="xm-select-linkage-group xm-select-linkage-group${idx + 1} ${idx != 0 ? 'xm-select-linkage-hide':''}">`];
  489. $.each(arr, (idx2, item) => {
  490. let span = `<li title="${item.name}" pid="${item.pid}" xm-value="${item.value}"><span>${item.name}</span></li>`;
  491. groupDiv.push(span);
  492. });
  493. groupDiv.push(`</div>`);
  494. html = html.concat(groupDiv);
  495. });
  496. html.push('<div style="clear: both; height: 288px;"></div>');
  497. html.push('</div>');
  498. reElem.find('dl').html(html.join(''));
  499. reElem.find(`.${INPUT}`).css('display', 'none');//联动暂时不支持搜索
  500. }
  501. Common.prototype.renderReplace = function(id, dataArr){
  502. let dl = $(`.${PNAME} dl[xid="${id}"]`);
  503. let ajaxConfig = ajaxs[id] ? ajaxs[id] : ajax;
  504. dataArr = this.exchangeData(id, dataArr);
  505. db[id] = dataArr;
  506. let html = dataArr.map((item) => {
  507. let itemVal = $.extend({}, item, {
  508. innerHTML: item[ajaxConfig.keyName],
  509. value: item[ajaxConfig.keyVal],
  510. sel: item[ajaxConfig.keySel],
  511. disabled: item[ajaxConfig.keyDis],
  512. type: item.type,
  513. name: item[ajaxConfig.keyName]
  514. });
  515. return this.createDD(id, itemVal);
  516. }).join('');
  517. dl.find(`dd:not(.${FORM_SELECT_TIPS}),dt:not([style])`).remove();
  518. dl.find(`dt[style]`).after($(html));
  519. }
  520. Common.prototype.exchangeData = function(id, arr){//这里处理树形结构
  521. let ajaxConfig = ajaxs[id] ? ajaxs[id] : ajax;
  522. let childrenName = ajaxConfig['keyChildren'];
  523. let disabledName = ajaxConfig['keyDis'];
  524. db[id] = {};
  525. let result = this.getChildrenList(arr, childrenName, disabledName, [], false);
  526. return result;
  527. }
  528. Common.prototype.getChildrenList = function(arr, childrenName, disabledName, pid, disabled){
  529. let result = [], offset = 0;
  530. for(let a = 0; a < arr.length; a ++){
  531. let item = arr[a];
  532. if(item.type && item.type == 'optgroup'){
  533. result.push(item);
  534. continue;
  535. }else{
  536. offset ++;
  537. }
  538. let parentIds = pid.concat([]);
  539. parentIds.push(`${offset - 1}_E`);
  540. item[FORM_TEAM_PID] = JSON.stringify(parentIds);
  541. item[disabledName] = item[disabledName] || disabled;
  542. result.push(item);
  543. let child = item[childrenName];
  544. if(child && common.isArray(child) && child.length){
  545. item['XM_TREE_FOLDER'] = true;
  546. let pidArr = parentIds.concat([]);
  547. let childResult = this.getChildrenList(child, childrenName, disabledName, pidArr, item[disabledName]);
  548. result = result.concat(childResult);
  549. }
  550. }
  551. return result;
  552. }
  553. Common.prototype.create = function(id, isCreate, inputValue){
  554. if(isCreate && inputValue){
  555. let fs = data[id],
  556. dl = $(`[xid="${id}"]`),
  557. tips= dl.find(`dd.${FORM_SELECT_TIPS}.${FORM_DL_INPUT}`),
  558. tdd = null,
  559. temp = dl.find(`dd.${TEMP}`);
  560. dl.find(`dd:not(.${FORM_SELECT_TIPS}):not(.${TEMP})`).each((index, item) => {
  561. if(inputValue == $(item).find('span').attr('name')){
  562. tdd = item;
  563. }
  564. });
  565. if(!tdd){//如果不存在, 则创建
  566. let val = fs.config.create(id, inputValue);
  567. if(temp[0]){
  568. temp.attr('lay-value', val);
  569. temp.find('span').text(inputValue);
  570. temp.find('span').attr("name", inputValue);
  571. temp.removeClass(DD_HIDE);
  572. }else{
  573. tips.after($(this.createDD(id, {
  574. name: inputValue,
  575. innerHTML: inputValue,
  576. value: val
  577. }, `${TEMP} ${CREATE_LONG}`)));
  578. }
  579. }
  580. }else{
  581. $(`[xid=${id}] dd.${TEMP}`).remove();
  582. }
  583. }
  584. Common.prototype.createDD = function(id, item, clz){
  585. let ajaxConfig = ajaxs[id] ? ajaxs[id] : ajax;
  586. let name = $.trim(item.innerHTML);
  587. db[id][item.value] = $(item).is('option') ? (item = function(){
  588. let resultItem = {};
  589. resultItem[ajaxConfig.keyName] = name;
  590. resultItem[ajaxConfig.keyVal] = item.value;
  591. resultItem[ajaxConfig.keyDis] = item.disabled;
  592. return resultItem;
  593. }()) : item;
  594. let template = data[id].config.template(id, item);
  595. let pid = item[FORM_TEAM_PID];
  596. pid ? (pid = JSON.parse(pid)) : (pid = [-1]);
  597. let attr = pid[0] == -1 ? '' : `tree-id="${pid.join('-')}" tree-folder="${!!item['XM_TREE_FOLDER']}"`;
  598. return `<dd lay-value="${item.value}" class="${item.disabled ? DISABLED : ''} ${clz ? clz : ''}" ${attr}>
  599. <div class="xm-unselect xm-form-checkbox ${item.disabled ? DISABLED : ''}" style="margin-left: ${(pid.length - 1) * 30}px">
  600. <i class="${CHECKBOX_YES}"></i>
  601. <span name="${name}">${template}</span>
  602. </div>
  603. </dd>`;
  604. }
  605. Common.prototype.createQuickBtn = function(obj, right){
  606. return `<div class="${CZ}" method="${obj.name}" title="${obj.name}" ${right ? 'style="margin-right: ' + right + '"': ''}><i class="${obj.icon}"></i><span>${obj.name}</span></div>`
  607. }
  608. Common.prototype.renderBtns = function(id, show, right){
  609. let quickBtn = [];
  610. let dl = $(`dl[xid="${id}"]`);
  611. quickBtn.push(`<div class="${CZ_GROUP}" show="${show}" style="max-width: ${dl.prev().width() - 54}px;">`);
  612. $.each(data[id].config.btns, (index, item) => {
  613. quickBtn.push(this.createQuickBtn(item, right));
  614. });
  615. quickBtn.push(`</div>`);
  616. quickBtn.push(this.createQuickBtn({icon: 'xm-iconfont icon-caidan', name: ''}));
  617. return quickBtn.join('');
  618. }
  619. Common.prototype.renderSelect = function(id, tips, select){
  620. db[id] = {};
  621. let arr = [];
  622. if(data[id].config.btns.length){
  623. setTimeout(() => {
  624. let dl = $(`dl[xid="${id}"]`);
  625. dl.parents(`.${FORM_SELECT}`).attr(SEARCH_TYPE, data[id].config.searchType);
  626. dl.find(`.${CZ_GROUP}`).css('max-width', `${dl.prev().width() - 54}px`);
  627. }, 10)
  628. arr.push([
  629. `<dd lay-value="" class="${FORM_SELECT_TIPS}" style="background-color: #FFF!important;">`,
  630. this.renderBtns(id, null, '30px'),
  631. `</dd>`,
  632. `<dd lay-value="" class="${FORM_SELECT_TIPS} ${FORM_DL_INPUT}" style="background-color: #FFF!important;">`,
  633. `<i class="xm-iconfont icon-sousuo"></i>`,
  634. `<input type="text" class="${FORM_INPUT} ${INPUT}" placeholder="请搜索"/>`,
  635. `</dd>`
  636. ].join(''));
  637. }else{
  638. arr.push(`<dd lay-value="" class="${FORM_SELECT_TIPS}">${tips}</dd>`);
  639. }
  640. if(this.isArray(select)){
  641. $(select).each((index, item) => {
  642. if(item){
  643. if(item.type && item.type === 'optgroup') {
  644. arr.push(`<dt>${item.name}</dt>`);
  645. } else {
  646. arr.push(this.createDD(id, item));
  647. }
  648. }
  649. });
  650. }else{
  651. $(select).find('*').each((index, item) => {
  652. if(item.tagName.toLowerCase() == 'option' && index == 0 && !item.value){
  653. return ;
  654. }
  655. if(item.tagName.toLowerCase() === 'optgroup') {
  656. arr.push(`<dt>${item.label}</dt>`);
  657. } else {
  658. arr.push(this.createDD(id, item));
  659. }
  660. });
  661. }
  662. arr.push('<dt style="display:none;"> </dt>');
  663. arr.push(`<dd class="${FORM_SELECT_TIPS} ${FORM_NONE} ${arr.length === 2 ? FORM_EMPTY:''}">没有选项</dd>`);
  664. return arr.join('');
  665. }
  666. Common.prototype.on = function(){//事件绑定
  667. this.one();
  668. $(document).on('click', (e) => {
  669. if(!$(e.target).parents(`.${FORM_TITLE}`)[0]){//清空input中的值
  670. $(`.${PNAME} dl .${DD_HIDE}`).removeClass(DD_HIDE);
  671. $(`.${PNAME} dl dd.${FORM_EMPTY}`).removeClass(FORM_EMPTY);
  672. $(`.${PNAME} dl dd.${TEMP}`).remove();
  673. $.each(data, (key, fs) => {
  674. this.clearInput(key);
  675. if(!fs.values.length){
  676. this.changePlaceHolder($(`div[FS_ID="${key}"] .${LABEL}`));
  677. }
  678. });
  679. }
  680. $(`.${PNAME} .${FORM_SELECTED}`).each((index, item) => {
  681. this.changeShow($(item).find(`.${FORM_TITLE}`), false);
  682. }) ;
  683. });
  684. }
  685. Common.prototype.calcLabelLeft = function(label, w, call){
  686. let pos = this.getPosition(label[0]);
  687. pos.y = pos.x + label[0].clientWidth;
  688. let left = label[0].offsetLeft;
  689. if(!label.find('span').length){
  690. left = 0;
  691. }else if(call){//校正归位
  692. let span = label.find('span:last');
  693. span.css('display') == 'none' ? (span = span.prev()[0]) : (span = span[0]);
  694. let spos = this.getPosition(span);
  695. spos.y = spos.x + span.clientWidth;
  696. if(spos.y > pos.y){
  697. left = left - (spos.y - pos.y) - 5;
  698. }else{
  699. left = 0;
  700. }
  701. }else{
  702. if(w < 0){
  703. let span = label.find(':last');
  704. span.css('display') == 'none' ? (span = span.prev()[0]) : (span = span[0]);
  705. let spos = this.getPosition(span);
  706. spos.y = spos.x + span.clientWidth;
  707. if(spos.y > pos.y){
  708. left -= 10;
  709. }
  710. }else{
  711. if(left < 0){
  712. left += 10;
  713. }
  714. if(left > 0){
  715. left = 0;
  716. }
  717. }
  718. }
  719. label.css('left', left + 'px');
  720. }
  721. Common.prototype.one = function(target){//一次性事件绑定
  722. $(target ? target : document).off('click', `.${FORM_TITLE}`).on('click', `.${FORM_TITLE}`, (e) => {
  723. let othis = $(e.target),
  724. title = othis.is(FORM_TITLE) ? othis : othis.parents(`.${FORM_TITLE}`),
  725. dl = title.next(),
  726. id = dl.attr('xid');
  727. //清空非本select的input val
  728. $(`dl[xid]`).not(dl).each((index, item) => {
  729. this.clearInput($(item).attr('xid'));
  730. });
  731. $(`dl[xid]`).not(dl).find(`dd.${DD_HIDE}`).removeClass(DD_HIDE);
  732. //如果是disabled select
  733. if(title.hasClass(DIS)){
  734. return false;
  735. }
  736. //如果点击的是右边的三角或者只读的input
  737. if(othis.is(`.${SANJIAO}`) || othis.is(`.${INPUT}[readonly]`)){
  738. this.changeShow(title, !title.parents(`.${FORM_SELECT}`).hasClass(FORM_SELECTED));
  739. return false;
  740. }
  741. //如果点击的是input的右边, focus一下
  742. if(title.find(`.${INPUT}:not(readonly)`)[0]){
  743. let input = title.find(`.${INPUT}`),
  744. epos = {x: e.pageX, y: e.pageY},
  745. pos = this.getPosition(title[0]),
  746. width = title.width();
  747. while(epos.x > pos.x){
  748. if($(document.elementFromPoint(epos.x, epos.y)).is(input)){
  749. input.focus();
  750. this.changeShow(title, true);
  751. return false;
  752. }
  753. epos.x -= 50;
  754. }
  755. }
  756. //如果点击的是可搜索的input
  757. if(othis.is(`.${INPUT}`)){
  758. this.changeShow(title, true);
  759. return false;
  760. }
  761. //如果点击的是x按钮
  762. if(othis.is(`i[fsw="${NAME}"]`)){
  763. let val = this.getItem(id, othis),
  764. dd = dl.find(`dd[lay-value='${val.value}']`);
  765. if(dd.hasClass(DISABLED)){//如果是disabled状态, 不可选, 不可删
  766. return false;
  767. }
  768. this.handlerLabel(id, dd, false, val);
  769. return false;
  770. }
  771. this.changeShow(title, !title.parents(`.${FORM_SELECT}`).hasClass(FORM_SELECTED));
  772. return false;
  773. });
  774. $(target ? target : document).off('click', `dl.${DL}`).on('click', `dl.${DL}`, (e) => {
  775. let othis = $(e.target);
  776. if(othis.is(`.${LINKAGE}`) || othis.parents(`.${LINKAGE}`)[0]){//linkage的处理
  777. othis = othis.is('li') ? othis : othis.parents('li[xm-value]');
  778. let group = othis.parents('.xm-select-linkage-group'),
  779. id = othis.parents('dl').attr('xid');
  780. if(!id){
  781. return false;
  782. }
  783. //激活li
  784. group.find('.xm-select-active').removeClass('xm-select-active');
  785. othis.addClass('xm-select-active');
  786. //激活下一个group, 激活前显示对应数据
  787. group.nextAll('.xm-select-linkage-group').addClass('xm-select-linkage-hide');
  788. let nextGroup = group.next('.xm-select-linkage-group');
  789. nextGroup.find('li').addClass('xm-select-linkage-hide');
  790. nextGroup.find(`li[pid="${othis.attr('xm-value')}"]`).removeClass('xm-select-linkage-hide');
  791. //如果没有下一个group, 或没有对应的值
  792. if(!nextGroup[0] || nextGroup.find(`li:not(.xm-select-linkage-hide)`).length == 0){
  793. let vals = [],
  794. index = 0,
  795. isAdd = !othis.hasClass('xm-select-this');
  796. if(data[id].config.radio){
  797. othis.parents('.xm-select-linkage').find('.xm-select-this').removeClass('xm-select-this');
  798. }
  799. do{
  800. vals[index ++] = {
  801. name: othis.find('span').text(),
  802. value: othis.attr('xm-value')
  803. }
  804. othis = othis.parents('.xm-select-linkage-group').prev().find(`li[xm-value="${othis.attr('pid')}"]`);
  805. }while(othis.length);
  806. vals.reverse();
  807. let val = {
  808. name: vals.map((item) => {
  809. return item.name;
  810. }).join('/'),
  811. value: vals.map((item) => {
  812. return item.value;
  813. }).join('/'),
  814. }
  815. this.handlerLabel(id, null, isAdd, val);
  816. }else{
  817. nextGroup.removeClass('xm-select-linkage-hide');
  818. }
  819. return false;
  820. }
  821. if(othis.is('dl')){
  822. return false;
  823. }
  824. if(othis.is('dt')){
  825. othis.nextUntil(`dt`).each((index, item) => {
  826. item = $(item);
  827. if(item.hasClass(DISABLED) || item.hasClass(THIS)){
  828. }else{
  829. item.find('i:not(.icon-expand)').click();
  830. }
  831. });
  832. return false;
  833. }
  834. let dd = othis.is('dd') ? othis : othis.parents('dd');
  835. let id = dd.parent('dl').attr('xid');
  836. if(dd.hasClass(DISABLED)){//被禁用选项的处理
  837. return false;
  838. }
  839. //菜单功效
  840. if(othis.is('i.icon-caidan')){
  841. let opens = [], closes = [];
  842. othis.parents('dl').find('dd[tree-folder="true"]').each((index, item) => {
  843. $(item).attr('xm-tree-hidn') == undefined ? opens.push(item) : closes.push(item);
  844. });
  845. let arr = closes.length ? closes : opens;
  846. arr.forEach(item => item.click());
  847. return false;
  848. }
  849. //树状结构的选择
  850. let treeId = dd.attr('tree-id');
  851. if(treeId){
  852. //忽略右边的图标
  853. if(othis.is('i:not(.icon-expand)')){
  854. this.handlerLabel(id, dd, !dd.hasClass(THIS));
  855. return false;
  856. }
  857. let ajaxConfig = ajaxs[id] || ajax;
  858. let treeConfig = ajaxConfig.tree;
  859. let childrens = dd.nextAll(`dd[tree-id^="${treeId}"]`);
  860. if(childrens && childrens.length){
  861. let len = childrens[0].clientHeight;
  862. len ? (
  863. this.addTreeHeight(dd, len),
  864. len = 0
  865. ) : (
  866. len = dd.attr('xm-tree-hidn') || 36,
  867. dd.removeAttr('xm-tree-hidn'),
  868. dd.find('>i').remove(),
  869. (childrens = childrens.filter((index, item) => $(item).attr('tree-id').split('-').length - 1 == treeId.split('-').length))
  870. );
  871. childrens.animate({
  872. height: len
  873. }, 150)
  874. return false;
  875. }else{
  876. if(treeConfig.nextClick && treeConfig.nextClick instanceof Function){
  877. treeConfig.nextClick(id, this.getItem(id, dd), (res) => {
  878. if(!res || !res.length){
  879. this.handlerLabel(id, dd, !dd.hasClass(THIS));
  880. }else{
  881. dd.attr('tree-folder', 'true');
  882. let ddChilds = [];
  883. res.forEach((item, idx) => {
  884. item.innerHTML = item[ajaxConfig.keyName];
  885. item[FORM_TEAM_PID] = JSON.stringify(treeId.split('-').concat([idx]));
  886. ddChilds.push(this.createDD(id, item));
  887. db[id][item[ajaxConfig.keyVal]] = item;
  888. });
  889. dd.after(ddChilds.join(''));
  890. }
  891. });
  892. return false;
  893. }
  894. }
  895. }
  896. if(dd.hasClass(FORM_SELECT_TIPS)){//tips的处理
  897. let btn = othis.is(`.${CZ}`) ? othis : othis.parents(`.${CZ}`);
  898. if(!btn[0]){
  899. return false;
  900. }
  901. let method = btn.attr('method');
  902. let obj = data[id].config.btns.filter(bean => bean.name == method)[0];
  903. obj && obj.click && obj.click instanceof Function && obj.click(id, this);
  904. return false;
  905. }
  906. this.handlerLabel(id, dd, !dd.hasClass(THIS));
  907. return false;
  908. });
  909. }
  910. Common.prototype.addTreeHeight = function(dd, len){
  911. let treeId = dd.attr('tree-id');
  912. let childrens = dd.nextAll(`dd[tree-id^="${treeId}"]`);
  913. if(childrens.length){
  914. dd.append('<i class="xm-iconfont icon-expand"></i>');
  915. dd.attr('xm-tree-hidn', len);
  916. childrens.each((index, item) => {
  917. let that = $(item);
  918. this.addTreeHeight(that, len);
  919. })
  920. }
  921. }
  922. let db = {};
  923. Common.prototype.getItem = function(id, value){
  924. if(value instanceof $){
  925. if(value.is(`i[fsw="${NAME}"]`)){
  926. let span = value.parent();
  927. return db[id][value] || {
  928. name: span.find('font').text(),
  929. value: span.attr('value')
  930. }
  931. }
  932. let val = value.attr('lay-value');
  933. return !db[id][val] ? (db[id][val] = {
  934. name: value.find('span[name]').attr('name'),
  935. value: val
  936. }) : db[id][val];
  937. }else if(typeof(value) == 'string' && value.indexOf('/') != -1){
  938. return db[id][value] || {
  939. name: this.valToName(id, value),
  940. value: value
  941. }
  942. }
  943. return db[id][value];
  944. }
  945. Common.prototype.linkageAdd = function(id, val){
  946. let dl = $(`dl[xid="${id}"]`);
  947. dl.find('.xm-select-active').removeClass('xm-select-active');
  948. let vs = val.value.split('/');
  949. let pid, li, index = 0;
  950. let lis = [];
  951. do{
  952. pid = vs[index];
  953. li = dl.find(`.xm-select-linkage-group${index + 1} li[xm-value="${pid}"]`);
  954. li[0] && lis.push(li);
  955. index ++;
  956. }while(li.length && pid != undefined);
  957. if(lis.length == vs.length){
  958. $.each(lis, (idx, item) => {
  959. item.addClass('xm-select-this');
  960. });
  961. }
  962. }
  963. Common.prototype.linkageDel = function(id, val){
  964. let dl = $(`dl[xid="${id}"]`);
  965. let vs = val.value.split('/');
  966. let pid, li, index = vs.length - 1;
  967. do{
  968. pid = vs[index];
  969. li = dl.find(`.xm-select-linkage-group${index + 1} li[xm-value="${pid}"]`);
  970. if(!li.parent().next().find(`li[pid=${pid}].xm-select-this`).length){
  971. li.removeClass('xm-select-this');
  972. }
  973. index --;
  974. }while(li.length && pid != undefined);
  975. }
  976. Common.prototype.valToName = function(id, val){
  977. let dl = $(`dl[xid="${id}"]`);
  978. let vs = (val + "").split('/');
  979. if(!vs.length){
  980. return null;
  981. }
  982. let names = [];
  983. $.each(vs, (idx, item) => {
  984. let name = dl.find(`.xm-select-linkage-group${idx + 1} li[xm-value="${item}"] span`).text();
  985. names.push(name);
  986. });
  987. return names.length == vs.length ? names.join('/') : null;
  988. }
  989. Common.prototype.commonHandler = function(key, label){
  990. if(!label || !label[0]){
  991. return ;
  992. }
  993. this.checkHideSpan(key, label);
  994. //计算input的提示语
  995. this.changePlaceHolder(label);
  996. //计算高度
  997. this.retop(label.parents(`.${FORM_SELECT}`));
  998. this.calcLabelLeft(label, 0, true);
  999. //表单默认值
  1000. this.setHidnVal(key, label);
  1001. //title值
  1002. label.parents(`.${FORM_TITLE} .${NAME}`).attr('title', data[key].values.map((val) => {
  1003. return val.name;
  1004. }).join(','));
  1005. }
  1006. Common.prototype.initVal = function(id){
  1007. let target = {};
  1008. if(id){
  1009. target[id] = data[id];
  1010. }else{
  1011. target = data;
  1012. }
  1013. $.each(target, (key, val) => {
  1014. let values = val.values,
  1015. div = $(`dl[xid="${key}"]`).parent(),
  1016. label = div.find(`.${LABEL}`),
  1017. dl = div.find('dl');
  1018. dl.find(`dd.${THIS}`).removeClass(THIS);
  1019. let _vals = values.concat([]);
  1020. _vals.concat([]).forEach((item, index) => {
  1021. this.addLabel(key, label, item);
  1022. dl.find(`dd[lay-value="${item.value}"]`).addClass(THIS);
  1023. });
  1024. if(val.config.radio){
  1025. _vals.length && values.push(_vals[_vals.length - 1]);
  1026. }
  1027. this.commonHandler(key, label);
  1028. });
  1029. }
  1030. Common.prototype.setHidnVal = function(key, label) {
  1031. if(!label || !label[0]) {
  1032. return;
  1033. }
  1034. label.parents(`.${PNAME}`).find(`.${HIDE_INPUT}`).val(data[key].values.map((val) => {
  1035. return val.value;
  1036. }).join(','));
  1037. }
  1038. Common.prototype.handlerLabel = function(id, dd, isAdd, oval, notOn){
  1039. let div = $(`[xid="${id}"]`).prev().find(`.${LABEL}`),
  1040. val = dd && this.getItem(id, dd),
  1041. vals = data[id].values,
  1042. on = data[id].config.on || events.on[id],
  1043. endOn = data[id].config.endOn || events.endOn[id];
  1044. if(oval){
  1045. val = oval;
  1046. }
  1047. let fs = data[id];
  1048. if(isAdd && fs.config.max && fs.values.length >= fs.config.max){
  1049. let maxTipsFun = events.maxTips[id] || data[id].config.maxTips;
  1050. maxTipsFun && maxTipsFun(id, vals.concat([]), val, fs.config.max);
  1051. return ;
  1052. }
  1053. if(!notOn){
  1054. if(on && on instanceof Function && on(id, vals.concat([]), val, isAdd, dd && dd.hasClass(DISABLED)) == false) {
  1055. return ;
  1056. }
  1057. }
  1058. let dl = $(`dl[xid="${id}"]`);
  1059. isAdd ? (
  1060. (dd && dd[0] ? (
  1061. dd.addClass(THIS),
  1062. dd.removeClass(TEMP)
  1063. ) : (
  1064. dl.find('.xm-select-linkage')[0] && this.linkageAdd(id, val)
  1065. )),
  1066. this.addLabel(id, div, val),
  1067. vals.push(val)
  1068. ) : (
  1069. (dd && dd[0] ? (
  1070. dd.removeClass(THIS)
  1071. ) : (
  1072. dl.find('.xm-select-linkage')[0] && this.linkageDel(id, val)
  1073. )),
  1074. this.delLabel(id, div, val),
  1075. this.remove(vals, val)
  1076. );
  1077. if(!div[0]) return ;
  1078. //单选选完后直接关闭选择域
  1079. if(fs.config.radio){
  1080. this.changeShow(div, false);
  1081. }
  1082. //移除表单验证的红色边框
  1083. div.parents(`.${FORM_TITLE}`).prev().removeClass('layui-form-danger');
  1084. //清空搜索值
  1085. fs.config.clearInput && this.clearInput(id);
  1086. this.commonHandler(id, div);
  1087. !notOn && endOn && endOn instanceof Function && endOn(id, vals.concat([]), val, isAdd, dd && dd.hasClass(DISABLED));
  1088. }
  1089. Common.prototype.addLabel = function(id, div, val){
  1090. if(!val) return ;
  1091. let tips = `fsw="${NAME}"`;
  1092. let [$label, $close] = [
  1093. $(`<span ${tips} value="${val.value}"><font ${tips}>${val.name}</font></span>`),
  1094. $(`<i ${tips} class="xm-iconfont icon-close"></i>`)
  1095. ];
  1096. $label.append($close);
  1097. //如果是radio模式
  1098. let fs = data[id];
  1099. if(fs.config.radio){
  1100. fs.values.length = 0;
  1101. $(`dl[xid="${id}"]`).find(`dd.${THIS}:not([lay-value="${val.value}"])`).removeClass(THIS);
  1102. div.find('span').remove();
  1103. }
  1104. //如果是固定高度
  1105. div.find('input').css('width', '50px');
  1106. div.find('input').before($label);
  1107. }
  1108. Common.prototype.delLabel = function(id, div, val){
  1109. if(!val) return ;
  1110. div.find(`span[value="${val.value}"]:first`).remove();
  1111. }
  1112. Common.prototype.checkHideSpan = function(id, div){
  1113. let parentHeight = div.parents(`.${NAME}`)[0].offsetHeight + 5;
  1114. div.find('span.xm-span-hide').removeClass('xm-span-hide');
  1115. div.find('span[style]').remove();
  1116. let count = data[id].config.showCount;
  1117. div.find('span').each((index, item) => {
  1118. if(index >= count){
  1119. $(item).addClass('xm-span-hide');
  1120. }
  1121. });
  1122. let prefix = div.find(`span:eq(${count})`);
  1123. prefix[0] && prefix.before($(`<span style="padding-right: 6px;" fsw="${NAME}"> + ${div.find('span').length - count}</span>`))
  1124. }
  1125. Common.prototype.retop = function(div){//计算dl显示的位置
  1126. let dl = div.find('dl'),
  1127. top = div.offset().top + div.outerHeight() + 5 - $win.scrollTop(),
  1128. dlHeight = dl.outerHeight();
  1129. let up = div.hasClass('layui-form-selectup') || dl.css('top').indexOf('-') != -1 || (top + dlHeight > $win.height() && top >= dlHeight);
  1130. div = div.find(`.${NAME}`);
  1131. let fs = data[dl.attr('xid')];
  1132. let base = dl.parents('.layui-form-pane')[0] && dl.prev()[0].clientHeight > 38 ? 14 : 10;
  1133. if((fs && fs.config.direction == 'up') || up){
  1134. up = true;
  1135. if((fs && fs.config.direction == 'down')){
  1136. up = false;
  1137. }
  1138. }
  1139. let reHeight = div[0].offsetTop + div.height() + base;
  1140. if(up) {
  1141. dl.css({
  1142. top: 'auto',
  1143. bottom: reHeight + 3 + 'px',
  1144. });
  1145. } else {
  1146. dl.css({
  1147. top: reHeight + 'px',
  1148. bottom: 'auto'
  1149. });
  1150. }
  1151. }
  1152. Common.prototype.changeShow = function(children, isShow){//显示于隐藏
  1153. $('.layui-form-selected').removeClass('layui-form-selected');
  1154. let top = children.parents(`.${FORM_SELECT}`),
  1155. realShow = top.hasClass(FORM_SELECTED),
  1156. id = top.find('dl').attr('xid');
  1157. $(`.${PNAME} .${FORM_SELECT}`).not(top).removeClass(FORM_SELECTED);
  1158. if(isShow){
  1159. this.retop(top);
  1160. top.addClass(FORM_SELECTED);
  1161. top.find(`.${INPUT}`).focus();
  1162. if(!top.find(`dl dd[lay-value]:not(.${FORM_SELECT_TIPS})`).length){
  1163. top.find(`dl .${FORM_NONE}`).addClass(FORM_EMPTY);
  1164. }
  1165. }else{
  1166. top.removeClass(FORM_SELECTED);
  1167. this.clearInput(id);
  1168. top.find(`dl .${FORM_EMPTY}`).removeClass(FORM_EMPTY);
  1169. top.find(`dl dd.${DD_HIDE}`).removeClass(DD_HIDE);
  1170. top.find(`dl dd.${TEMP}`).remove();
  1171. //计算ajax数据是否为空, 然后重新请求数据
  1172. if(id && data[id] && data[id].config.isEmpty){
  1173. this.triggerSearch(top);
  1174. }
  1175. this.changePlaceHolder(top.find(`.${LABEL}`));
  1176. }
  1177. if(isShow != realShow){
  1178. let openFun = data[id].config.opened || events.opened[id];
  1179. isShow && openFun && openFun instanceof Function && openFun(id);
  1180. let closeFun = data[id].config.closed || events.closed[id];
  1181. !isShow && closeFun && closeFun instanceof Function && closeFun(id);
  1182. }
  1183. }
  1184. Common.prototype.changePlaceHolder = function(div){//显示于隐藏提示语
  1185. //调整pane模式下的高度
  1186. let title = div.parents(`.${FORM_TITLE}`);
  1187. title[0] || (title = div.parents(`dl`).prev());
  1188. if(!title[0]){
  1189. return ;
  1190. }
  1191. let id = div.parents(`.${PNAME}`).find(`dl[xid]`).attr('xid');
  1192. if(data[id] && data[id].config.height){//既然固定高度了, 那就看着办吧
  1193. }else{
  1194. let height = title.find(`.${NAME}`)[0].clientHeight;
  1195. title.css('height' , (height > 36 ? height + 4 : height) + 'px');
  1196. //如果是layui pane模式, 处理label的高度
  1197. let label = title.parents(`.${PNAME}`).parent().prev();
  1198. if(label.is('.layui-form-label') && title.parents('.layui-form-pane')[0]){
  1199. height = height > 36 ? height + 4 : height;
  1200. title.css('height' , height + 'px');
  1201. label.css({
  1202. height: height + 2 + 'px',
  1203. lineHeight: (height - 18) + 'px'
  1204. })
  1205. }
  1206. }
  1207. let input = title.find(`.${TDIV} input`),
  1208. isShow = !div.find('span:last')[0] && !title.find(`.${INPUT}`).val();
  1209. if(isShow){
  1210. let ph = input.attr('back');
  1211. input.removeAttr('back');
  1212. input.attr('placeholder', ph);
  1213. }else{
  1214. let ph = input.attr('placeholder');
  1215. input.removeAttr('placeholder');
  1216. input.attr('back', ph)
  1217. }
  1218. }
  1219. Common.prototype.indexOf = function(arr, val){
  1220. for(let i = 0; i < arr.length; i++) {
  1221. if(arr[i].value == val || arr[i].value == (val ? val.value : val) || arr[i] == val || JSON.stringify(arr[i]) == JSON.stringify(val)) {
  1222. return i;
  1223. }
  1224. }
  1225. return -1;
  1226. }
  1227. Common.prototype.remove = function(arr, val){
  1228. let idx = this.indexOf(arr, val ? val.value : val);
  1229. if(idx > -1) {
  1230. arr.splice(idx, 1);
  1231. return true;
  1232. }
  1233. return false;
  1234. }
  1235. Common.prototype.selectAll = function(id, isOn, skipDis){
  1236. let dl = $(`[xid="${id}"]`);
  1237. if(!dl[0]){
  1238. return ;
  1239. }
  1240. if(dl.find('.xm-select-linkage')[0]){
  1241. return ;
  1242. }
  1243. dl.find(`dd[lay-value]:not(.${FORM_SELECT_TIPS}):not(.${THIS})${skipDis ? ':not(.'+DISABLED+')' :''}`).each((index, item) => {
  1244. item = $(item);
  1245. let val = this.getItem(id, item);
  1246. this.handlerLabel(id, dl.find(`dd[lay-value="${val.value}"]`), true, val, !isOn);
  1247. });
  1248. }
  1249. Common.prototype.removeAll = function(id, isOn, skipDis){
  1250. let dl = $(`[xid="${id}"]`);
  1251. if(!dl[0]){
  1252. return ;
  1253. }
  1254. if(dl.find('.xm-select-linkage')[0]){//针对多级联动的处理
  1255. data[id].values.concat([]).forEach((item, idx) => {
  1256. let vs = item.value.split('/');
  1257. let pid, li, index = 0;
  1258. do{
  1259. pid = vs[index ++];
  1260. li = dl.find(`.xm-select-linkage-group${index}:not(.xm-select-linkage-hide) li[xm-value="${pid}"]`);
  1261. li.click();
  1262. }while(li.length && pid != undefined);
  1263. });
  1264. return ;
  1265. }
  1266. data[id].values.concat([]).forEach((item, index) => {
  1267. if(skipDis && dl.find(`dd[lay-value="${item.value}"]`).hasClass(DISABLED)){
  1268. }else{
  1269. this.handlerLabel(id, dl.find(`dd[lay-value="${item.value}"]`), false, item, !isOn);
  1270. }
  1271. });
  1272. }
  1273. Common.prototype.reverse = function(id, isOn, skipDis){
  1274. let dl = $(`[xid="${id}"]`);
  1275. if(!dl[0]){
  1276. return ;
  1277. }
  1278. if(dl.find('.xm-select-linkage')[0]){
  1279. return ;
  1280. }
  1281. dl.find(`dd[lay-value]:not(.${FORM_SELECT_TIPS})${skipDis ? ':not(.'+DISABLED+')' :''}`).each((index, item) => {
  1282. item = $(item);
  1283. let val = this.getItem(id, item);
  1284. this.handlerLabel(id, dl.find(`dd[lay-value="${val.value}"]`), !item.hasClass(THIS), val, !isOn);
  1285. });
  1286. }
  1287. Common.prototype.skin = function(id){
  1288. let skins = ['default' ,'primary', 'normal', 'warm', 'danger'];
  1289. let skin = skins[Math.floor(Math.random() * skins.length)];
  1290. $(`dl[xid="${id}"]`).parents(`.${PNAME}`).find(`.${FORM_SELECT}`).attr('xm-select-skin', skin);
  1291. this.check(id) && this.commonHandler(id, $(`dl[xid="${id}"]`).parents(`.${PNAME}`).find(`.${LABEL}`));
  1292. }
  1293. Common.prototype.getPosition = function(e){
  1294. let x = 0, y = 0;
  1295. while (e != null) {
  1296. x += e.offsetLeft;
  1297. y += e.offsetTop;
  1298. e = e.offsetParent;
  1299. }
  1300. return { x: x, y: y };
  1301. };
  1302. Common.prototype.onreset = function(){//监听reset按钮, 然后重置多选
  1303. $(document).on('click', '[type=reset]', (e) => {
  1304. $(e.target).parents('form').find(`.${PNAME} dl[xid]`).each((index, item) => {
  1305. let id = item.getAttribute('xid'),
  1306. dl = $(item),
  1307. dd,
  1308. temp = {};
  1309. common.removeAll(id);
  1310. data[id].config.init.forEach((val, idx) => {
  1311. if(val && (!temp[val] || data[id].config.repeat) && (dd = dl.find(`dd[lay-value="${val.value}"]`))[0]){
  1312. common.handlerLabel(id, dd, true);
  1313. temp[val] = 1;
  1314. }
  1315. });
  1316. })
  1317. });
  1318. }
  1319. Common.prototype.bindEvent = function(name, id, fun){
  1320. if(id && id instanceof Function){
  1321. fun = id;
  1322. id = null;
  1323. }
  1324. if(fun && fun instanceof Function){
  1325. if(!id){
  1326. $.each(data, (id, val) => {
  1327. data[id] ? (data[id].config[name] = fun) : (events[name][id] = fun)
  1328. })
  1329. }else{
  1330. data[id] ? (data[id].config[name] = fun, delete events[name][id]) : (events[name][id] = fun)
  1331. }
  1332. }
  1333. }
  1334. Common.prototype.check = function(id, notAutoRender){
  1335. if($(`dl[xid="${id}"]`).length) {
  1336. return true;
  1337. }else if($(`select[xm-select="${id}"]`).length){
  1338. if(!notAutoRender){
  1339. this.render(id, $(`select[xm-select="${id}"]`));
  1340. return true;
  1341. }
  1342. }else{
  1343. delete data[id];
  1344. return false;
  1345. }
  1346. }
  1347. Common.prototype.render = function(id, select){
  1348. common.init(select);
  1349. common.one($(`dl[xid="${id}"]`).parents(`.${PNAME}`));
  1350. common.initVal(id);
  1351. }
  1352. Common.prototype.log = function(obj){
  1353. console.log(obj);
  1354. }
  1355. let Select4 = function(){
  1356. this.v = v;
  1357. this.render();
  1358. };
  1359. let common = new Common();
  1360. Select4.prototype.value = function(id, type, isAppend){
  1361. if(typeof id != 'string'){
  1362. return [];
  1363. }
  1364. let fs = data[id];
  1365. if(!common.check(id)){
  1366. return [];
  1367. }
  1368. if(typeof type == 'string' || type == undefined){
  1369. let arr = fs.values.concat([]) || [];
  1370. if(type == 'val') {
  1371. return arr.map((val) => {
  1372. return val.value;
  1373. });
  1374. }
  1375. if(type == 'valStr') {
  1376. return arr.map((val) => {
  1377. return val.value;
  1378. }).join(',');
  1379. }
  1380. if(type == 'name') {
  1381. return arr.map((val) => {
  1382. return val.name;
  1383. });
  1384. }
  1385. if(type == 'nameStr') {
  1386. return arr.map((val) => {
  1387. return val.name;
  1388. }).join(',');
  1389. }
  1390. return arr;
  1391. }
  1392. if(common.isArray(type)) {
  1393. let dl = $(`[xid="${id}"]`),
  1394. temp = {},
  1395. dd,
  1396. isAdd = true;
  1397. if(isAppend == false){//删除传入的数组
  1398. isAdd = false;
  1399. }else if(isAppend == true){//追加模式
  1400. isAdd = true;
  1401. }else{//删除原有的数据
  1402. common.removeAll(id);
  1403. }
  1404. if(isAdd){
  1405. fs.values.forEach((val, index) => {
  1406. temp[val.value] = 1;
  1407. });
  1408. }
  1409. type.forEach((val, index) => {
  1410. if(val && (!temp[val] || fs.config.repeat)){
  1411. if((dd = dl.find(`dd[lay-value="${val}"]`))[0]){
  1412. common.handlerLabel(id, dd, isAdd, null, true);
  1413. temp[val] = 1;
  1414. }else{
  1415. let name = common.valToName(id, val);
  1416. if(name){
  1417. common.handlerLabel(id, dd, isAdd, common.getItem(id, val), true);
  1418. temp[val] = 1;
  1419. }
  1420. }
  1421. }
  1422. });
  1423. }
  1424. }
  1425. Select4.prototype.on = function(id, fun, isEnd) {
  1426. common.bindEvent(isEnd ? 'endOn' : 'on', id, fun);
  1427. return this;
  1428. }
  1429. Select4.prototype.filter = function(id, fun){
  1430. common.bindEvent('filter', id, fun);
  1431. return this;
  1432. }
  1433. Select4.prototype.maxTips = function(id, fun){
  1434. common.bindEvent('maxTips', id, fun);
  1435. return this;
  1436. }
  1437. Select4.prototype.opened = function(id, fun){
  1438. common.bindEvent('opened', id, fun);
  1439. return this;
  1440. }
  1441. Select4.prototype.closed = function(id, fun){
  1442. common.bindEvent('closed', id, fun);
  1443. return this;
  1444. }
  1445. Select4.prototype.config = function(id, config, isJson){
  1446. if(id && typeof id == 'object'){
  1447. isJson = config == true;
  1448. config = id;
  1449. id = null;
  1450. }
  1451. if(config && typeof config== 'object'){
  1452. if(isJson){
  1453. config.header || (config.header = {});
  1454. config.header['Content-Type'] = 'application/json; charset=UTF-8';
  1455. config.dataType = 'json';
  1456. }
  1457. id ? (
  1458. ajaxs[id] = $.extend(true, {}, ajaxs[id] || ajax, config), !common.check(id) && this.render(id),
  1459. data[id] && config.direction && (data[id].config.direction = config.direction),
  1460. data[id] && config.clearInput && (data[id].config.clearInput = true),
  1461. config.searchUrl && data[id] && common.triggerSearch($(`.${PNAME} dl[xid="${id}"]`).parents(`.${FORM_SELECT}`), true)
  1462. ) : (
  1463. $.extend(true, ajax, config),
  1464. $.each(ajaxs, (key, item) => {
  1465. $.extend(true, item, config)
  1466. })
  1467. );
  1468. }
  1469. return this;
  1470. }
  1471. Select4.prototype.render = function(id, options){
  1472. if(id && typeof id == 'object'){
  1473. options = id;
  1474. id = null;
  1475. }
  1476. let config = options ? {
  1477. init: options.init,
  1478. disabled: options.disabled,
  1479. max: options.max,
  1480. isSearch: options.isSearch,
  1481. searchUrl: options.searchUrl,
  1482. isCreate: options.isCreate,
  1483. radio: options.radio,
  1484. skin: options.skin,
  1485. direction: options.direction,
  1486. height: options.height,
  1487. formname: options.formname,
  1488. layverify: options.layverify,
  1489. layverType: options.layverType,
  1490. showCount: options.showCount,
  1491. placeholder: options.placeholder,
  1492. create: options.create,
  1493. filter: options.filter,
  1494. maxTips: options.maxTips,
  1495. on: options.on,
  1496. on: options.on,
  1497. opened: options.opened,
  1498. closed: options.closed,
  1499. template: options.template,
  1500. clearInput: options.clearInput,
  1501. } : {};
  1502. options && options.searchType != undefined && (config.searchType = options.searchType == 'dl' ? 1 : 0);
  1503. if(id){
  1504. fsConfigs[id] = {};
  1505. $.extend(fsConfigs[id], data[id] ? data[id].config : {}, config);
  1506. }else{
  1507. $.extend(fsConfig, config);
  1508. }
  1509. ($(`select[${NAME}="${id}"]`)[0] ? $(`select[${NAME}="${id}"]`) : $(`select[${NAME}]`)).each((index, select) => {
  1510. let sid = select.getAttribute(NAME);
  1511. common.render(sid, select);
  1512. setTimeout(() => common.setHidnVal(sid, $(`select[xm-select="${sid}"] + div.${PNAME} .${LABEL}`)), 10);
  1513. });
  1514. return this;
  1515. }
  1516. Select4.prototype.disabled = function(id){
  1517. let target = {};
  1518. id ? (common.check(id) && (target[id] = data[id])) : (target = data);
  1519. $.each(target, (key, val) => {
  1520. $(`dl[xid="${key}"]`).prev().addClass(DIS);
  1521. });
  1522. return this;
  1523. }
  1524. Select4.prototype.undisabled = function(id){
  1525. let target = {};
  1526. id ? (common.check(id) && (target[id] = data[id])) : (target = data);
  1527. $.each(target, (key, val) => {
  1528. $(`dl[xid="${key}"]`).prev().removeClass(DIS);
  1529. });
  1530. return this;
  1531. }
  1532. Select4.prototype.data = function(id, type, config){
  1533. if(!id || !type || !config){
  1534. common.log(`id: ${id} param error !!!`)
  1535. return this;
  1536. }
  1537. if(!common.check(id)){
  1538. common.log(`id: ${id} not render !!!`)
  1539. return this;
  1540. }
  1541. this.value(id, []);
  1542. this.config(id, config);
  1543. if(type == 'local'){
  1544. common.renderData(id, config.arr, config.linkage == true, config.linkageWidth ? config.linkageWidth : '100');
  1545. }else if(type == 'server'){
  1546. common.ajax(id, config.url, config.keyword, config.linkage == true, config.linkageWidth ? config.linkageWidth : '100');
  1547. }
  1548. return this;
  1549. }
  1550. Select4.prototype.btns = function(id, btns, config){
  1551. if(id && common.isArray(id)){
  1552. btns = id;
  1553. id = null;
  1554. }
  1555. if(!btns || !common.isArray(btns)) {
  1556. return this;
  1557. };
  1558. let target = {};
  1559. id ? (common.check(id) && (target[id] = data[id])) : (target = data);
  1560. btns = btns.map((obj) => {
  1561. if(typeof obj == 'string'){
  1562. if(obj == 'select'){
  1563. return quickBtns[0];
  1564. }
  1565. if(obj == 'remove'){
  1566. return quickBtns[1];
  1567. }
  1568. if(obj == 'reverse'){
  1569. return quickBtns[2];
  1570. }
  1571. if(obj == 'skin'){
  1572. return quickBtns[3];
  1573. }
  1574. }
  1575. return obj;
  1576. });
  1577. $.each(target, (key, val) => {
  1578. val.config.btns = btns;
  1579. let dd = $(`dl[xid="${key}"]`).find(`.${FORM_SELECT_TIPS}:first`);
  1580. if(btns.length){
  1581. let show = config && config.show && (config.show == 'name' || config.show == 'icon') ? config.show : '';
  1582. let html = common.renderBtns(key, show, config && config.space ? config.space : '30px');
  1583. dd.html(html);
  1584. }else{
  1585. let pcInput = dd.parents(`.${FORM_SELECT}`).find(`.${TDIV} input`);
  1586. let html = pcInput.attr('placeholder') || pcInput.attr('back');
  1587. dd.html(html);
  1588. dd.removeAttr('style');
  1589. }
  1590. });
  1591. return this;
  1592. }
  1593. Select4.prototype.search = function(id, val){
  1594. if(id && common.check(id)){
  1595. ajaxs[id] = $.extend(true, {}, ajaxs[id] || ajax, {
  1596. first: true,
  1597. searchVal: val
  1598. });
  1599. common.triggerSearch($(`dl[xid="${id}"]`).parents(`.${FORM_SELECT}`), true);
  1600. }
  1601. return this;
  1602. }
  1603. Select4.prototype.replace = function(id, type, config){
  1604. if(!id || !type || !config){
  1605. common.log(`id: ${id} param error !!!`)
  1606. return this;
  1607. }
  1608. if(!common.check(id, true)){
  1609. common.log(`id: ${id} not render !!!`)
  1610. return this;
  1611. }
  1612. let oldVals = this.value(id, 'val');
  1613. this.value(id, []);
  1614. this.config(id, config);
  1615. if(type == 'local'){
  1616. common.renderData(id, config.arr, config.linkage == true, config.linkageWidth ? config.linkageWidth : '100', false, true);
  1617. this.value(id, oldVals, true);
  1618. }else if(type == 'server'){
  1619. common.ajax(id, config.url, config.keyword, config.linkage == true, config.linkageWidth ? config.linkageWidth : '100', false, (id) => {
  1620. this.value(id, oldVals, true);
  1621. }, true);
  1622. }
  1623. }
  1624. return new Select4();
  1625. });