selectM.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /*
  2. * @version: 2.0
  3. * @Author: tomato
  4. * @Date: 2018-5-5 11:29:57
  5. * @Last Modified by: tomato
  6. * @Last Modified time: 2018-5-26 18:08:43
  7. */
  8. //多选下拉框
  9. layui.define(['jquery', 'layer'], function(exports){
  10. var MOD_NAME = 'selectM';
  11. var $ = layui.jquery,layer=layui.layer;
  12. var obj = function(config){
  13. this.disabledIndex =[];
  14. //当前选中的值名数据
  15. this.selected = [];
  16. //当前选中的值
  17. this.values =[];
  18. //当前选中的名称
  19. this.names =[];
  20. //初始化设置参数
  21. this.config = {
  22. //选择器id或class
  23. elem: '',
  24. //候选项数据[{id:"1",name:"名称1",status:0},{id:"2",name:"名称2",status:1}]
  25. data: [],
  26. //默认选中值
  27. selected: [],
  28. //空值项提示,支持将{max}替换为max
  29. tips: '请选择 最多 {max} 个',
  30. //最多选中个数,默认5
  31. max : 5,
  32. //选择框宽度
  33. width:null,
  34. //值验证,与lay-verify一致
  35. verify: '',
  36. //input的name 不设置与选择器相同(去#.)
  37. name: '',
  38. //值的分隔符
  39. delimiter: ',',
  40. //候选项数据的键名 status=0为禁用状态
  41. field: {idName:'id',titleName:'name',statusName:'status'}
  42. }
  43. this.config = $.extend(this.config,config);
  44. //创建选项元素
  45. this.createOption = function(){
  46. var o=this,c=o.config,f=c.field,d = c.data;
  47. var s = c.selected;
  48. $E = $(c.elem);
  49. var tips = c.tips.replace('{max}',c.max);
  50. var inputName = c.name=='' ? c.elem.replace('#','').replace('.','') : c.name;
  51. var verify = c.verify=='' ? '' : 'lay-verify="'+c.verify+'" ';
  52. var html = '';
  53. html += '<div class="layui-unselect layui-form-select">';
  54. html += '<div class="layui-select-title">';
  55. html += '<input '+verify+'name="'+inputName+'" type="text" readonly="" class="layui-input layui-unselect">';
  56. html += '</div>';
  57. html += '<div class="layui-input multiple">';
  58. html += '</div>';
  59. html += '<dl class="layui-anim layui-anim-upbit">';
  60. html += '<dd lay-value="" class="layui-select-tips">'+tips+'</dd>';
  61. for(var i=0;i<d.length;i++){
  62. var disabled1='',disabled2='';
  63. if(d[i][f.statusName]==0){
  64. o.disabledIndex[d[i][f.idName]] = d[i][f.titleName];
  65. disabled1 = d[i][f.statusName]==0 ? 'layui-disabled' : '';
  66. disabled2 = d[i][f.statusName]==0 ? ' layui-checkbox-disbaled layui-disabled' : '';
  67. }
  68. html +='<dd lay-value="'+d[i][f.idName]+'" class="'+disabled1+'">';
  69. html += '<div class="layui-unselect layui-form-checkbox'+disabled2+'" lay-skin="primary">';
  70. html += '<span>'+d[i][f.titleName]+'</span><i class="layui-icon">&#xe605;</i>';
  71. html += '</div>';
  72. html +='</dd>';
  73. }
  74. html += '</dl>';
  75. html += '</div>';
  76. $E.html(html);
  77. }
  78. //设置选中值
  79. this.set = function(selected){
  80. var o=this,c=o.config;
  81. var s = typeof selected=='undefined' ? c.selected : selected;
  82. $E = $(c.elem);
  83. $E.find('.layui-form-checkbox').removeClass('layui-form-checked');
  84. $E.find('dd').removeClass('layui-this');
  85. //为默认选中值添加类名
  86. var max = s.length>c.max ? c.max : s.length;
  87. for(var i=0;i<max;i++){
  88. if(s[i] && !o.disabledIndex.hasOwnProperty(s[i])){
  89. $E.find('dd[lay-value='+s[i]+']').addClass('layui-this');
  90. }
  91. }
  92. $E.find('dd.layui-this').each(function(){
  93. $(this).find('div').addClass('layui-form-checked');
  94. });
  95. o.setSelected(selected);
  96. }
  97. //设置选中值 每次点击操作后执行
  98. this.setSelected = function(first){
  99. var o=this,c=o.config,f=c.field;
  100. $E = $(c.elem);
  101. var values=[],names=[],selected = [],spans = [];
  102. var items = $E.find('dd.layui-this');
  103. if(items.length==0){
  104. var tips = c.tips.replace('{max}',c.max);
  105. spans.push('<span class="tips">'+tips+'</span>');
  106. }
  107. else{
  108. items.each(function(){
  109. $this = $(this);
  110. var item ={};
  111. var v = $this.attr('lay-value');
  112. var n = $this.find('span').text();
  113. item[f.idName] = v;
  114. item[f.titleName] = n;
  115. values.push(v);
  116. names.push(n);
  117. spans.push('<a href="javascript:;"><span lay-value="'+v+'">'+n+'</span><i class="layui-icon">&#x1006;</i></a>');
  118. selected.push(item);
  119. });
  120. }
  121. spans.push('<i class="layui-edge" style="pointer-events: none;"></i>');
  122. $E.find('.multiple').html(spans.join(''));
  123. $E.find('.layui-select-title').find('input').each(function(){
  124. if(typeof first=='undefined'){
  125. this.defaultValue = values.join(c.delimiter);
  126. }
  127. this.value = values.join(c.delimiter);
  128. });
  129. var h = $E.find('.multiple').height()+14;
  130. $E.find('.layui-form-select dl').css('top',h+'px');
  131. o.values=values,o.names=names,o.selected = selected;
  132. }
  133. //ajax方式获取候选数据
  134. this.getData = function(url){
  135. var d;
  136. $.ajax({
  137. url:url,
  138. dataType:'json',
  139. async:false,
  140. success:function(json){
  141. d=json;
  142. },
  143. error: function(){
  144. console.error(MOD_NAME+' hint:候选数据ajax请求错误 ');
  145. d = false;
  146. }
  147. });
  148. return d;
  149. }
  150. };
  151. //渲染一个实例
  152. obj.prototype.render = function(){
  153. var o=this,c=o.config,f=c.field;
  154. $E = $(c.elem);
  155. if($E.length==0){
  156. console.error(MOD_NAME+' hint:找不到容器 ' +c.elem);
  157. return false;
  158. }
  159. if(Object.prototype.toString.call(c.data)!='[object Array]'){
  160. var data = o.getData(c.data);
  161. if(data===false){
  162. console.error(MOD_NAME+' hint:缺少分类数据');
  163. return false;
  164. }
  165. o.config.data = data;
  166. }
  167. //给容器添加一个类名
  168. $E.addClass('lay-ext-mulitsel');
  169. if(/^\d+$/.test(c.width)){
  170. $E.css('width',c.width+'px');
  171. }
  172. //添加专属的style
  173. if($('#lay-ext-mulitsel-style').length==0){
  174. var style = '.lay-ext-mulitsel .layui-form-select dl dd div{margin-top:0px!important;}.lay-ext-mulitsel .layui-form-select dl dd.layui-this{background-color:#fff}.lay-ext-mulitsel .layui-input.multiple{line-height:auto;height:auto;padding:4px 10px 4px 10px;overflow:hidden;min-height:38px;margin-top:-38px;left:0;z-index:99;position:relative;background:#fff;}.lay-ext-mulitsel .layui-input.multiple a{padding:2px 5px;background:#5FB878;border-radius:2px;color:#fff;display:block;line-height:20px;height:20px;margin:2px 5px 2px 0;float:left;}.lay-ext-mulitsel .layui-input.multiple a i{margin-left:4px;font-size:14px;} .lay-ext-mulitsel .layui-input.multiple a i:hover{background-color:#009E94;border-radius:2px;}.lay-ext-mulitsel .danger{border-color:#FF5722!important}.lay-ext-mulitsel .tips{pointer-events: none;position: absolute;left: 10px;top: 10px;color:#757575;}';
  175. $('<style id="lay-ext-mulitsel-style"></style>').text(style).appendTo($('head'));
  176. };
  177. //创建选项
  178. o.createOption();
  179. //设置选中值
  180. o.set();
  181. //展开/收起选项
  182. $E.on('click','.layui-select-title,.multiple,.multiple.layui-edge',function(e){
  183. //隐藏其他实例显示的弹层
  184. $('.lay-ext-mulitsel').not(c.elem).removeClass('layui-form-selected');
  185. if($(c.elem).is('.layui-form-selected')){
  186. $(c.elem).removeClass('layui-form-selected');
  187. $(document).off('click',mEvent);
  188. }
  189. else{
  190. $(c.elem).addClass('layui-form-selected');
  191. $(document).on('click',mEvent=function(e){
  192. if(e.target.id!==c.elem && e.target.className!=='layui-input multiple'){
  193. $(c.elem).removeClass('layui-form-selected');
  194. $(document).off('click',mEvent);
  195. }
  196. });
  197. }
  198. });
  199. //点击选项
  200. $E.on('click','dd',function(e){
  201. var _dd = $(this);
  202. if(_dd.hasClass('layui-disabled')){
  203. return false;
  204. }
  205. //点 请选择
  206. if(_dd.is('.layui-select-tips')){
  207. _dd.siblings().removeClass('layui-this');
  208. $(c.elem).find('.layui-form-checkbox').removeClass('layui-form-checked');
  209. }
  210. //取消选中
  211. else if(_dd.is('.layui-this')){
  212. _dd.removeClass('layui-this');
  213. _dd.find('.layui-form-checkbox').removeClass('layui-form-checked');
  214. e.stopPropagation();
  215. }
  216. //选中
  217. else{
  218. if(o.selected.length >= c.max){
  219. $(c.elem+' .multiple').addClass('danger');
  220. layer.tips('最多只能选择 '+c.max+' 个', c.elem+' .multiple', {
  221. tips: 3,
  222. time: 1000,
  223. end:function(){
  224. $(c.elem+' .multiple').removeClass('danger');
  225. }
  226. });
  227. return false;
  228. }
  229. else{
  230. _dd.addClass('layui-this');
  231. _dd.find('.layui-form-checkbox').addClass('layui-form-checked');
  232. e.stopPropagation();
  233. }
  234. }
  235. o.setSelected();
  236. });
  237. //删除选项
  238. $E.on('click','a i',function(e){
  239. var _this = $(this).prev('span');
  240. var v = _this.attr('lay-value');
  241. if(v){
  242. var _dd = $(c.elem).find('dd[lay-value='+v+']');
  243. _dd.removeClass('layui-this');
  244. _dd.find('.layui-form-checkbox').removeClass('layui-form-checked');
  245. }
  246. o.setSelected();
  247. _this.parent().remove();
  248. e.stopPropagation();
  249. });
  250. //验证失败样式
  251. $E.find('input').focus(function(){
  252. $(c.elem+' .multiple').addClass('danger');
  253. setTimeout(function(){
  254. $(c.elem+' .multiple').removeClass('danger');
  255. },3000);
  256. });
  257. }
  258. //输出模块
  259. exports(MOD_NAME, function (config) {
  260. var _this = new obj(config);
  261. _this.render();
  262. return _this;
  263. });
  264. });