处理下拉在表格中看不到的选项的一种解决方案

讨论 未结 置顶 精帖
109 3216
岁月小偷
悬赏:80飞吻
正文的最下面有新的更新,主要处理select在layer中的效果的,如果已经读过本帖子对这个有兴趣的可以仔细看看更新的部分[微笑]
目前因为table设定,包括高度的限制,超出隐藏加上当前select的美化的形式,在table的td中显示一个下拉一般会出现看不到选项的情况,然后以前是把有下拉的td里面的div给添加一个overflow:auto的样式这样子就能看到了,但是大家如果使用过这个方法的话,有个问题就是下拉的选项的节点是属于表格内部的,会出现下拉选项的节点增加了table内部td的内容的大小,导致多出来滚动条,而且有小伙伴的表格刚好需要在固定列上显示,这个就更坑了,干脆出不来,这个是因为固定列比非固定列更多的限制;另外后面有人提供过一个方式是修改table的一些容器的overflow为visiable,这个实际如果遇到表格的记录比较多表格的高度有限制的时候就会出问题,下面的记录也都能看见;
这里提供多一种其他的方式大家看看好用不好用,思路就是既然在表格内部会出现这么多问题,那么如果我让他在一个layer中显示呢?也就是说在之前的方法都不加的情况下,点击下拉之后,把看不到的内容给他“借”到layer去显示,那么layer是不属于table内部的节点的,只要能确保事件还能连通之前的就可以了:
先看效果图:

关键代码:
1,给表格中的下拉的title部分添加点击事件处理,将下拉出来的内容拿到layer中去显示

里面大概的就是关掉之前的下拉选项弹窗(如果有的话),然后弹出一个容器,将选项添加到这个容器中,添加进去的dom对象实际就是从原始的select美化的节点中租借过来的,里面的事件啥的还是之前的,所以这个就完成了之前说的要连通点击的那个下拉的一半了,另外一半就是在end回调的时候记得要把对应的选项的dom节点还原回去select里面,不然关了layer销毁了后面select里面就没有选项的节点了,然后里面就是一些细节的处理了,比如弹出框的大小位置等等;
2,既然是一个弹窗,那么点击其他地方要跟select一样的效果,目前select它就是折叠起来这个选项的内容,那么弹窗正常的话就是要给关了,所以下面加了一些事件的处理:

实现的到这里就done了。
测试页面: https://sun_zoro.gitee.io/layuitableplug/testTableCheckboxDisabled
gitee项目:
附加一个简易实用的小功能,就是筛选列的时候添加一个全选和反选的快捷操作的支持

主要的实现代码:
更新于2019年1月10日11:41:30
有小伙伴在帖子里面回复了layer中的select如何处理?实际之前也有考虑这个问题,其实方式跟在table中的处理是差不多的,就是利用再弹一个layer来显示select的选项,只不过有一个难点,下面大概的介绍一下。
上面说的难点其实就是layer可以是弹出一个页面层,也可以是一个iframe。
单页面的其实很简单可以完全跟表格中的下拉一样的,只要在委托的事件中多加一类弹出的select的title点击,其他的不需要变就可以。
先看看原始的layer中如果有select的话高度不够会是什么效果:

处理的方法:

之前不变的情况下,加多个这个,就可以用了,但是!细节还是需要处理好的一个就是样式,因为原始的select的下拉的dl,显示出来的时候会导致内容高度变了,有可能会出现滚动条,那么就会压缩content的内容宽度,会有一个跳变的过程,所以反正要用layer去弹出了,索性加多一个样式把layer中的这些dl的样式给改成不可见的如下:

加上这些样式之后就不会有一个跳变的过程,用户体验更好。
效果:

下面关键的来了,iframe怎么办~如果弹出的是一个iframe,而且大小有限,即使它也引入了tablePlug也做了跟top一样的优化处理,但是!就目前的逻辑再让它去弹出一个layer显然范围会更小,那么是不是用parent去弹出呢?这个是个思路,毕竟父窗口大,但是也不保险其实,如果一个小的又弹出一个更小的呢?所以稳妥起见应该是让top去弹出,但是如果要说top也贼小,摊摊手,只能说那不是给普通人做的系统,估计是给蚁人看的。所以正常来说用top去弹出就可以了,那么之前的逻辑实际要做一个不小的改造,包括得到位移的算法,弹出的各种细节控制,这里就不一一都说明了,理解理解代码应该就知道思路了。修改如下
获得位移的算法:

点击弹出选项的主要代码:

最后是一些细节的事件处理:

效果:

最后留下一个思考:是否可以不管是什么状态下的下拉都改成这种layer弹出的?如果可以,好处当然就是不管什么场景下都不会出现说因为select的下拉导致了页面的内容高度的变化,也不会有因为被容器的overflow给影响看不到之类的问题,坏处嘛,改成layer要说一点也不影响性能效率那应该是不可能的,里面需要计算,也需要用layer去弹出。
回帖
  • @岁月小偷
    图1是定义的一个table,有一个添加活动的按钮,点击按钮调用图2的js方法,插入一个tr到table里面去,tr中有一个td定义了一个select,最后显示图3的效果,就是没有下拉框出来
    0 回复
  • @名烟黄鹤楼 嗯嗯,从你发出来的内容还是没能确定你是用的静态表格的形式(只是利用了layui-table来处理表格的样式)还是用的动态表格(后面用table.init将静态转成动态),但是关于图三没有出select这个知道为啥,是因为你动态插入的节点最后没有form.render去渲染它,详细见: https://www.layui.com/doc/modules/form.html#render
    0 回复
  • @岁月小偷 太感谢了,终于出来了,之前表单里面可以直接显示select就没记住这个,谢了
    0 回复
  • @名烟黄鹤楼 不客气额[微笑]
    0 回复
  • 每天都有惊喜。19年了,可以让心姐把你的几个plus合成进去了[嘻嘻]
    0 回复
  • @爱死寂寞人 期待3.0[偷笑]
    0 回复
  • [good] [good] [good]
    0 回复
  • 大佬,有没有弹出层中加下拉且弹出层可以出现滚动,但是下拉也可以超出弹出层的解决方案?
    .layui-layer-page .layui-layer-content {
    position: relative;
    overflow: visible !important;
    }
    修改css只能实现下拉超出弹出层,但是弹出层就无法出现滚动条了
    0 回复
  • @雷锋2班红领巾 弹出层可能稍微复杂点,也有考虑这个问题,弹出层的主要还会遇到的一个问题是会有type2的问题,如果弹出的iframe本来就很小,那么应该是用父亲的或者顶层的去弹出才能足够它显示,页面层倒是好处理额,大概就是给需要这样子处理的select加上一个特殊的class,然后也给这些节点的美化select加上事件就好,主要难点还得处理iframe之间的问题我觉得,可以自己试试看哈,我今天找时间实践一下看看
    0 回复
  • @岁月小偷 那单页面的呢?加上css可以实现下拉超出,但是弹出层的滚动条就没有了
    0 回复
  • @雷锋2班红领巾 单页面的可以按照在表格一样的处理方式,
    0 回复
  • 可以可以~受教了
    0 回复
  • 学习了!好东西
    0 回复
  • @岁月小偷 现在又有一个问题了,图三是点击加号之后添加的一个tr,计划开始日期和完成日期是日期输入框,如果定义id,可以通过render显示出来,可是点击加号再添加第二个tr的时候,这个方法就没有用了,没有日期输入框出来,请问怎么解决呢
    0 回复
  • @名烟黄鹤楼 这个请移步到我另外一个帖子: https://fly.layui.com/jie/42166/ ,主要问题是你定义id,那么应该每个都是唯一的,不能出现很多id重复的节点,这个从根本上就是不应该的,可能到这里你会考虑换成class,然后通过elem:'.XXX'的形式,实际这个也不行,因为目前laydate不支持一次性render多个节点,上面那个帖子主要处理的有两个,一个是一次性render多个节点,另外一个是重复render来更新已经render过的节点;但是如果要简单的使用的话实际elem不单单是可以写#id .class这种形式,还能是一个dom对象,所以正确的使用方式应该是你新增一条记录的还是就去遍历一下里面需要render成laydate的节点,对他们的dom对象进行render这个可以看看更早之前的一个帖子: https://fly.layui.com/jie/27108/
    0 回复
  • @岁月小偷 下午自己试试
    0 回复
  • 介秀敏
    2019-1-10
    select 特殊字符 选不了 选之后,有短暂的显示,但 立马被清空了
    没有特殊字符的正常.
    0 回复
  • @介秀敏 嗯嗯,在原始的layui的表单不会有这个现象是么?还是原始的表单会,我倒是没遇到过这样子的额,能提供一下你这个表单的dom结构吗?我本地试试看。@小小爬虫丁 嗯嗯,看看有没有使用价值,有bug的话记得反馈哈[嘻嘻]
    0 回复
  • 介秀敏
    2019-1-10
    使用的是layui from select,原生的不会有这个现象
    <form class="layui-form" >
    <select name="number" lay-search lay-filter="test" >
    <option value=""></option>
    </select>
    </form>
    js 拼接 var html = '<option value=""></option>'; 动态的
    完了form.render() 整个表单
    0 回复
  • 介秀敏
    2019-1-10
    通过form.val 回显值 也有问题 特殊符号 被layui去掉了
    0 回复
  • @介秀敏 你是说一开始没有这个选项的里面,然后通过form.val赋值的时候赋了一个特殊符号它会在选项中添加一个选项是么?这个真心没遇到过额,也不知道你说的特殊符号是有多特殊,有的话提供一下你赋值的相关数据,这边可以试试看会不会
    0 回复
  • util6
    2019-1-10
    厉害[good] [good] [good]
    0 回复
  • 等待2018
    2019-1-10
    大赞小偷的无私奉献以及刻苦钻石的精神~~~~~~~
    0 回复
  • Pojin
    2019-1-11
    @岁月小偷 非常好,建议贤心尽快加入到下一个版本中。
    0 回复
  • 0 回复
  • 介秀敏
    2019-1-11
    特殊符号 只有 双引号;
    现在选中已经解决了,只要把layui slect 监听事件中把对应生成的input随便赋个值,就能选中了;
    0 回复
  • 应该合并到layui中去。
    0 回复
  • 大神,有没有什么办法做到每个单元格控制他有没有下拉,比如第一行的某个单元格有下拉,第二行没有,就是我截图的那个红框里没有下拉,有什么思路吗
    0 回复
  • @旺仔qq糖 这个可以通过templet实现额,templet中根据条件去决定显示什么
    0 回复
  • @岁月小偷 如果需要根据表格的数据动态的改变这些显示呢,比如重新渲染之后
    0 回复