Skip to content

jQuery常用表格操作

方跃明 2015-10-30

html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>常用表格操作</title>
  <link rel="stylesheet" href="http://cdn.bootcss.com/qtip2/3.0.3/jquery.qtip.min.css">
  <style>
  div {
    margin-bottom: 10px;
  }
  th span, td span {
    padding: 3px;
  }
  .zebra-false {
    background-color: #ccc;
  }
  .error {
    background-color: #f99;
  }
  </style>
</head>
<body>
  <div id="title">
    <button role="delete">删</button>
    <button role="insert">增</button>
  </div>
  <div id="data">
    <script id="tmpl" type="text/x-dot-template">
      <table border="1">
        <thead>
          <tr>
            <th role="check"><span><input type="checkbox"></span></th>
            <th><span>序号</span></th>
            <th><span>网址</span></th>
            <th><span>邮箱</span></th>
            <th><span>时间</span></th>
          </tr>
        </thead>
        <tbody>{{~it:v:k}}
          <tr>
            <td role="check"><span><input type="checkbox" value="{{=v.id}}"></span></td>
            <td role="index"><span></span></td>
            <td role="url"><span>{{=v.url}}</span></td>
            <td role="email"><span>{{=v.email}}</span></td>
            <td role="date"><span>{{=v.date}}</span></td>
          </tr>{{~}}
        </tbody>
      </table>
    </script>
  </div>
  <script src="http://cdn.bootcss.com/jquery/3.2.0/jquery.min.js"></script>
  <script src="http://cdn.bootcss.com/validator/7.0.0/validator.min.js"></script>
  <script src="http://cdn.bootcss.com/qtip2/3.0.3/jquery.qtip.min.js"></script>
  <script src="http://cdn.bootcss.com/dot/2.0.0-beta.0/doT.min.js"></script>
  <script>
  $(document).ready(function() {
    // 数据
    var data = [
      {"id": "1",  "url": "163.com",     "email": "admin@163.com",    "date": "2016-09-01"},
      {"id": "5",  "url": "163.com",     "email": "test@163.com",     "date": "2016-09-05"},
      {"id": "6",  "url": "163.com",     "email": "user@163.com",     "date": "2016-09-10"},
      {"id": "7",  "url": "google.com",  "email": "google@gmail.com", "date": "2004-06-06"},
      {"id": "8",  "url": "google.com",  "email": "admin@gmail.com",  "date": "2004-01-01"},
      {"id": "9",  "url": "google.com",  "email": "test@gmail.com",   "date": "2006-10-10"},
      {"id": "11", "url": "qq.com",      "email": "admin@qq.com",     "date": "2005-12-23"},
      {"id": "14", "url": "qq.com",      "email": "test@qq.com",      "date": "2008-09-01"},
      {"id": "15", "url": "baidu.com",   "email": "admin@baidu.com",  "date": "2003-02-01"},
      {"id": "16", "url": "baidu.com",   "email": "test@baidu.com",   "date": "2006-12-31"}
    ]
    // 模版
    var tmpl = doT.template($('#tmpl').text())
    // 编译模版
    $('#data').html(tmpl(data))
    // 斑马纹
    var zebra = true
    $('table tbody tr').each(function(e){
      $(this).addClass('zebra-' + zebra)
      if($(this).children('td[role="url"]').find('span').text() !=
         $(this).next().children('td[role="url"]').find('span').text()){
        zebra = !zebra
      }
    })
    // 序号
    var index = 0
    $('table tbody tr').each(function(){
      $(this).children('td[role="index"]').children('span').text(++index)
    })
    // 表格编辑
    var typing = false                                                 // 变量:可编辑
    var pretyping = ''                                                 // 变量:保存编辑前内容
    // 进入编辑
    $('table').on('dblclick', 'tbody tr', function(e){                 // 响应编辑事件
      if(typing) {                                                     // 有编辑未完成
        alert("输入进行中")
      } else {
        var el = $(this)
        pretyping = el.html()                                    // 保存编辑前内容
        el.children('td[role="check"]').find('span').html([      // 构建操作按钮
          '<button role="cancel">弃</button>',
          '<button role="save">存</button>'
        ].join('\n'))
        // 构建行内表单
        el.children('td:not([role="check"],[role="index"])').each(function(){
          $(this).html('<input type="text" value="' + $(this).text() + '">')
        })
        typing = true      // 正在编辑
      }
    })
    // 取消编辑
    $('table').on('click', 'td[role="check"] button[role="cancel"]', function(e){
      var el = $(this).parent().parent().parent()      // 定位到tr
      el.html(pretyping)                               // 恢复行原始数据
      typing = false                                   // 可编辑
    })
    // 保存编辑
    // TODO select, textarea, ...
    $('table').on('click', 'td[role="check"] button[role="save"]', function(e){
      var data = []                                    // 预定义数据(名称、验证、类型)
      var eq = 0                                       // 目前使用eq,考虑统一进预定义数据
      var el = $(this).parent().parent().parent()              // 元素定位
      var isValid = false                                      // 客户端验证
      el.children('td').each(function(){                      // 遍历单元格
        var val = $(this).find('input').val()                 // 取输入值
        undefined != val && data.push({ eq: eq, val: val })   // 按需保存
        eq++                                                  // 递增索引
      })
      isValid =                                              // 统一验证
        validator.isURL(data[0].val) &&
        validator.isEmail(data[1].val) &&
        validator.isISO8601(data[2].val)
      if(isValid) {                                         // 验证通过
        // TODO 新增、更新分支
        // TODO 服务端保存(AJAX回调)
        el.html(pretyping)                                  // 复原原始内容
        for(k in data) {                                    // 遍历数据
          el.children('td').eq(data[k].eq).find('span').html(data[k].val) // 按需填充
        }
        typing = false                                      // 恢复可编辑
      } else {
        // 验证失败
        alert('验证失败')
      }
    })
    // 数据格式提醒
    $('table').on('blur', 'input', function(e){
      var el = $(this).parent()
      var role = el.attr('role')
      var val = $(this).val()
      switch(role) {
        case 'url':
          validator.isURL(val) || tip(el, '网址格式错误')
        break
        case 'email':
          validator.isEmail(val) || tip(el, '邮箱格式错误')
        break
        case 'date':
          validator.isISO8601(val) || tip(el, '日期格式错误')
        break
        default:
        break
      }
    })
    // 消除错误提示
    $('table').on('focus', 'input', function(e){
      var el = $(this).parent()
      el.qtip('destroy')
      el.children().removeClass('error')
    })
    // 出错提醒函数
    var tip = function(el, text) {
      el.children().addClass('error')
      el.qtip({
        content: { text: text },
        position: { at: 'bottom center' },
        show: { ready: true, solo: true }
      })
    }
    // 全选、不选
    $('table').on('click', 'th[role="check"] input[type="checkbox"]', function(e){
      $('td input:nth-child(1)').prop('checked', $(this).is(':checked'))
    })
    // 删除选中
    $('#title').on('click', 'button[role="delete"]', function(e){
      var checked = []
      $('#data tbody tr').each(function(){
        var tr = $(this)
        var checkbox = tr.children('td[role="check"]').find('input[type="checkbox"]')
        checkbox.is(':checked') && checked.push(checkbox.val())
      })
      alert(JSON.stringify(checked))
    })
  })
</script>
</body>
</html>
WEB
JavaScript
jQuery