Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

改进可编辑单元格 #1650

Open
4 tasks done
starsphp opened this issue Feb 22, 2024 · 1 comment
Open
4 tasks done

改进可编辑单元格 #1650

starsphp opened this issue Feb 22, 2024 · 1 comment
Labels
enhancement 改进或增强 good reproduction 提供了良好重现的议题,可以优先处理

Comments

@starsphp
Copy link

议题条件

  • 我确认已查看官方使用文档:https://layui.dev ,但没有找到相关解决方案。
  • 我确认已在 Issues 中搜索过类似的问题,但没有找到相关解决方案。
  • 我已仔细阅读: 🍀 Layui Issue 贡献指南

议题类型

疑是 BUG

使用版本

V2.9.6

问题描述

v2.9.5和V2.9.6都尝试了,table.updateRow能正常更新数据,但是当前行如果有对应事件按钮,事件丢失并失效,在行中使用dropdown时,调用table.updateRow更新数据后,dropdown的事件会丢失(laydate事件也丢失)

业务代码

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Demo</title>
  <!-- 请勿在项目正式环境中引用该 layui.css 地址 -->
  <link href="http://unpkg.com/layui@2.9.6/dist/css/layui.css" rel="stylesheet">
</head>
<body>
<table class="layui-hide" id="ID-table-demo-editmodes"></table>
<!-- 原生 select 模板(推荐) -->
<script type="text/html" id="TPL-select-primary">
  {{#  var cityList = d.cityList || ["北京","上海","广州","城市-1"]; }}
  <select name="city" class="layui-border select-demo-primary" lay-ignore>
    <option value="">原生 select</option>
    {{#  layui.each(cityList, function(i, v){ }}
    <option value="{{= v }}" {{= v === d.city ? 'selected' : '' }}>{{= v }}</option>
    {{#  }); }}
  </select> 
</script>
<!-- layui select 在 table 中使用(不推荐。因为当 select 出现在 table 底部时,可能会撑起多余高度) -->
<script type="text/html" id="TPL-select-city">
  {{#  var cityList = d.cityList || ["北京","上海","广州","城市-1"]; }}
  <select name="city" lay-filter="select-demo">
    <option value="">select 方式</option>
    {{#  layui.each(cityList, function(i, v){ }}
    <option value="{{= v }}" {{= v === d.city ? 'selected' : '' }}>{{= v }}</option>
    {{#  }); }}
  </select> 
</script>
<!-- 推荐 -->
<script type="text/html" id="TPL-dropdpwn-demo">
  <button class="layui-btn layui-btn-primary dropdpwn-demo">
    <span>{{= d.sex || '保密' }}</span>
    <i class="layui-icon layui-icon-down layui-font-12"></i>
  </button>
</script>
<!-- laydate -->
<script type="text/html" id="TPL-laydate-demo">
  <input class="layui-input laydate-demo" placeholder="选择日期" value="{{= d.fieldname3 || '' }}">
</script>
<!-- colorpicker -->
<script type="text/html" id="TPL-colorpicker-demo">
  {{#  var color = d.color || ['#16baaa','#16b777','#1E9FFF','#FF5722','#FFB800','#393D49'][Math.round(Math.random()*5)]; }}
  <div class="colorpicker-demo" lay-options="{color: '{{= color }}'}"></div>
</script>
  
<!-- 请勿在项目正式环境中引用该 layui.js 地址 -->
<script src="http://unpkg.com/layui@2.9.6/dist/layui.js"></script>
<script>
    var data = [
            {
                "id": 10000,
                "username": "user-0",
                "sex": "女",
                "city": "城市-0",
                "sign": "签名-0",
                "experience": 255,
                "logins": 24,
                "words": 82830700,
                "classify": "作家",
                "score": 57
            },
            {
                "id": 10001,
                "username": "user-1",
                "sex": "男",
                "city": "城市-1",
                "sign": "签名-1",
                "experience": 884,
                "logins": 58,
                "words": 64928690,
                "classify": "词人",
                "score": 70.5
            },
            {
                "id": 10002,
                "username": "user-2",
                "sex": "女",
                "city": "城市-2",
                "sign": "签名-2",
                "experience": 650,
                "logins": 77,
                "words": 6298078,
                "classify": "酱油",
                "score": 31
            },
            {
                "id": 10003,
                "username": "user-3",
                "sex": "女",
                "city": "城市-3",
                "sign": "签名-3",
                "experience": 362,
                "logins": 157,
                "words": 37117017,
                "classify": "诗人",
                "score": 68
            },
            {
                "id": 10004,
                "username": "user-4",
                "sex": "男",
                "city": "城市-4",
                "sign": "签名-4",
                "experience": 807,
                "logins": 51,
                "words": 76263262,
                "classify": "作家",
                "score": 6
            },
            {
                "id": 10005,
                "username": "user-5",
                "sex": "女",
                "city": "城市-5",
                "sign": "签名-5",
                "experience": 173,
                "logins": 68,
                "words": 60344147,
                "classify": "作家",
                "score": 87
            },
            {
                "id": 10006,
                "username": "user-6",
                "sex": "女",
                "city": "城市-6",
                "sign": "签名-6",
                "experience": 982,
                "logins": 37,
                "words": 57768166,
                "classify": "作家",
                "score": 34
            },
            {
                "id": 10007,
                "username": "user-7",
                "sex": "男",
                "city": "城市-7",
                "sign": "签名-7",
                "experience": 727,
                "logins": 150,
                "words": 82030578,
                "classify": "作家",
                "score": 28
            },
            {
                "id": 10008,
                "username": "user-8",
                "sex": "男",
                "city": "城市-8",
                "sign": "签名-8",
                "experience": 951,
                "logins": 133,
                "words": 16503371,
                "classify": "词人",
                "score": 14
            },
            {
                "id": 10009,
                "username": "user-9",
                "sex": "女",
                "city": "城市-9",
                "sign": "签名-9",
                "experience": 484,
                "logins": 25,
                "words": 86801934,
                "classify": "词人",
                "score": 75
            }
        ]
layui.use(function(){
  var $ = layui.$;
  var table = layui.table;
  var form = layui.form;
  var dropdown = layui.dropdown;
  var laydate = layui.laydate;
  var colorpicker = layui.colorpicker;
  
  // 渲染
  table.render({
    elem: '#ID-table-demo-editmodes',
    data: data,
    //url: 'http://layui.dev/static/json/2/table/user.json', // 此处为静态模拟数据,实际使用时需换成真实接口
    page: true,
    css: [ // 设置单元格样式
      // 取消默认的溢出隐藏,并设置适当高度
      '.layui-table-cell{height: 50px; line-height: 40px;}',
      '.layui-table-cell .layui-colorpicker{width: 38px; height: 38px;}',
      '.layui-table-cell select{height: 36px; padding: 0 5px;}'
    ].join(''),
    cols: [[ // 表头
      {field: 'id', title: 'ID', width:80, align: 'center', fixed: 'left'},
      {field: 'city', title: '原生 select', width:135, unresize: true, templet: '#TPL-select-primary'}, 
      //{field: 'city', title: 'layui select', width:150, templet: '#TPL-select-city'}, 
      {field: 'sex', title: 'dropdown', width:115, unresize: true, align: 'center', templet: '#TPL-dropdpwn-demo'}, 
      {field: 'date', title: 'laydate', width:150, templet: '#TPL-laydate-demo'}, 
      {field: 'color', title: 'color', width:80, unresize: true, align: 'center', templet: '#TPL-colorpicker-demo'},
      {field: 'sign', title: '文本', edit: 'textarea'}
    ]],
    done: function(res, curr, count){
      var options = this;
      
      // 获取当前行数据
      table.getRowData = function(tableId, elem){
        var index = $(elem).closest('tr').data('index');
        return table.cache[tableId][index] || {};
      };
      
      // 原生 select 事件
      var tableViewElem = this.elem.next();
      tableViewElem.find('.select-demo-primary').on('change', function(){
        var value = this.value; // 获取选中项 value
        var data = table.getRowData(options.id, this); // 获取当前行数据(如 id 等字段,以作为数据修改的索引)
        // 更新数据中对应的字段
        data.city = value;
        // 显示 - 仅用于演示
        layer.msg('选中值: '+ value +'<br>当前行数据:'+ JSON.stringify(data));
      });
      
      // layui form select 事件
      form.on('select(select-demo)', function(obj){
        console.log(obj); // 获取选中项数据
        
        // 获取当前行数据(如 id 等字段,以作为数据修改的索引)
        var data = table.getRowData(options.id, obj.elem);
        // 更新数据中对应的字段
        data.city = value;
        console.log(data);
      });
      
      // dropdown 方式的下拉选择
      dropdown.render({
        elem: '.dropdpwn-demo',
        // trigger: 'hover',
        // 此处的 data 值,可根据 done 返回的 res 遍历来赋值
        data: [{
          title: '男',
          id: 100
        },{
          title: '女',
          id: 101
        },{
          title: '保密',
          id: 102
        }],
        click: function(obj){
          var data = table.getRowData(options.id, this.elem); // 获取当前行数据(如 id 等字段,以作为数据修改的索引)
          
          this.elem.find('span').html(obj.title);
          // 更新数据中对应的字段
          data.sex = obj.title;
          // 显示 - 仅用于演示
          layer.msg('选中值: '+ obj.title +'<br>当前行数据:'+ JSON.stringify(data));
        }
      });
      
      // laydate
      laydate.render({
        elem: '.laydate-demo',
        done: function(value, date, endDate){
          var data = table.getRowData(options.id, this.elem); // 获取当前行数据(如 id 等字段,以作为数据修改的索引)
          // 更新数据中对应的字段
          data.date = value;
          
          // 显示 - 仅用于演示
          layer.msg('选中值: '+ value +'<br>当前行数据:'+ JSON.stringify(data));
        }
      });
      
      // colorpicker
      colorpicker.render({
        elem: '.colorpicker-demo',
        done: function(value){
          var data = table.getRowData(options.id, this.elem); // 获取当前行数据(如 id 等字段,以作为数据修改的索引)
          // 更新数据中对应的字段
          data.color = value;
          
          // 显示 - 仅用于演示
          layer.msg('选中值: '+ value +'<br>当前行数据:'+ JSON.stringify(data));
        }
      });
      
      // 单元格普通编辑事件
      table.on('edit(ID-table-demo-editmodes)', function(obj){
        var value = obj.value // 得到修改后的值
        var data = obj.data // 得到所在行所有键值
        var field = obj.field; // 得到字段
        
        // 更新数据中对应的字段
        var update = {};
        update[field] = value;
        obj.update(update);
        
        // 编辑后续操作,如提交更新请求,以完成真实的数据更新
        // …
        
        // 显示 - 仅用于演示
        layer.msg('编辑值: '+ value +'<br>当前行数据:'+ JSON.stringify(data));
      });
      
      // 更多编辑方式……
    }
  });
  setTimeout(() => {
    var d1 = {
        "id": 10000,
        "username": "user-0",
        "sex": "女",
        "city": "城市-1",
        "sign": "签名-0 - table.updateRow",
        "experience": 255,
        "logins": 24,
        "words": 82830700,
        "classify": "作家",
        "score": 57,
        "color": "#38b080"
    }
    // 更新指定行数据
    table.updateRow('ID-table-demo-editmodes', {
        index: 0,
        data: d1,
        // 是否更新关联的列视图
        related: function(field, index){
            return true;
        }
    })
  }, 2000);
});
</script>

</body>
</html>

截图补充

No response

浏览器

Microsoft Edge 版本 121.0.2277.128 (正式版本) (64 位)

演示地址

No response

友好承诺

  • 我承诺将本着相互尊重、理解和友善的态度进行交流,共同维护 Layui 良好的社区氛围。
@Sight-wcg Sight-wcg added the usage 用法问题 label Feb 22, 2024
@Sight-wcg
Copy link
Collaborator

但是当前行如果有对应事件按钮,事件丢失并失效

按钮事件推荐使用事件委托解决,例如单元格工具事件或者 util.on() 等

dropdown的事件会丢失(laydate事件也丢失)

就像动态插入的表单元素需要主动执行 form.render() 一样,此处需要主动重新渲染组件

这不是 BUG,后续看看有没有办法增强可编辑单元格,简化用法。

@Sight-wcg Sight-wcg added good reproduction 提供了良好重现的议题,可以优先处理 enhancement 改进或增强 and removed good reproduction 提供了良好重现的议题,可以优先处理 labels Feb 22, 2024
@Sight-wcg Sight-wcg added the good reproduction 提供了良好重现的议题,可以优先处理 label Mar 13, 2024
@Sight-wcg Sight-wcg changed the title table.updateRow 方法用于更新指定行存在一个BUG, 改进可编辑单元格 Apr 28, 2024
@Sight-wcg Sight-wcg removed the usage 用法问题 label Apr 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement 改进或增强 good reproduction 提供了良好重现的议题,可以优先处理
Projects
None yet
Development

No branches or pull requests

2 participants