select-resource.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  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: 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. render_tags(originalItems);
  199. }
  200. ResourceSelector.displayers = {
  201. default: function (tag, $input, opts) {
  202. var place = '<span class="default-text" style="opacity:0.75">' + (opts.placeholder || $input.attr('placeholder')) + '</span>',
  203. maxItem = opts.maxItem;
  204. function _init() {
  205. if (!LA.len(tag)) {
  206. return $input.html(place);
  207. }
  208. if (maxItem == 1) {
  209. return $input.html(build_one(tag[Object.keys(tag)[0]]));
  210. }
  211. $input.html(build_many(tag));
  212. }
  213. function build_many(tag) {
  214. var html = [];
  215. for (var i in tag) {
  216. if (maxItem > 2 || !maxItem) {
  217. var strVar = "";
  218. strVar += "<li class=\"select2-selection__choice\" >";
  219. strVar += tag[i] + " <span data-id=\"" + i + "\" class=\"select2-selection__choice__remove ";
  220. strVar += opts.clearOneClass +"\" role=\"presentation\"> ×</span>";
  221. strVar += "</li>";
  222. html.push(strVar);
  223. } else {
  224. html.push(
  225. "<a class='label label-primary'>" + tag[i] + " " +
  226. "<span data-id=" + i + " class='" + opts.clearOneClass +
  227. "' style='font-weight:bold;cursor:pointer;font-size:14px'>×</span></a>"
  228. )
  229. }
  230. }
  231. if (!(maxItem > 2 || !maxItem)) {
  232. return build_one(html.join('&nbsp;'));
  233. }
  234. html.unshift('<span class="select2-selection__clear '+opts.clearAllClass+'">×</span>');
  235. html = '<ul class="select2-selection__rendered">' + html.join('') + '</ul>';
  236. return html;
  237. }
  238. /**
  239. * 单个选项样式
  240. *
  241. * @param tag
  242. * @returns {string}
  243. */
  244. function build_one(tag) {
  245. var clearButton = "<div class='pull-right "+opts.clearAllClass+"' style='font-weight:bold;cursor:pointer'>×</div>";
  246. return ""+tag+""+clearButton;
  247. }
  248. _init();
  249. },
  250. // list模式
  251. navList: function (tag, $input, opts) {
  252. var place = '<span style="opacity:0.75">' + (opts.placeholder || $input.attr('placeholder')) + '</span>',
  253. maxItem = opts.maxItem;
  254. function _init() {
  255. var $app = $(opts.selector).parents('.select-resource').find('app');
  256. $app.html('');
  257. if (!LA.len(tag)) {
  258. return $input.html(place);
  259. }
  260. if (maxItem == 1) {
  261. return $input.html(build_one(tag[Object.keys(tag)[0]]));
  262. }
  263. $input.html(build_one(opts.selectedOptionsTip.replace(':num', LA.len(tag))));
  264. $app.html(build_many(tag));
  265. }
  266. function build_many(tag) {
  267. var html = [];
  268. for (var i in tag) {
  269. var strVar = "";
  270. strVar += "<li>";
  271. strVar += "<a class='pull-left'>" + tag[i] + "</a><a data-id='" + i + "' class='pull-right red ";
  272. strVar += opts.clearOneClass +"' ><i class='fa fa-close'></i></a>";
  273. strVar += "<span class='clearfix'></span></li>";
  274. html.push(strVar);
  275. }
  276. html = '<ul class="nav nav-pills nav-stacked" >' + html.join('') + '</ul>';
  277. return html;
  278. }
  279. function build_one(tag) {
  280. var clearButton = "<div class='pull-right "+opts.clearAllClass+"' style='font-weight:bold;cursor:pointer'>×</div>";
  281. return ""+tag+""+clearButton;
  282. }
  283. _init();
  284. }
  285. };
  286. LA.ResourceSelector = ResourceSelector;
  287. })(window);