select-resource.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. (function (w) {
  2. var NONE = '';
  3. function ResourceSelector(options) {
  4. options = $.extend({
  5. title: '选择', // 弹窗标题
  6. selector: '', // 选择按钮选择器
  7. column: '', // 字段名称
  8. source: '', // 资源地址
  9. maxItem: 1, // 最大选项数量,0为不限制
  10. area: ['80%', '90%'],
  11. items: {}, // 默认选中项,key => value 键值对
  12. placeholder: '', // input placeholder
  13. showCloseButton: false,
  14. closeButtonText: '关闭',
  15. exceedMaxItemTip: '您已超出最大可选择的数量',
  16. selectedOptionsTip: '已选中:num个选项',
  17. $displayerContainer: null, // 选项展示容器dom对象
  18. $hiddenInput: null, // 隐藏表单dom对象
  19. displayer: null, // 自定义选中项渲染方法
  20. disabled: false,
  21. clearAllClass: '',
  22. clearOneClass: '',
  23. window: null,
  24. }, options);
  25. options.window = options.window || (top || w);
  26. var self = ResourceSelector,
  27. column = options.column,
  28. cls = column.replace(/[\[\]]*/g, '') + (Math.random().toString(36).substr(2)),
  29. layer = options.window.layer,
  30. $input = options.$displayerContainer || $(options.selector).parents('.select-resource').find('div[name="' + column + '"]'),
  31. $hidden = options.$hiddenInput || $('input[name="' + column + '"]'),
  32. tagClearClass = options.clearOneClass || (cls + '-tag-clear-button'),
  33. clearClass = options.clearAllClass || (cls + '-clear-button'),
  34. maxItem = options.maxItem,
  35. originalItems = options.items,
  36. iframeWin,
  37. layerIdx,
  38. $layerWin;
  39. options.clearOneClass = tagClearClass;
  40. options.clearAllClass = clearClass;
  41. $(options.selector).click(function () {
  42. if (options.disabled) return;
  43. if (layerIdx) {
  44. $layerWin.show();
  45. click_checked_items();
  46. return;
  47. }
  48. $(document).one('pjax:complete', function () {// 跳转新页面时移除弹窗
  49. layer.close(layerIdx);
  50. $layerWin.remove();
  51. layerIdx = $layerWin = null;
  52. });
  53. layerIdx = layer.open({
  54. type: 2,
  55. title: options.title,
  56. shadeClose: true,
  57. maxmin: false,
  58. shade: false,
  59. skin: 'select-resource',
  60. area: format_area(options.area),
  61. content: options.source + '?_mini=1',
  62. btn: options.showCloseButton ? [options.closeButtonText] : null,
  63. success: function (layero) {
  64. iframeWin = options.window[layero.find('iframe')[0]['name']];
  65. // 绑定勾选默认选项事件
  66. bind_checked_default_event(iframeWin);
  67. },
  68. yes: function () {
  69. $layerWin.hide();
  70. return false;
  71. },
  72. cancel: function () {
  73. $layerWin.hide();
  74. return false;
  75. }
  76. });
  77. $layerWin = options.window.$('#layui-layer' + layerIdx);
  78. });
  79. /**
  80. * 多选
  81. */
  82. function multiple_select($this) {
  83. var id = $this.data('id'),
  84. label = $this.data('label') || id,
  85. exist = LA.isset(originalItems, id);
  86. if ($this.prop('checked')) {
  87. if (!exist) {
  88. originalItems[id] = label;
  89. }
  90. } else if (exist) {
  91. delete originalItems[id];
  92. }
  93. if (maxItem > 0 && LA.len(originalItems) > maxItem) {
  94. unchecked($this);
  95. delete originalItems[id];
  96. // 多选项判断最大长度
  97. return LA.warning(options.exceedMaxItemTip);
  98. }
  99. render_tags(originalItems);
  100. }
  101. // 单选
  102. function select($this) {
  103. var id = $this.data('id'),
  104. label = $this.data('label') || id;
  105. get_all_ckb().each(function () {
  106. if ($(this).data('id') != id) {
  107. unchecked($(this));
  108. }
  109. });
  110. originalItems = {};
  111. if ($this.prop('checked')) {
  112. originalItems[id] = label;
  113. }
  114. render_tags(originalItems);
  115. }
  116. /**
  117. * 显示选项内容
  118. *
  119. * @param items
  120. */
  121. function render_tags(items) {
  122. var ids = [];
  123. for (var id in items) {
  124. ids.push(id);
  125. }
  126. // 显示勾选的选项内容
  127. display_input_div(items);
  128. set_selected_id(ids);
  129. // 绑定清除事件
  130. $('.' + clearClass).click(clear_all_tags);
  131. $('.' + tagClearClass).click(clear_tag);
  132. }
  133. function set_selected_id(ids) {
  134. $hidden.val(ids.length ? ids.join(',') : NONE);
  135. }
  136. /**
  137. * 显示勾选的选项内容
  138. */
  139. function display_input_div(tag) {
  140. if (options.displayer) {
  141. if (typeof options.displayer == 'string' && LA.isset(self.displayers, options.displayer)) {
  142. return self.displayers[options.displayer](tag, $input, options);
  143. }
  144. // 自定义选中内容渲染
  145. return options.displayer(tag, $input, options);
  146. }
  147. return self.displayers.default(tag, $input, options);
  148. }
  149. function bind_checked_default_event(iframeWin) {
  150. LA.ready(function () {
  151. click_checked_items();
  152. get_all_ckb().change(function () {
  153. if (maxItem == 1) {
  154. select($(this));
  155. } else {
  156. multiple_select($(this));
  157. }
  158. });
  159. if (maxItem == 1) {
  160. // 单选模式禁用全选按钮
  161. $(layer.getChildFrame('.checkbox-grid .select-all', layerIdx)).click(function () {
  162. return false;
  163. });
  164. }
  165. }, iframeWin);
  166. }
  167. function unchecked($ckb) {
  168. $ckb.parents('tr').css('background-color', 'transparent');
  169. $ckb.prop('checked', false);
  170. }
  171. // 勾选默认选项
  172. function click_checked_items() {
  173. setTimeout(function () {
  174. var ckb = layer.getChildFrame('tbody .checkbox-grid input[type="checkbox"]:checked', layerIdx);
  175. unchecked(ckb);
  176. for (var id in originalItems) {
  177. layer.getChildFrame('.checkbox-grid input[data-id="'+id+'"]', layerIdx).click();
  178. }
  179. }, 10);
  180. }
  181. function get_all_ckb() {
  182. return $(layer.getChildFrame('.checkbox-grid input[type="checkbox"]:not(.select-all)', layerIdx));
  183. }
  184. /**
  185. * 清除所有选项
  186. */
  187. function clear_tag() {
  188. delete originalItems[$(this).data('id')];
  189. render_tags(originalItems);
  190. }
  191. /**
  192. * 清除所有选项
  193. */
  194. function clear_all_tags() {
  195. originalItems = {};
  196. render_tags(originalItems);
  197. }
  198. function format_area(area) {
  199. if (w.screen.width <= 750) {
  200. return ['100%', '100%'];
  201. }
  202. return area;
  203. }
  204. render_tags(originalItems);
  205. }
  206. ResourceSelector.displayers = {
  207. default: function (tag, $input, opts) {
  208. var place = '<span class="default-text" style="opacity:0.75">' + (opts.placeholder || $input.attr('placeholder')) + '</span>',
  209. maxItem = opts.maxItem;
  210. function _init() {
  211. if (!LA.len(tag)) {
  212. return $input.html(place);
  213. }
  214. if (maxItem == 1) {
  215. return $input.html(build_one(tag[Object.keys(tag)[0]]));
  216. }
  217. $input.html(build_many(tag));
  218. }
  219. function build_many(tag) {
  220. var html = [];
  221. for (var i in tag) {
  222. if (maxItem > 2 || !maxItem) {
  223. var strVar = "";
  224. strVar += "<li class=\"select2-selection__choice\" >";
  225. strVar += tag[i] + " <span data-id=\"" + i + "\" class=\"select2-selection__choice__remove ";
  226. strVar += opts.clearOneClass +"\" role=\"presentation\"> ×</span>";
  227. strVar += "</li>";
  228. html.push(strVar);
  229. } else {
  230. html.push(
  231. "<a class='label label-primary'>" + tag[i] + " " +
  232. "<span data-id=" + i + " class='" + opts.clearOneClass +
  233. "' style='font-weight:bold;cursor:pointer;font-size:14px'>×</span></a>"
  234. )
  235. }
  236. }
  237. if (!(maxItem > 2 || !maxItem)) {
  238. return build_one(html.join('&nbsp;'));
  239. }
  240. html.unshift('<span class="select2-selection__clear '+opts.clearAllClass+'">×</span>');
  241. html = '<ul class="select2-selection__rendered">' + html.join('') + '</ul>';
  242. return html;
  243. }
  244. /**
  245. * 单个选项样式
  246. *
  247. * @param tag
  248. * @returns {string}
  249. */
  250. function build_one(tag) {
  251. var clearButton = "<div class='pull-right "+opts.clearAllClass+"' style='font-weight:bold;cursor:pointer'>×</div>";
  252. return ""+tag+""+clearButton;
  253. }
  254. _init();
  255. },
  256. // list模式
  257. navList: function (tag, $input, opts) {
  258. var place = '<span style="opacity:0.75">' + (opts.placeholder || $input.attr('placeholder')) + '</span>',
  259. maxItem = opts.maxItem;
  260. function _init() {
  261. var $app = $(opts.selector).parents('.select-resource').find('app');
  262. $app.html('');
  263. if (!LA.len(tag)) {
  264. return $input.html(place);
  265. }
  266. if (maxItem == 1) {
  267. return $input.html(build_one(tag[Object.keys(tag)[0]]));
  268. }
  269. $input.html(build_one(opts.selectedOptionsTip.replace(':num', LA.len(tag))));
  270. $app.html(build_many(tag));
  271. }
  272. function build_many(tag) {
  273. var html = [];
  274. for (var i in tag) {
  275. var strVar = "";
  276. strVar += "<li>";
  277. strVar += "<a class='pull-left'>" + tag[i] + "</a><a data-id='" + i + "' class='pull-right red ";
  278. strVar += opts.clearOneClass +"' ><i class='fa fa-close'></i></a>";
  279. strVar += "<span class='clearfix'></span></li>";
  280. html.push(strVar);
  281. }
  282. html = '<ul class="nav nav-pills nav-stacked" >' + html.join('') + '</ul>';
  283. return html;
  284. }
  285. function build_one(tag) {
  286. var clearButton = "<div class='pull-right "+opts.clearAllClass+"' style='font-weight:bold;cursor:pointer'>×</div>";
  287. return ""+tag+""+clearButton;
  288. }
  289. _init();
  290. }
  291. };
  292. LA.ResourceSelector = ResourceSelector;
  293. })(window);