layui table 和 formSelects 结合案例

讨论 已结 置顶 精帖 140 16838
岁月小偷
悬赏:500飞吻
之前处理过layui的下拉在表格中还有layer中的显示效果,有小伙伴提出来希望在这个插件里面把多选下拉也集成进来。个人的看法是多选下拉(formSelects)是社区其他小伙伴的劳动成果,所谓的集合不是直接“盗用”,也不是重复造轮子,而是如何解决他在表格中因为表格td等一些样式导致需要看到选项的时候看不到选项的问题。

更新于 2019年5月22日 20:44:02
针对type: 1的layer中的多选下拉也做了显示优化处理,并且将帖子中的修改的内容抽出来到一个renderFormSelectsIn.js中,css也提到了renderFormSelectsIn.css,方便先要用这个修改的小伙伴直接引入,唯一需要注意的可能就是下面这个路径,如果你先use了formSelects了再use这个renderFormSelectsIn,就将这个extend去掉,不然会提示已经加载过的错误信息,如果没有use过formSelects就直接使用这个模块,那么就要将这个extend的路径改成自己项目中的正确的路径。

想看layer中的多选下拉优化效果的,可以自己点击“编辑”,在弹出的表单中有一个“个人标签”的项,用这个测试就可以了。

另外一个修改是有小伙伴问,固定列鼠标滚动支持的这个功能有没有配置可以决定要不要,个人认为这个修改实际是对体验有较大提升的一个点,是本插件的一个特色,而且即使有,那也必须是全局的,不会提供给具体某一个表格要某一个表格不要的支持,不然用户会认为出bug,在一个表格明明可以,但是有一些表格却不行,所以新增了一个tablePlug.enableTableFixedScroll的方法,参数就是true/false;内部已经默认是打开的,如果真的不要这个功能,可以在use了tablePlug之后给tablePlug.enableTableFixedScroll(false);关闭一下即可,后面就都不会有,除非再次打开。测试的话就在上图中的表格上方的一个开关可以自己尝试切换试试看。

问题解决思路:
实际上,formSelects就是参考layui的select开发出来的一个比较优秀的插件了,所以一开始觉得可以参考之前select的处理方式优化一下optimizeSelectOption这个小插件,提高可扩展性,要做的就是可以补充进来对其他插件的支持,包括点击title的时候的监听,打开之后的监听处理,还有关闭选项之后的监听处理,让关键的这几个可以扩展的话后面用户就可以自由的添加新的插件在对应的表格还有layer中的显示优化的问题。
改造如下:

内部将之前的layui的select的修改给注册进来:

最后暴露出去:

可能会问最后暴露的这块为啥注释掉了,那后面如果要把formSelects给注册进来岂不是不能用layui.optimizeSelectOption('formSelects',{....});这样子加进来。原因注释的里面也写了,因为不完善,但是更具体的原因是因为虽然formSelects跟layui的select很相似,但是,实际实现的逻辑,事件的监听等等一些列的细节是不一样的,所以optimizeSelectOption这个注册的方法定义的一些套路走不通,得针对具体的插件做具体的处理,所以render等于没有起到他该有的作用,但是这个工作其实不是白费的,起码的在封装的过程中让我对formSelects有了更多一些的了解。下面会提出来他跟原始layui的不一样的地方导致render的尝试失败的原因已经最终的解决方案。
先看一个最后的效果图:

编辑表单修改回填,图不好录自己在测试页面体验

第一个问题:title的点击事件被formSelects阻止了冒泡
出师不利,第一步就碰壁,因为formSelects内部对title点击的事件中添加了冒泡的阻止,也就是说render里面是利用事件委托去监听的,因为被阻止了也就监听不到,所以一开始觉得如果只是这个小问题的话改一下让它别阻止就行,
这个大概是在最新版本(4.0.0.0910)的源码871行

注释掉之后点击可以出来,但是更麻烦的还在后头。
第二个问题:组件内部关于选项点击之后如果同步到title还有select中去,这个可以说是决定性的,layui的下拉是在render的时候就给加上事件并且用的基本都是jquery对象的处理,后面即使把选项挪到别的地方(layer)去,点击了还是会有原本的事件响应能找到他需要修改的title节点还有select原始节点,但是formSelects不同的是他是通过点击的时候的节点去parent()呀prev()呀这些方式去找到需要的节点,如果这个时候把选项挪出去,点击的时候他就找不到需要的那些节点了导致后面一些列的逻辑都崩塌了,这个才是不好处理的。

综合两个问题,在不修改formSelects的基础上,找到一个更合适的方案:一般来说我们需要在它选项打开的时候去处理一些事情,layui的select没有提供对应的事件,但是他没有阻止冒泡,所以我们利用了事件委托抓取到了,formSelects呢,本身阻止了,委托是抓不到了,但是,好在关了一扇门开了一扇窗,它提供了opened还有closed这两个监听,所以把需要在打开之后将选项拿到layer中显示的处理就可以拿到这个opened监听里面去了如下
多选列的templet:

done回调处理:

红色框框只是说明opened监听的部分的主要地方,但是其他的跟formSelects相关的也挺重要的,包括初始化,赋值,修改监听中将值同步到cache中等这些就自行查看formSelects的文档了;关闭监听处理,表格视图中的滚动监听关掉内部已打开的选项的处理这些细节处理也是跟本次修改比较相关的。
修改到这里就基本over了,只是一个比较简易的结合方案,如果觉得有用可以后面自行的进一步封装出来一些通用的方法方便后面复用。
更新于2019年5月8日 18:23:27
有小伙伴提出来这个功能在ie上不能用,测试了一下是有一个情况就是在关闭选项的时候,layer end回调里面将clone的节点replace回去的时候,在ie上会出现clone内部的节点丢失,导致覆盖回去之后原始的节点也变成空的,也就是看着空白了,修改方案就是跟layui的select一样,在关闭的回调中去将需要重新渲染一下的节点给重新渲染一下。
不过期间也遇到了一些问题,主要是因为多选下拉这个插件的事件监听,个人猜想实际他是打算参考form的事件做的,因为可以针对某个下拉绑定事件,也可以全部加,感觉像是利用了layui.onevent,但是实际不是,有点像但是没有模仿到位,导致的问题是,监听全部的事件只能对已经存在的render过的下拉实例有效,如果这个节点是后面追加的或者替换掉重新render了,之前加的那个全局的事件是不管用的,不单单是全局的事件,连针对单个的事件也是,这点上就跟layui.event没法比了,但是本身不是开发多选下拉插件的,所以他是什么套路就按照他的套路出对策就好。
将原始的几个事件监听给提取出来做成一个方法并且在end回调的时候去掉之前的处理逻辑重新render下拉并重新绑定事件:

之前添加事件的地方就只要调用一下这个方法就好:
回帖
  • 沙发是我的 [哈哈]
    大神辛苦了,社区之光,名不虚传![good] [good] [good]
    7 回复
  • @不二812 典型的撒泼打滚,买卖自由,模板商场里面有免费的有要钱的,为啥不选免费的?既然网上大把为啥还要来买?秀逗了,就这么几个普通的简单页面难道要给你整个几个T的文件你才觉得值钱,能更简洁的实现就是不值钱,人家的页面就是用这么几个文件简单的就搞定了,又不是说买之前看到的是一个样子,买了就不是了,货不对版的问题,这跟买了个lv然后说他没有地摊货10块钱的袋子装的东西多一点都不值那么多钱有什么区别?
    10 回复
  • @ycgyab 整个表格的数据估计纯前台不一定拿得到,要看表格是url接口的还是data模式的,如果是data可以直接得到当前表格的实例的config.data就是了,如果是url全部的数据是没办法确定的,因为涉及分页,当然如果不分页的话直接table.cache[tableId]就能够得到,
    5 回复
  • @金乡大蒜 不会吧,关键是现在已经能满足基本的需求了呀,又不是到了没有更新就完全用不了的地步,也有不少优秀的第三个插件可以使用,大版本估计最近就会发布,值得期待。
    5 回复
  • 膜拜大神!
    2 回复
  • 2 回复
  • @雷锋2班红领巾 可以做到,感觉正在慢慢像那边靠拢[偷笑] ,思路差不多,具体的实现方式调整一下
    2 回复
  • 柱华
    2019-5-9
    666666,功能太丰富了,点个赞
    2 回复
  • @固執的大叔 嗯,是有可能会有一些冲突,初略的看了一下他的赛选的设置也是在cols对应的列上加上filter,跟我的配置重叠了,当然具体还得看其实现的方法,才能找到更好的解决方案,目前除了这个过滤之外还有其他的问题吗?
    1 回复
  • tx
    2019-5-8
    这个IE不支持吧
    1 回复