2010-09-20 3 views
16

Ich habe zwei verbundene tbody Elemente, die mir erlauben, Zeilen zwischen zwei Tabellen zu ziehen. Alles funktioniert gut, bis alle Zeilen aus jeder Tabelle entfernt sind.Jquery ui-sortierbar - nicht in der Lage, tr in leeren tbody fallen lassen

Wenn alle Zeilen auf die andere Tabelle gezogen wurden, verringert sich die Tbody-Höhe und es ist (fast) unmöglich, die Zeilen wieder nach innen fallen zu lassen.

Gibt es eine bekannte Problemumgehung für dieses Problem? (min-height funktioniert nicht auf einem tbody element)

Vielen Dank im Voraus.

+0

Gute Frage, ich versuche Zeilen zu sortieren und Listen verschieben und das gleiche Problem mit leeren Tabellen bekommen ... Hast du weiter damit? –

+0

Lösung hier: http://stackoverflow.com/questions/6832687/jquery-problem-with-sortable-items-cant-be-dropped-onto-empty-lists Zusammenfassung: In Polsterung an den Behälter – Populus

Antwort

9

Sie können eine Zeile erstellen, die für den "sortierbaren" Mechanismus unsichtbar ist. Wahrscheinlich ist der einfachste Weg, dies zu tun, mit der Option "Artikel".

Lassen Sie uns sagen, dass Ihre HTML-ähnliche

<tbody class="sortable"> 
    <tr><td>stuff</td></tr> 
    <tr><td>stuff</td></tr> 
    <tr><td>stuff</td></tr> 
    <tr class="sort-disabled"><td></td></tr> 
</tbody> 

dann in jquery aussieht, kann man

$('.sortable').sortable({ 
    items: ">*:not(.sort-disabled)" 
}); 

Es ist ein bisschen wie ein Hack, aber ich denke, wenn man sich mit Variationen dieses Spiels (geben Sie der .sort-disabled Zeile eine Höhe in CSS usw.) Sie können wahrscheinlich etwas finden, das für Sie arbeitet. Sie können auch versuchen, eine .sort-deaktivierte Zeile sowohl als erste als auch als letzte Zeile zu verwenden, sodass der Platz in der Mitte das Drop-Ziel ist.

Hoffe, das hilft!

+0

Werde dies versuchen, aber wie du sagst aussehen wie ein bisschen ein hack .. –

+0

Ended dabei tun. Hat sehr gut funktioniert. Ich habe nur "tr: ​​nicht (.padder)", da ich glaube, dass das ">" implizit ist. –

+0

Tatsächlich fand ich einen ärgerlichen Nachteil: Sie können nicht garantieren, ob Sie Gegenstände vor oder nach der Padder-Reihe fallen lassen. Das bedeutet, dass das Styling inkonsistent werden kann, insbesondere wenn Sie mehrere Tabellen haben, von denen einige Zeilen über dem Padder haben und einige Zeilen darunter haben. –

3

Ich habe die gleiche Frage, und verwalten die Hälfte es dadurch zu lösen, dies zu tun:

$('table').sortable(
{ 
    connectWith: 'table', 
    items: 'tbody tr' 
}); 

Dies ermöglicht es mir Reihen auf einen leeren Tisch zu bewegen, und es sieht gut aus, aber das Element eingefügt nach der tbody statt drinnen. Ich denke, Danny Roberts Antwort wird für mich funktionieren, aber ich wäre daran interessiert, eine Non-Hack-Lösung zu sehen.

+1

können Sie das beheben, indem Sie hinzufügen: 'empfangen: Funktion (e, ui) { \t $ (this) .find (" tbody "). Append (ui.item); } ' –

6

Es ist schwer, Tabelle zu erzwingen. tbody, um Höhe zu haben, während es leer ist. Also habe ich es auf folgende Weise gemacht.

<div class="ui-widget sortablecolumn"> 
    <table> 
    </table> 
</div> 

$('.sortablecolumn').sortable(
{ 
    connectWith: '.sortablecolumn', 
    items: 'table > tbody > *', 
    receive: function(ev, ui) { 
     ui.item.parent().find('table > tbody').append(ui.item); 
    } 
}); 
$('.sortablecolumn').disableSelection(); 

Schwerpunkte sind items Selektor und receive Ereignishandler, wo hinzugefügt Artikel in Tabellenkörper bewegt wird.

Jetzt funktioniert es gut.

+0

Dies ist die beste Antwort. Keine Hacks, nur ein anderer Container div und gelöst. Vielen Dank! – MazarD

+0

Ich löste mein Problem mit 'var $ parent = ui.item.parent(); if ($ parent.is ('table')) {$ parent.find ('tbody'). append (ui.item);} 'stattdessen, was sehr nahe an dem ist, was Sie haben. –

4

Kasse my post about this - Sie können es lösen, indem ein Verfahren zum Klick verbunden sind, die Höhe zu leeren Behältern ergänzt:

function sortAndDrag() { 

    //show BEFORE sortable starts 
    $(".sortableClass").bind('click mousedown', function(){ 
      $(".sortableClass"").each(function (c) { 
       if ($("tbody", this).size() == 0) { 
        $(this).addClass("aClassWhichGivesHeight") 
       } 
      }) 
    }); 

    //enable sortable 
    $(".sortableClass").sortable({ 
     connectWith: ".sortableClass", 
     stop: function (a, d) { 
      $("tbody").removeClass("aClassWhichGivesHeight"); 
     } 
    }); 

} 

So etwas wie das?

+0

Das Hinzufügen von Höhe zu tbody hilft nicht, da tbodys nicht ohne Inhalt angezeigt werden - auch wenn 'display: table-row-group' oder ähnliches gesetzt ist. – Deebster

2

Hier ist, wie ich das Problem gelöst mit nicht in der Lage eine tr in einem leeren tbody fallen zu lassen:

$(function() { 

    var sort1 = $('#sort1 tbody'); 
    var sort2 = $('#sort2 tbody'); 

    sizeCheck(sort1); 
    sizeCheck(sort2); 

    //Start the jQuery Sortable for Active and Fresh Promo Tables 
    $("#sort1 tbody, #sort2 tbody").sortable({ 

    items: ">*:not(.sort-disabled)", 

    deactivate: function(e, ui) { 

     sizeCheck(sort1); 
     sizeCheck(sort2); 

    }, 
    //Connect tables to pass data 
    connectWith: ".contentTable tbody" 

    }).disableSelection(); 

}); 

//Prevent empty tbody from not allowing items dragged into it 

function sizeCheck(item){ 
    if($(item).height() == 0){ 
     $(item).append('<tr class="sort-disabled"><td></td></tr>'); 
    } 
} 
1

Ich weiß, diese Frage markiert wurde als „beantwortet“ aber ich wollte auch eine andere Art und Weise hinzuzufügen, zu nähern Dies.

Ich überprüfe, ob die Liste leer ist, wenn ja, erstelle ein neues Zeilenelement und injiziere es in den tbody. Ich habe eine Nachricht wie "Keine weiteren Gegenstände" in der td.

Sobald ein Element in die "leere" Liste fällt, wird die leere Nachricht zerstört.

Ich benutze Mootools daher das Fehlen von Beispielcode.

0

i verwenden:

$(document).ready(function(){ 
     $("#sortable1 tbody, #sortable2 tbody").sortable({ 
     connectWith: ".connectedSortable", 
     remove: function(event, ui){ if($(this).html().replace(/^\s+/, "") == '') { $(this).html('<tr class="tmp_tr nobr"><td colspan="7">&nbsp;</td></tr>'); }}, 
     update: function(event, ui) {$(this).find('.tmp_tr').remove();}, 
    }).disableSelection(); 

});

0

Einfache Lösung (PURE CSS):

tbody:after { 
    content:" "; 
    height:30px; 
} 

Wenn der leere Raum kein stardard Leerzeichen ist. Es ist ein unsichtbares Leerzeichen wie das Folgende: Invisible characters - ASCII

Arbeitete für mich in FF und Chrome.