美文网首页
jquery实现表格行自定义顺序

jquery实现表格行自定义顺序

作者: 超人鸭 | 来源:发表于2019-12-05 11:51 被阅读0次

    这次记录一下刚做的一个功能(需求),使用jquery实现表格行自定义顺序,由于实际工作中这个需求涉及到的条件比较多,所以超人鸭就直接按我工作中的情况来讲这个功能,不做模拟。
    先看看实现的具体功能:


    image.png

    表格行的排序是输入框,正常情况下是不可编辑的,当点击上面的编辑排序按钮后,就可以输入想要更换的顺序,并且显示右边的操作按钮:


    image.png
    点击保存后保存新的排序,并且表格行按排序更换顺序;点击取消排序号返回到编辑前的情况,并且隐藏操作按钮。这里有几个限制条件,第一,排序号不能重复;第二,排序的范围只能在原本的范围内。
    知道需求后开始整理思路:
    1. 输入框只能输入正整数,并且一开始是disable。
    2. 点击了编辑排序后,输入框全部要取消disable,然后显示后面的操作按钮。
    3. 点击取消后,排序号要退回到原来的值,所以要保存原本的排序,所以在上一个事件,点击编辑排序按钮的时候,就需要保存原本的排序,用一个数组保存起来,可以用each去遍历输入框,点击取消后要隐藏操作按钮与让输入框变成disable状态。
    4. 点击保存后,要根据限制条件做校验,先是最大值和最小值,编辑前的排序号已经被我用数组保存起来,所以用这个数组求得正确的最大最小值,然后需要求得编辑后的最大最小值,一样,用一个数组把编辑后的排序保存起来,求得最大最小值,去比较就可以。然后判断是否重复,把编辑后的排序号数组去重,然后和原数组比较长度就可以判断。
    5. 保存成功后,更换表格的顺序,这项目不是vue的数据渲染,所以只能操作dom,我的思路是用删除表格行再按特定的顺序插进去来实现,这里用到jq两个操作dom的api,prependafter,那如果获取到特定顺序的表格行呢,需要和输入框的做关联,输入的排序号是输入框的value,用到value选择器:
      $("input[value = '1']"),根据这个输入框来获取到表格行。
      接下来就是具体实现了,先看看大概的html:
    // 表格里面
    <table>
      <tbody>
        <tr>
          <td>
            <input type="text" name="order-input" disabled onkeyup="changeValue(this)" >
          </td>
        </tr>
        .....
      </tbody>
    </table>
    
    // 表格上面的按钮
    <span class="order-edit-btn">编辑排序</span>
    <div style="display: none;">
      <button class="save-order-btn">保存</button>
      <button class="cancel-order-btn">取消</button>
    </div>
    

    大概的html就是这样,因为实际开发还有其他条件,所以都是用class来当选择器。接下来是实现:

    1. 输入框的限制放在最后,涉及到其他问题,首先点击编辑排序的时候:
    var orderList = []  // 保存原排序的数组,全局变量
    var maxOrder = 0  // 正确的最大值,全局变量
    var minOrder = 0 // 正确的最小值,全局变量
    
    $(".order-edit-btn").click(function () {
      $(this).next().show() // 显示操作按钮
      $('table').find("input[name='order-input']").attr("disabled",false)  // 让序号输入框可以输入
      
      orderList = []  // 重置
      $('table').find("input[name='order-input']").each(function(){  // 得到全部序号的数组
        orderList.push(parseInt($(this).val()))
      })
      
      maxOrder = Math.max.apply(Math,orderList)  // 得到最大值
      minOrder = Math.min.apply(Math,orderList)  // 得到最小值
    })
    
    1. 点击取消按钮的事件:
    $(".cancel-order-btn").click(function() {
      $('table').find("input[name='order-input']").each(function (index) {  // 让排序号撤回到编辑前的值
        $(this).val(orderList[index])
      })
    
      $('table').find("input[name='order-input']").attr("disabled",true) // 让序号不可编辑
      
      $(this).parent().hide()  // 隐藏操作按钮
    })
    
    1. 点击保存按钮,需要对新编辑的排序号做校验,所以需要再声明一个数组:
    $(".save-order-btn").click(function () {
      var newOrderList = []  // 保存编辑后的排序号
      $('table').find("input[name='order-input']").each(function() {
        newOrderList.push(parseInt($(this).val()))
      })
      var newMaxOrder = Math.max.apply(Math, newOrderList)  // 得到新的最大值
      var newMixOrder = Math.min.apply(Math, newOrderList)  // 得到新的最小值
      // 下面是校验
      if (newMixOrder < minOrder) {
        alert('最小值不能小于' + minOrder)
        return
      }
      if(newMaxOrder > maxOrder) {
        alert('最大值不能小于' + maxOrder)
        return
      }
      newOrderList = newOrderList.filter((x, index, self) => self.indexOf(x) === index)  // 去重
      if (newOrderList.length < orderList.length) {
        alert('不能出现重复序号')
        return
      }
    
      // 到这里如果没问题排序号就已经更新了,接下来是要实现表格行的更换顺序
      /*上面说到,需要先把表格行先删掉,再插入到对应的位置,这里离分为两种情况,第一条也就是序号为一的表格行和其他表格行,如果是第一条表格行就
        直接插入到表格的最上面,用到prepend,其他情况就是插到上一个行的后面,用到after,所以需要获取到上一个行的dom,下面看实现
      */
      var prevTrDom = null  // 保存上一个行的dom
      for (var i = minOrder; i <= maxOrder; i++) {
        if (i === minOrder) {  // 如果是第一行的情况下
          let temDom = $("input[name='order-input'][value = " + i + "]").parent().parent() // 保存这个tr的dom,重要
          $("input[name='order-input'][value = " + i + "]").parent().parent().remove()  // 先将这个dom在表格里面删掉
          $('table').find('tbody').prepend(temDom) // 在表格的最前面插入这个行
          prevTrDom = temDom  // 此时代表上一行的dom就是这一行 
    
        } else {   // 除了第一行的其他行
          let temDom = $("input[name='order-input'][value = " + i + "]").parent().parent() // 同样要先保存
          $("input[name='order-input'][value = " + i + "]").parent().parent().remove()  // 删掉
          prevTrDom.after(temDom) // 插入
          prevTrDom = temDom  // 更新代表上一行的dom
        }
      }
    
      $('table').find("input[name='order-input']").attr("disabled", true)  // 同样让输入框恢复不可编辑
      $(this).parent().hide()  // 隐藏操作按钮
    })
    

    理论上来说,写到这里除了输入框的限制输入正整数外,需求功能都实现了。但还有一个问题,看上面的实现表格更换顺序,里面最关键的就是获取到与排序号关联的表格行tr:

     $("input[name='order-input'][value = " + i + "]").parent().parent()
    

    我用到input的value选择器,注意里面如果要写变量要想我那样写,不然 i 会被识别成字符串。可能是之前做的都是vue的项目,都习惯了数据的双向绑定与动态更新,但是在原生dom里面的输入框,当你输入后,它的value是不会实时更新的:


    image.png

    可以看到还是我改变前输入的值,所以上面说到的排序号,虽然我编辑了,输入框的值改变了,但是它的value还是没有变,所以上面的实现表格更换顺序会没有反应,所以现在的问题就是实现输入框一输入,它的value就会更新,超人鸭在百度找到了一个方法,刚好可以和限制输入框只能输入正整数写在一起。还记得我上面写的输入框的html代码吗?

    <input type="text" name="order-input" disabled onkeyup="changeValue(this)" >
    

    监听输入框的onkeyup事件:

    function changeValue(obj) {
      $(obj).attr("value",$(obj).val().replace(/^(0+)|[^\d]+/g,''));
    }
    

    实现了输入框vlaue的实时更新与正则匹配过滤掉非正整数。
    到这里就完成了所说的功能,欢迎留言指教。
    作者微信: ***Promise_fulfilled ***

    相关文章

      网友评论

          本文标题:jquery实现表格行自定义顺序

          本文链接:https://www.haomeiwen.com/subject/svtdgctx.html