selectM.js 9.0 KB

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