jquery UI Sortable พร้อมโต๊ะและความกว้าง tr


155

ฉันใช้ jQuery UI ที่สามารถจัดเรียงได้เพื่อทำให้ตารางตารางของฉันเรียงลำดับได้ ดูเหมือนว่ารหัสจะทำงานได้ดี แต่เนื่องจากฉันไม่ได้เพิ่มความกว้างให้กับtds เมื่อฉันลากtrมันทำให้เนื้อหาหดตัว

ตัวอย่างเช่น; หากแถวตารางของฉันคือ 500px เมื่อฉันเริ่มลากมันจะกลายเป็น 300px ฉันคิดว่ามันเกิดขึ้นเพราะไม่มีการกำหนดความกว้างในตาราง นั่นเป็นเพราะฉันใช้สองคลาสสำหรับtds ( fixและliquid)

fixระดับทำให้tdเท่ากับความกว้างของเนื้อหาและliquidทำให้tdความกว้าง 100% มันเป็นวิธีการของฉันสำหรับตารางตารางโดยไม่ต้องกำหนดความกว้างtdของ

ความคิดใด ๆ ที่ทำให้การจัดเรียงทำงานกับแนวทางของฉันได้อย่างไร


3
คำตอบของ Yaroslav คือ 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
เดฟขอบคุณสำหรับการแบ่งปันนี้ผมได้ทำ jsFiddle เพื่อแสดงให้เห็นความแตกต่างระหว่างเดิมแก้ไขและแก้ไขปัญหาไม่มีที่ใช้: jsfiddle.net/bgrins/tzYbU ฉันจะอัปเดตโพสต์ดั้งเดิมด้วยโซลูชันของคุณ
Brian Grinstead

9
มันใช้งานได้ดี แต่ฉันคิดว่ายังมีปัญหาเล็กน้อยอยู่ เมื่อคุณลาก / วางแถวส่วนที่เหลือของคอลัมน์ตารางอาจเปลี่ยนความกว้างเนื่องจากแถวหายไป ผมคิดว่ามีความกว้างของพวกเขาจำเป็นต้องได้รับการแก้ไขเช่นกัน ...
Jez

1
สิ่งนี้ช่วยฉันได้มาก ควรทำเครื่องหมายเป็นคำตอบที่ถูกต้อง
Andrew Bessa

3
ฉันพบว่าความกว้างนั้นส่งผลให้เซลล์แบบบุนวมนั้นไม่ได้มีขนาดที่ถูกต้อง ฉันแลกเพื่อ$(this).width($originals.eq(index).outerWidth());
Barry Carlyon

166

ฉันคิดว่ามันสามารถช่วย:

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

13
นี่ไม่ใช่คำตอบยอดนิยมอย่างไร หนึ่งบรรทัดง่าย ๆ ของ CSS แก้ไขให้ฉัน
jcrowson

8
ฉันเห็นด้วย! คุณจะไม่เชื่อว่า CSS ง่ายๆบรรทัดเดียวจะแก้ไขตารางที่จัดเรียงได้ของคุณ - ผู้เชี่ยวชาญ Stackoverflow งงงัน!
Brade

3
นี่คือคำตอบ ขอบคุณ @Yaroslav
Steffi

3
นี่ไม่ใช่วิธีแก้ปัญหาทั่วไปและจะส่งผลให้มีลักษณะที่แตกต่างกันของแถวลาก
Tomas M

13
วิธีนี้ดีมาก แต่อาจมีผลกับรายการอื่น ๆ ที่ไม่ได้อยู่ในตาราง คำแนะนำของฉันคือคุณแก้ไขคำตอบของคุณเฉพาะเจาะจงมากขึ้น ชอบสิ่งนี้ => ตาราง tr.ui-sortable-helper {display: table! important; }
Rafael Gomes Francisco

29

คำตอบที่เลือกไว้ที่นี่เป็นคำตอบที่ดีมาก แต่มีข้อผิดพลาดร้ายแรงอย่างหนึ่งซึ่งปรากฏอยู่ในซอ fiddle 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 Fiddle: 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 Fiddle: http://jsfiddle.net/rp4fV/4/


ขอบคุณคุณประหยัดเวลาของฉัน
super pantera

เทคนิคตัวยึดตำแหน่งที่นี่คือนักฆ่า! แก้ปัญหาของฉันได้อย่างสมบูรณ์
jessegavin

1
วิธีแก้ปัญหานี้ดีมากจริง ๆ และเทคนิคการยึดตำแหน่งเป็นของแข็งจริง ๆ ควรเป็นคำตอบที่เลือกในความคิดของฉัน
Chris James Champeau

1
สิ่งนี้ยังทำให้เกิดพฤติกรรมที่ไม่พึงประสงค์เมื่อคุณมีแถวที่สูงมาก แถวอื่น ๆ ทั้งหมดจะซ่อนอยู่ข้างหลัง ฉันจะเพิ่มสิ่งนี้ในวิธีการเริ่มต้น:$(".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 ซึ่งไม่ได้เพิ่ม colspans แต่อ้างถึงพวกเขา (อาการปวดสตริง 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;
}

ฉันจะเพิ่มนี่เป็นความคิดเห็นในคำตอบของเดฟ แต่ฉันมีตัวแทนไม่เพียงพอในบัญชีนี้


หลังจากอ่านเอกสาร jQuery ฉันพบว่าการเรียงลำดับยังใช้ตัวเลือก "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


-4

ใช้การจัดเรียงกับองค์ประกอบ tbody ของตารางและเพียงตั้งค่าตัวช่วยเป็น 'โคลน' ตามที่อธิบายไว้ในAPIของ jquery-ui

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

1
ดูเหมือนจะไม่ช่วย
แอนดรู
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.