jquery UI triable avec table et largeur tr


155

J'utilise jQuery UI triable pour rendre ma grille de table triable. Le code semble fonctionner correctement, mais comme je n'ajoute pas de largeur à tds, lorsque je fais glisser le, tril réduit le contenu.

Par exemple; si ma ligne de tableau est de 500 pixels lorsque je commence à faire glisser, elle devient 300 pixels. Je suppose que cela se produit car aucune largeur n'est définie dans la grille. C'est parce que j'utilise deux classes pour le tds ( fixet liquid).

La fixclasse rend tdégal à la largeur du contenu et liquidrend la tdlargeur à 100%. C'est mon approche pour la table de grille sans avoir à attribuer une largeur à tds.

Une idée comment rendre le travail triable avec mon approche?


3
La réponse de Yaroslav est le VRAI MVP!
Brade

J'ai eu le même problème, je pense que @Yaroslav a la bonne réponse pour traiter les tables, ce que le PO demande
doz87

Réponses:


254

J'ai trouvé la réponse ici .

Je l'ai légèrement modifié pour cloner la ligne, au lieu d'ajouter des largeurs à l'original:

  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 Comment feriez-vous fonctionner l'option d'espace réservé?
shaun5

5
Dave, merci de partager ceci, j'ai fait un jsFiddle pour montrer les différences entre l'original, modifié et aucun correctif appliqué: jsfiddle.net/bgrins/tzYbU . Je mettrai également à jour le message d'origine avec votre solution.
Brian Grinstead

9
Cela fonctionne très bien, mais je pense qu'il y a encore un léger problème; lorsque vous faites glisser / déposez la ligne, le reste des colonnes du tableau peut changer de largeur en raison de la ligne manquante. Je suppose que leurs largeurs doivent également être corrigées ...
Jez

1
Cela m'a sauvé beaucoup de travail. Il doit être marqué comme la bonne réponse.
Andrew Bessa

3
J'ai trouvé que la largeur entraînait des cellules rembourrées pas tout à fait correctes. J'ai troqué pour$(this).width($originals.eq(index).outerWidth());
Barry Carlyon

166

Je pense que cela peut aider:

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

13
Comment n'est-ce pas la meilleure réponse? Une simple ligne de CSS le corrige pour moi.
jcrowson le

8
Je suis d'accord! Vous ne CROYEZ pas comment une simple ligne de CSS corrige votre table triable - les experts de Stackoverflow sont déconcertés!
Brade

3
C'est LA réponse. Merci @Yaroslav
Steffi

3
Ce n'est PAS une solution générale et entraînera une apparence différente de la ligne traînée
Tomas M

13
Cette solution est très bonne, mais elle peut affecter d'autres listes qui ne sont pas des tables. Ma suggestion est que vous modifiez votre réponse pour qu'elle soit plus précise. Comme ceci => table tr.ui-sortable-helper {display: table! Important; }
Rafael Gomes Francisco

29

La réponse choisie ici est une très bonne solution, mais elle a un bug grave qui est apparent dans le violon JS original ( http://jsfiddle.net/bgrins/tzYbU/ ): essayez de faire glisser la ligne la plus longue ( God Bless You, Mr . Rosewater ), et le reste de la largeur des cellules s'effondre.

Cela signifie que la fixation des largeurs de cellule sur la cellule déplacée n'est pas suffisante - vous devez également fixer les largeurs sur le tableau.

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

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

JS Fiddle: http://jsfiddle.net/rp4fV/3/

Cela résout le problème de la réduction du tableau après avoir fait glisser la première colonne, mais en introduit une nouvelle: si vous modifiez le contenu du tableau, les tailles de cellule sont maintenant fixées.

Pour contourner ce problème lors de l'ajout ou de la modification de contenu, vous devez effacer les largeurs définies:

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

Ajoutez ensuite votre contenu, puis corrigez à nouveau les largeurs.

Ce n'est toujours pas une solution complète, car (en particulier avec une table) vous avez besoin d'un espace réservé de dépôt. Pour cela, nous devons ajouter une fonction au démarrage qui construit l'espace réservé:

$('#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/


Merci, vous gagnez mon temps
super pantera

La technique de l'espace réservé est ici tueuse! Totalement résolu mon problème.
jessegavin

1
Cette solution est en fait vraiment bonne, et la technique de l'espace réservé est vraiment solide, cela devrait être la réponse choisie à mon avis.
Chris James Champeau

1
Cela provoque toujours un comportement désagréable lorsque vous avez une ligne très haute. Toutes les autres lignes se cacheront derrière. J'ajouterais ceci à la méthode de départ:$(".must-have-class").css("height", $(ui.item).outerHeight());
Itzik Ben Hutta

6

Il semble que le clonage de la ligne ne fonctionne pas bien sur IE8, mais la solution d'origine fonctionne.

Testé avec le jsFiddle .


Merci d'avoir configuré le fichier jsFiddle. Je vais avec la solution originale car, comme Jez l'a noté, les autres cellules de ligne peuvent changer de largeur lors du glissement d'une ligne.
Roger

4

Appelez ce code suivant lorsque votre table est prête à être triée, cela garantira que vos éléments td ont une structure de table fixe avec sans rupture.

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

Oui, c'est à peu près la même chose que ma réponse, bien que la mienne fonctionne thaussi bien td. Il corrige l'effondrement des lignes traînées et l'effondrement du tableau, mais au prix de la fixation des largeurs.
Keith

1

jsFiddle

Après de nombreuses tentatives, j'ai juste essayé une solution simple qui complète la solution de Dave James Miller pour éviter que la table ne rétrécisse en faisant glisser la plus grande ligne. J'espère que cela aidera :)

// 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

La solution de Keith est bonne mais a produit un peu de ravages dans Firefox qui n'a pas additionné les colspans mais les a signalés. (L'ancienne douleur de type string js dans le genou)

en remplaçant cette ligne:

 cellCount += colspan;

avec:

 cellCount += colspan-0;

Résout le problème. (Comme js est obligé de traiter les variables comme des nombres au lieu de chaînes)


0

La réponse de Dave James Miller a fonctionné pour moi, mais en raison de la disposition des divs de conteneur sur ma page, l'assistant qui traîne avec le curseur de la souris est décalé de la position de ma souris. Pour résoudre ce problème, j'ai ajouté ce qui suit au rappel de l'aide

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

Voici le rappel complet avec la ligne ci-dessus ajoutée:

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;
}

J'aurais ajouté ceci en commentaire à la réponse de Dave, mais je n'avais pas assez de représentants sur ce compte.


Après avoir lu la documentation jQuery, j'ai trouvé que le triable prend également une option "appendTo" qui spécifie à quel élément l'assistant est ajouté.
Shea Riley

0

Il semble que disableSelection()- la méthode est mauvaise et obsolète de nos jours. Je ne peux plus utiliser d'entrées de texte dans une ligne triable dans Mozilla Firefox 35.0. Ce n'est tout simplement plus focalisable.


-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
Plus d'explications sont nécessaires!
Afsanefda

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

-4

Appliquez le triable à l'élément tbody de la table et définissez simplement l'assistant sur `` clone '', comme décrit dans l' API de jquery-ui

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

1
Cela ne semble pas aider.
Andrew
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.