web-dev-qa-db-fra.com

jquery UI Triable avec table et largeur tr

J'utilise jQuery UI sortable pour rendre ma grille de table triable. Le code semble bien fonctionner, mais comme je n’ajoute pas de largeur à tds, lorsque je déplace le tr, le contenu est réduit.

Par exemple; si ma ligne de table est 500px lorsque je commence à faire glisser, elle devient 300px. 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 (fix et liquid).

La classe fix rend le td égal à la largeur du contenu et liquid rend le td width à 100%. C'est mon approche pour la grille sans avoir à attribuer une largeur à tds.

Avez-vous une idée de la façon dont vous pouvez faire le tri avec mon approche?

153
ntan

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;
  },
252
Dave James Miller

Je pense que cela peut aider:

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

La réponse choisie ici est une solution vraiment sympa, mais elle a un grave problème qui apparaît dans le violon JS original ( http://jsfiddle.net/bgrins/tzYbU/ ): essayez de faire glisser le plus long row (, Dieu vous bénisse, M. Rosewater ), et le reste de la largeur des cellules s’effondre.

Cela signifie que fixer les largeurs de cellule sur la cellule déplacée ne suffit pas - vous devez également fixer les largeurs sur la table.

$(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 le glissement de la première colonne, mais en introduit un nouveau: si vous modifiez le contenu du tableau, la taille des cellules est maintenant corrigée.

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 (surtout avec une table), vous avez besoin d'un espace réservé pour déposer. Pour cela, nous devons ajouter une fonction start 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/

28
Keith

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

Testé avec le jsFiddle .

6
vincentp

Appelez ce code ci-dessous lorsque votre table est prête à être triée, cela garantira que vos éléments td sont corrigés avec une structure de table sans rupture.

 $(".tableToSort td").each(function () {
            $(this).css("width", $(this).width());
        });  
4
Teoman shipahi
$(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));
      });
    }
  });
0
Peter

Il semble que la méthode disableSelection() - soit mauvaise et obsolète de nos jours. Je ne peux plus utiliser de texte dans une ligne pouvant être triée dans Mozilla Firefox 35.0. Ce n'est plus focalisable.

0
Miika Kontio

La solution de Keith est correcte mais a provoqué un petit désastre dans Firefox qui n'a pas additionné les colspans mais les a calés. (Le vieux type de corde js douleur 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 plutôt que des chaînes)

0
Max

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

$(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 comme commentaire à la réponse de Dave, mais je n'avais pas assez de représentants sur ce compte.

0
Shea Riley

jsFiddle

Après de nombreuses tentatives différentes, je viens d'essayer une solution simple qui complète la solution de Dave James Miller afin d'empêcher la table de rétrécir tout en faisant glisser la plus grande ligne. J'espère que ça va aider :)

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