Reorder HTML table rows using drag-and-drop

后端 未结 7 636
無奈伤痛
無奈伤痛 2021-01-29 23:00

I have a jQuery function to move table rows up and down. I do not know how to save the data, nor get the position of each row. I am using PHP to show the table rows.

How

7条回答
  •  刺人心
    刺人心 (楼主)
    2021-01-29 23:37

    Building upon the fiddle from @tim, this version tightens the scope and formatting, and converts bind() -> on(). It's designed to bind on a dedicated td as the handle instead of the entire row. In my use case, I have input fields so the "drag anywhere on the row" approach felt confusing.

    Tested working on desktop. Only partial success with mobile touch. Can't get it to run correctly on SO's runnable snippet for some reason...

    let ns = {
      drag: (e) => {
        let el = $(e.target),
          d = $('body'),
          tr = el.closest('tr'),
          sy = e.pageY,
          drag = false,
          index = tr.index();
    
        tr.addClass('grabbed');
    
        function move(e) {
          if (!drag && Math.abs(e.pageY - sy) < 10)
            return;
          drag = true;
          tr.siblings().each(function() {
            let s = $(this),
              i = s.index(),
              y = s.offset().top;
            if (e.pageY >= y && e.pageY < y + s.outerHeight()) {
              i < tr.index() ? s.insertAfter(tr) : s.insertBefore(tr);
              return false;
            }
          });
        }
    
        function up(e) {
          if (drag && index !== tr.index())
            drag = false;
    
          d.off('mousemove', move).off('mouseup', up);
          //d.off('touchmove', move).off('touchend', up); //failed attempt at touch compatibility
          tr.removeClass('grabbed');
        }
        d.on('mousemove', move).on('mouseup', up);
        //d.on('touchmove', move).on('touchend', up);
      }
    };
    
    $(document).ready(() => {
      $('body').on('mousedown touchstart', '.drag', ns.drag);
    });
    .grab {
      cursor: grab;
      user-select: none
    }
    
    tr.grabbed {
      box-shadow: 4px 1px 5px 2px rgba(0, 0, 0, 0.5);
    }
    
    tr.grabbed:active {
      user-input: none;
    }
    
    tr.grabbed:active * {
      user-input: none;
      cursor: grabbing !important;
    }
    
    
    Drag the rows below...

提交回复
热议问题