테이블과 tr 너비로 정렬 가능한 jquery UI


155

테이블 그리드를 정렬 가능하게 만들기 위해 jQuery UI를 정렬 가능하게 사용하고 있습니다. 코드는 정상적으로 작동하는 것 같지만 tds에 너비를 추가하지 않기 때문에 드래그 tr하면 내용이 축소됩니다.

예를 들어; 드래그를 시작할 때 테이블 행이 500px이면 300px가됩니다. 그리드에 너비가 정의되어 있지 않기 때문에 발생한다고 가정합니다. tds ( fixliquid)에 두 개의 클래스를 사용하고 있기 때문 입니다.

fix클래스하게 td콘텐츠 폭 같고 liquid차종 td폭을 100 %. 너비를 tds 에 할당하지 않고 그리드 테이블에 대한 나의 접근 방식입니다 .

내 접근 방식으로 정렬 가능한 작업을 수행하는 방법을 알고 있습니까?


3
야로슬라프의 대답은 REAL mvp입니다!
Brade

나는 같은 문제를 겪었다. @Yaroslav는 OP가 요구하는 테이블을 다루는 정답을 가지고 있다고 생각한다
doz87

답변:


254

나는 여기서 답을 찾았다 .

원본에 너비를 추가하는 대신 행을 복제하도록 약간 수정했습니다.

  helper: function(e, tr)
  {
    var $originals = tr.children();
    var $helper = tr.clone();
    $helper.children().each(function(index)
    {
      // Set helper cell sizes to match the original sizes
      $(this).width($originals.eq(index).width());
    });
    return $helper;
  },

@Dave James Miller 자리 표시 자 옵션을 어떻게 작동하게 하시겠습니까?
shaun5

5
Dave, 이것을 공유해 주셔서 감사합니다. 나는 jsFiddle을 수정하여 원래 수정, 수정되지 않은 수정, jsfiddle.net/bgrins/tzYbU 의 차이점을 보여 주었습니다 . 또한 귀하의 솔루션으로 원본 게시물을 업데이트 할 것입니다.
Brian Grinstead

9
이것은 꽤 잘 작동하지만 여전히 약간의 문제가 있다고 생각합니다. 행을 끌어서 놓을 때 행이 누락되어 나머지 테이블 열의 너비가 변경 될 수 있습니다. 너비도 고정해야한다고 생각합니다.
Jez

1
이것은 나에게 많은 일을 저장했다. 정답으로 표시해야합니다.
앤드류 베사

3
너비가 QUITE가 아닌 패딩 된 셀을 초래한다는 것을 알았습니다. 나는 교환했다$(this).width($originals.eq(index).outerWidth());
Barry Carlyon

166

도움이 될 것 같습니다.

.ui-sortable-helper {
    display: table;
}

13
이것이 어떻게 정답이 아닌가? CSS의 간단한 한 줄이 나를 위해 수정합니다.
jcrowson

8
나는 동의한다! 한 줄의 CSS가 정렬 가능한 테이블을 어떻게 수정하는지 믿지 못할 것입니다.
Brade

3
이것이 답입니다. 감사합니다 @Yaroslav
Steffi

3
이것은 일반적인 해결책이 아니며 드래그 된 행을 다르게 보일 것입니다
Tomas M

13
이 솔루션은 매우 좋지만 테이블이 아닌 다른 목록에 영향을 줄 수 있습니다. 내 제안은 더 구체적으로 만들 수 있도록 답변을 편집하는 것입니다. 다음과 같이 => table tr.ui-sortable-helper {display : table! important; }
Rafael Gomes Francisco

29

여기에 선택된 대답은 정말 좋은 해결책이지만 원래 JS 바이올린 ( http://jsfiddle.net/bgrins/tzYbU/ )에 명백한 심각한 버그가 있습니다 . 가장 긴 행을 드래그하십시오 ( God Bless You, Mr Rosewater ) 및 나머지 셀 너비가 축소됩니다.

즉, 드래그 한 셀의 셀 너비를 고정하는 것만으로는 충분하지 않습니다. 또한 테이블의 너비를 수정해야합니다.

$(function () {
    $('td, th', '#sortFixed').each(function () {
        var cell = $(this);
        cell.width(cell.width());
    });

    $('#sortFixed tbody').sortable().disableSelection();
});

JS 피들 : http://jsfiddle.net/rp4fV/3/

이렇게하면 첫 번째 열을 드래그 한 후 테이블이 축소되는 문제가 해결되지만 새로운 열이 도입됩니다. 테이블의 내용을 변경하면 셀 크기가 수정됩니다.

내용을 추가하거나 변경할 때이 문제를 해결하려면 너비 설정을 지워야합니다.

$('td, th', '#sortFixed').each(function () {
    var cell = $(this);
    cell.css('width','');
});

그런 다음 컨텐츠를 추가 한 다음 너비를 다시 수정하십시오.

이것은 특히 테이블에서 드롭 자리 표시자가 필요하기 때문에 완벽한 솔루션이 아닙니다. 이를 위해 시작시 자리 표시자를 작성하는 함수를 추가해야합니다.

$('#sortFixed tbody').sortable({
    items: '> tr',
    forcePlaceholderSize: true,
    placeholder:'must-have-class',
    start: function (event, ui) {
        // Build a placeholder cell that spans all the cells in the row
        var cellCount = 0;
        $('td, th', ui.helper).each(function () {
            // For each TD or TH try and get it's colspan attribute, and add that or 1 to the total
            var colspan = 1;
            var colspanAttr = $(this).attr('colspan');
            if (colspanAttr > 1) {
                colspan = colspanAttr;
            }
            cellCount += colspan;
        });

        // Add the placeholder UI - note that this is the item's content, so TD rather than TR
        ui.placeholder.html('<td colspan="' + cellCount + '">&nbsp;</td>');
    }
}).disableSelection();

JS 피들 : http://jsfiddle.net/rp4fV/4/


감사합니다, 당신은 내 시간을 절약
super pantera

여기서 자리 표시 자 기술은 킬러입니다! 내 문제를 완전히 해결했습니다.
jessegavin

1
이 솔루션은 실제로 정말 좋고 자리 표시 자 기술은 실제로 견고합니다. 이것이 제 의견으로는 선택된 대답이어야합니다.
Chris James Champeau

1
행이 매우 높은 경우에도 여전히 불쾌한 동작이 발생합니다. 다른 모든 행은 그 뒤에 숨겨집니다. 나는 이것을 start 메소드에 추가 할 것이다 :$(".must-have-class").css("height", $(ui.item).outerHeight());
Itzik Ben Hutta

6

IE8에서는 행 복제가 제대로 작동하지 않지만 원래 솔루션은 작동하지 않는 것 같습니다.

jsFiddle로 테스트했습니다 .


jsFiddle을 설정해 주셔서 감사합니다. Jez가 지적한 것처럼 행을 드래그 할 때 다른 행 셀의 너비가 변경 될 수 있기 때문에 원래 솔루션을 사용하고 있습니다.
Roger

4

테이블을 정렬 할 준비가되면이 코드를 호출하면 테이블 구조를 손상시키지 않고 td 요소가 고정됩니다.

 $(".tableToSort td").each(function () {
            $(this).css("width", $(this).width());
        });  

광산이 작동하지만 예, 즉, 내 대답과 같은 꽤 많이입니다 th뿐만 아니라 td. 드래그 된 행 축소 및 테이블 축소를 수정하지만 너비를 수정해야합니다.
Keith

1

jsFiddle

많은 다른 시도 후 방금 축소 된 테이블을 방지하기 위해 Dave James Miller의 솔루션을 완성하는 간단한 솔루션을 시도했습니다. 나는 그것이 도움이되기를 바랍니다 :)

// Make sure the placeholder has the same with as the orignal
var start = function(e, ui) {
    let $originals = ui.helper.children();
    ui.placeholder.children().each(function (index) {
        $(this).width($originals.eq(index).width());
    });
}
// Return a helper with preserved width of cells
var helper = function(e, tr) {
    let $helper = tr.clone();
    let $originals = tr.children();
    $helper.children().each(function (index) {
        $(this).width($originals.eq(index).outerWidth(true));
    });
    return $helper;
};

0

Keith의 솔루션은 훌륭하지만 Firefox에서 약간의 혼란을 야기하여 colspan을 추가하지 않고 신호를 줄였습니다. (무릎에 오래된 JS 스트링 타입 통증)

이 줄 바꾸기 :

 cellCount += colspan;

와:

 cellCount += colspan-0;

문제를 해결합니다. (js는 변수를 문자열 대신 숫자로 취급해야하므로)


0

Dave James Miller의 답변이 저에게 도움이되었지만 내 페이지의 컨테이너 div 레이아웃으로 인해 마우스 커서로 드래그하는 도우미가 마우스 위치에서 오프셋됩니다. 이를 해결하기 위해 도우미 콜백에 다음을 추가했습니다.

$(document.body).append($helper);

위의 줄이 추가 된 완전한 콜백은 다음과 같습니다.

helper: function (e, tr) {
  var $originals = tr.children();
  var $helper = tr.clone();
  $helper.children().each(function (index) {
    // Set helper cell sizes to match the original sizes
    $(this).width($originals.eq(index).width());
  });

  // append it to the body to avoid offset dragging
  $(document.body).append($helper);

  return $helper;
}

Dave의 답변에이 내용을 주석으로 추가했지만이 계정에 대해 충분한 담당자가 없습니다.


jQuery 문서를 읽은 후 sortable은 도우미가 추가되는 요소를 지정하는 "appendTo"옵션도 사용한다는 것을 알았습니다.
Shea Riley

0

것 같다 disableSelection()방법은 나쁜 요즘되지이다 -. 에서 더 이상 정렬 가능한 행 안에 텍스트 입력을 사용할 수 없습니다 Mozilla Firefox 35.0. 더 이상 초점을 맞출 수 없습니다.


-1
$(function() {
    $( "#sort tbody" ).sortable({
        update: function () {
                                var order = $(this).sortable("toArray").join();
                                $.cookie("sortableOrder", order);
                        }
    });
    if($.cookie("sortableOrder")){
        var order = $.cookie("sortableOrder").split(",");
        reorder(order, $("#sort tbody"));
    }
    function reorder(aryOrder, element){
      $.each(aryOrder, function(key, val){
              element.append($("#"+val));
      });
    }
  });

1
더 많은 설명이 필요합니다!
Afsanefda

-1
.sortable({
    helper: function (e, ui) {
        ui.children().each(function () {
            $(this).width($(this).width());
        });
        return ui;
    }
});

-4

jquery-ui의 API에 설명 된대로 정렬 가능을 테이블의 tbody 요소에 적용하고 도우미를 '복제'로 설정하십시오.

$("$my-table-tbody").sortable({
    helper: "clone"
});

1
도움이되지 않는 것 같습니다.
앤드류
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.