jQuery DataTables: contrôle la largeur de la table

98

J'ai un problème pour contrôler la largeur d'une table à l'aide du plugin jQuery DataTables. Le tableau est censé représenter 100% de la largeur du conteneur, mais finit par être une largeur arbitraire, plutôt inférieure à la largeur du conteneur.

Suggestions appréciées

La déclaration de table ressemble à ceci

<table id="querytableDatasets" class="display" cellspacing="0"
cellpadding="3"     width="100%">

Et le javascript

jQuery('#tab-datasets').load('/cgi-bin/qryDatasets', '', function (){  
    jQuery('#querytableDatasets').dataTable({  
        "bPaginate": false,  
        "bInfo": false,  
        "bFilter": false  
    });  
});  `  

En inspectant le HTML dans Firebug, vous voyez ceci (notez le style ajouté = "width: 0px;")

<table id="querytableDatasets" class="display" cellspacing="0" 
cellpadding="3" width="100%" style="width: 0px;">

En regardant dans Firebug les styles, le style table.display a été remplacé. Je ne vois pas d'où ça vient

element.style {  
  width:0;}    

-- dataTables.css (line 84
table.display { 
  margin:0 auto;  
  width:100%;  
}  
John Mac
la source
FYI, je viens de rencontrer un problème où une colonne ne s'ajustait pas correctement dans IE8. Le coupable était une image dont la max-widthpropriété était définie. Apparemment, IE8 n'aime pas trop cette propriété et l'a ignorée par rapport aux tables de données, même si l'image était correctement dimensionnée à l'écran. Le changer pour widthrésoudre le problème.
John Bubriski

Réponses:

61

Le problème est dû au fait que dataTable doit calculer sa largeur - mais lorsqu'il est utilisé dans un onglet, il n'est pas visible et ne peut donc pas calculer les largeurs. La solution consiste à appeler «fnAdjustColumnSizing» lorsque l'onglet s'affiche.

Préambule

Cet exemple montre comment les DataTables avec défilement peuvent être utilisés avec les onglets de l'interface utilisateur jQuery (ou en fait toute autre méthode dans laquelle la table est dans un élément masqué (display: none) lors de son initialisation). La raison pour laquelle cela nécessite une attention particulière, est que lorsque DataTables est initialisé et qu'il se trouve dans un élément masqué, le navigateur n'a aucune mesure avec laquelle donner DataTables, et cela nécessitera le désalignement des colonnes lorsque le défilement est activé.

La méthode pour contourner ce problème consiste à appeler la fonction API fnAdjustColumnSizing. Cette fonction calcule les largeurs de colonne nécessaires en fonction des données actuelles, puis redessine le tableau - ce qui est exactement ce qui est nécessaire lorsque le tableau devient visible pour la première fois. Pour cela, nous utilisons la méthode 'show' fournie par les tables de l'interface utilisateur jQuery. Nous vérifions si le DataTable a été créé ou non (notez le sélecteur supplémentaire pour 'div.dataTables_scrollBody', il est ajouté lorsque le DataTable est initialisé). Si la table a été initialisée, nous la redimensionnons. Une optimisation pourrait être ajoutée pour redimensionner uniquement le premier affichage du tableau.

Code d'initialisation

$(document).ready(function() {
    $("#tabs").tabs( {
        "show": function(event, ui) {
            var oTable = $('div.dataTables_scrollBody>table.display', ui.panel).dataTable();
            if ( oTable.length > 0 ) {
                oTable.fnAdjustColumnSizing();
            }
        }
    } );

    $('table.display').dataTable( {
        "sScrollY": "200px",
        "bScrollCollapse": true,
        "bPaginate": false,
        "bJQueryUI": true,
        "aoColumnDefs": [
            { "sWidth": "10%", "aTargets": [ -1 ] }
        ]
    } );
} );

Voir ceci pour plus d'informations.

Arik Kfir
la source
1
J'ai aussi le même problème avec @John McC, cependant, j'ai appliqué mon datatable à un modal, j'utilise bootstrap et je suis resté coincé avec ce problème ... savez-vous comment l'implémenter en utilisant bootstrap modal au lieu d'onglets?. J'ai vraiment besoin de votre aide
cfz
Je recommande d'utiliser window.resize, regardez un exemple legacy.datatables.net/ref#fnAdjustColumnSizing
KingRider
"aoColumnDefs": [{"sWidth": "10%", "aTargets": [-1]}]. Je corrige mon problème, il suffit d'ajouter ceci, merci.
Mina chen
55

Vous voudrez modifier deux variables lorsque vous initialisez dataTables: bAutoWidthetaoColumns.sWidth

En supposant que vous ayez 4 colonnes avec des largeurs de 50px, 100, 120px et 30px, vous feriez:

jQuery('#querytableDatasets').dataTable({  
        "bPaginate": false,  
        "bInfo": false,  
        "bFilter": false,
        "bAutoWidth": false,
        "aoColumns" : [
            { sWidth: '50px' },
            { sWidth: '100px' },
            { sWidth: '120px' },
            { sWidth: '30px' }
        ]  
    }); 

Plus d'informations sur l'initialisation de dataTables peuvent être trouvées à http://datatables.net/usage

Surveillez l'interaction entre ce paramètre de widhts et le CSS que vous appliquez. Vous pouvez commenter votre CSS existant avant d'essayer ceci pour voir à quel point vous vous en approchez.

artlung
la source
mmm. C'est ce que vous dites, c'est que c'est le résultat de bAutoWidth: true ne faisant pas de choix particulièrement intelligents pour la largeur de colonne.
John Mac
C'est ce que je pense. Mes tables rebondissent si la longueur des données est incohérente. C'est pourquoi j'ai mis les paramètres aoColumns et bAutoWidth.
artlung
1
belle. totalement résolu mon problème.
Laguna
Génial @Laguna! J'adore entendre que de vieilles réponses comme celle-ci continuent d'être utiles.
artlung
1
"bAutoWidth": faux travaux. Mais juste une question. Est-ce une bonne pratique ou non si je mets des détails de largeur sur mes balises <th>?
finnTheHumin
52
jQuery('#querytableDatasets').dataTable({  
        "bAutoWidth": false
});
Suraj
la source
2
C'était la bonne réponse pour moi. J'utilise boostrap .table-responsive. Avec le code datatable qui définit sa propre largeur, cela gêne.
mac10688
Je suis venu ici pour publier ma solution à ce problème stupide qui impliquait de supprimer la propriété width sur l'événement de changement d'onglet, mais cela semble l'avoir résolu. Merci. +1
Topher
J'ai 3 onglets et datatables sur les deux premiers onglets, le tableau sur le deuxième onglet n'était pas pleine largeur. cela a résolu mon problème. merci
Mike Volmar
47

Eh bien, je ne suis pas familier avec ce plugin, mais pourriez-vous réinitialiser le style après avoir ajouté le datatable? Quelque chose comme

$("#querydatatablesets").css("width","100%")

après l'appel .dataTable?

SingleNegationElimination
la source
1
J'ai trouvé que c'était également la meilleure solution, car dans mon cas, la table était également définie sur une largeur de 100 pixels lorsque l'une des colonnes était rendue invisible - voir ici: datatables.net/forums/discussion/3417/…
mydoghasworms
C'est la solution qui a fonctionné pour moi. il donne un contrôle plus fin sur le css de la table de données par rapport à oTable.fnAdjustColumnSizing (); solution mentionnée précédemment.
Vijay Rumao
11

J'ai eu de nombreux problèmes avec les largeurs de colonne des tables de données. La solution magique pour moi était d'inclure la ligne

table-layout: fixed;

ce css va avec le css global de la table. Par exemple, si vous avez déclaré les tables de données comme suit:

LoadTable = $('#LoadTable').dataTable.....

alors la ligne magique css irait dans la classe Loadtable

#Loadtable {
margin: 0 auto;
clear: both;
width: 100%;
table-layout: fixed;

}

user1842675
la source
2
Cela aide, mais maintenant mes colonnes sont toutes de tailles étranges. Je me serais attendu à ce que les colonnes avec le plus de données prennent la plus grande largeur en pourcentage.
cjbarth
7

La solution TokenMacGuys fonctionne mieux parce que c'est le résultat d'un bogue dans jQdataTable. Ce qui se passe, c'est que si vous utilisez $ ('# someabe'). DataTable (). FnDestroy (), la largeur de la table est définie sur 100px au lieu de 100%. Voici une solution rapide:

$('#credentials-table').dataTable({
        "bJQueryUI": false,
        "bAutoWidth": false,
        "bDestroy": true,
        "bPaginate": false,
        "bFilter": false,
        "bInfo": false,
    "aoColumns": [
           { "sWidth": "140px" },
           { "sWidth": "300px" },
           { "sWidth": "50px" }       
        ],
        "fnInitComplete": function() {

            $("#credentials-table").css("width","100%");
        }

    });
Peter Drinnan
la source
6

Ajoutez cette classe css à votre page, cela résoudra le problème:

#<your_table_id> {
    width: inherit !important;
}
Bahadir Tasdemir
la source
1
J'ai eu un problème séparé que je me suis battu pendant les 30 dernières minutes - cette ligne de code l'a corrigé - donc je voulais juste dire merci pour ce commentaire aléatoire.
user1274820
1
C'est exactement pourquoi je donne des réponses supplémentaires
Bahadir Tasdemir
5

La définition des largeurs explicitement en utilisant sWidthpour chaque colonne ET bAutoWidth: falselors de l' dataTableinitialisation a résolu mon problème (similaire). J'adore la pile débordante.

tubelight
la source
5

Vous devez laisser au moins un champ sans champ fixe, par exemple:

$('.data-table').dataTable ({

 "bAutoWidth": false,
 "aoColumns" : [
    null,
    null,
    null,                    
    null,
    {"sWidth": "20px"},
    { "sWidth": "20px"}]
});

Vous pouvez tout changer, mais n'en laissez qu'un comme nul, afin qu'il puisse s'étirer. Si vous mettez des largeurs sur TOUT, cela ne fonctionnera pas. J'espère que j'ai aidé quelqu'un aujourd'hui!

guérir85
la source
1
C'était tout pour moi, je définissais toutes les colonnes pour avoir 1px. En laisser un de côté le faisait fonctionner comme par magie. Merci!
demoncodemonkey
4
"fnInitComplete": function() {
    $("#datatables4_wrapper").css("width","60%");
 }

Cela a bien fonctionné pour ajuster toute la largeur de la table. Merci @Peter Drinnan!

Nilani Algiriyage
la source
Je n'ai pas pu obtenir la table pour remplir correctement son conteneur parent. J'ai essayé d'ajuster le CSS de la table et de son emballage à la largeur: 100%; sans différence notable. Une fois que j'ai essayé la méthode mentionnée ci-dessus, cela a fonctionné à merveille, mais je ne pointe pas vers le wrapper, au lieu de cela, j'ai dû pointer vers la table elle-même. Mais un grand merci Nilani !!
Logic1
3

Aucune des solutions ici n'a fonctionné pour moi. Même l'exemple sur la page d'accueil des tables de données n'a pas fonctionné, d'où l'initialisation de la table de données dans l'option show.

J'ai trouvé une solution au problème. L'astuce consiste à utiliser l'option activate pour les onglets et à appeler fnAdjustColumnSizing () sur la table visible :

$(function () {

// INIT TABS WITH DATATABLES
$("#TabsId").tabs({
    activate: function (event, ui) {
        var oTable = $('div.dataTables_scrollBody>table:visible', ui.panel).dataTable();
        if (oTable.length > 0) {
            oTable.fnAdjustColumnSizing();
        }
    }
});

// INIT DATATABLES
// options for datatables
var optDataTables = {
    "sScrollY": "200px",
    "bScrollCollapse": true,
    "bPaginate": false,
    "bJQueryUI": true,
    "aoColumnDefs": [
        { "sWidth": "10%", "aTargets": [-1] }
    ]
};
// initialize data table
$('table').dataTable(optDataTables);

});
Helmut Steiner
la source
2

Juste pour dire que j'ai eu exactement le même problème que vous, même si j'appliquais juste JQuery à une table normale sans Ajax. Pour une raison quelconque, Firefox ne développe pas le tableau après l'avoir révélé. J'ai résolu le problème en plaçant la table dans un DIV et en appliquant les effets au DIV à la place.

Dave
la source
2

Faites-vous cela dans l'événement prêt?

$ (document) .ready (fonction () {...});

Le dimensionnement dépendra probablement du chargement complet du document.

Mufaka
la source
Regardez le code ci-dessus - cela se produit dans le rappel de la charge ajax du conteneur div # tab-datasets. La table #querytableDatasets est fournie par / cgi-bin / qryDatasets
John Mac
Je comprends cela, je ne suis pas sûr du moment où cela se produira. En regardant la source du plugin, il semblait que le seul moment où il pouvait définir une largeur de 0px était lorsqu'il ne pouvait pas déterminer la bonne table offSetWidth et j'ai pensé que c'était lié à une exécution trop tôt.
Mufaka
hmm. J'ai supposé que le rappel de la charge ajax est appelé après le chargement de la table #querytableDatasets. pensez-vous que ce n'est peut-être pas le cas?
John Mac
BTW pour répondre à votre question sur le moment où cela s'exécute, c'est en réponse au clic de l'utilisateur sur un bouton
John Mac
Hmm, je ne suis pas sûr de pouvoir ajouter quoi que ce soit de plus. Si c'est un clic sur un bouton, le document est entièrement chargé et il n'y a aucune raison de le placer dans l'événement prêt. Vous pouvez jouer avec la largeur du conteneur de la table ou essayer de faire fonctionner leur (plugin DataTables) en dehors de votre disposition actuelle.
Mufaka
1

Pour toute personne ayant des difficultés à ajuster la largeur de la table / cellule à l'aide du plugin d'en-tête fixe:

Les tables de données reposent sur les balises de tête pour les paramètres de largeur de colonne. C'est parce que c'est vraiment le seul html natif car la plupart des html internes de la table sont générés automatiquement.

Cependant, certaines de vos cellules peuvent être plus grandes que la largeur stockée à l'intérieur des cellules de tête.

C'est-à-dire que si votre table a beaucoup de colonnes (table large) et que vos lignes contiennent beaucoup de données, alors appeler "sWidth": changer la taille de cellule td ne fonctionnera pas correctement car les lignes enfants redimensionnent automatiquement les td en fonction du débordement content et cela se produit une fois que la table a été initialisée et passé ses paramètres init.

La thead originale "sWidth": les paramètres sont remplacés (rétrécis) parce que les tables de données pensent que votre table a toujours sa largeur par défaut de 100% - il ne reconnaît pas que certaines cellules sont débordées.

Pour résoudre ce problème, j'ai compris la largeur du débordement et je l'ai prise en compte en redimensionnant le tableau en conséquence après l'initialisation du tableau - pendant que nous y sommes, nous pouvons lancer notre en-tête fixe en même temps:

$(document).ready(function() {
  $('table').css('width', '120%');
  new FixedHeader(dTable, {
        "offsetTop": 40,
      });
});
DrewT
la source
1

créez votre en-tête fixe dans le "succès" de votre appel ajax, vous n'aurez aucun problème d'alignement dans l'en-tête et les lignes.

success: function (result) {
              /* Your code goes here */

    var table = $(SampleTablename).DataTable();

        new $.fn.dataTable.FixedHeader(table);
}        
Chandra Sekhar beluduru
la source
1

J'espère que cela aide quelqu'un qui a encore du mal.

Ne gardez pas votre table dans un contenant. Faites du wrapper de la table votre conteneur après le rendu de la table. Je sais que cela peut être invalide aux endroits où vous avez autre chose avec le tableau, mais vous pouvez toujours ajouter ce contenu.

Pour moi, ce problème se pose si vous avez une barre latérale et un conteneur qui est en fait un décalage par rapport à cette barre latérale.

$(YourTableName+'_wrapper').addClass('mycontainer');

(J'ai ajouté un panneau par défaut)
Et votre classe:

.mycontainer{background-color:white;padding:5px;}
abcdefghiraj
la source
1

trouver un autre lien utile sur ce problème et cela a résolu mon problème.

<table width="100%">
<tr>
    <td width="20%"> Left TD <td>
    <td width="80%"> Datatable </td>
</tr>
</table>

Tableau de largeur de force des tables de données

Chuanzhou Tang
la source
0

Je suis tombé sur un problème similaire lors d'un div enroulé autour de la table.

Ajout de la position: relative corrigée pour moi.


#report_container {
 float: right;
 position: relative;
 width: 100%;
}
mardala
la source
0

J'ai eu un problème similaire où le contenu du tableau était plus grand que l'en-tête et le pied de page du tableau. L'ajout d'un div autour de la table et la configuration de x-overflow semblent avoir résolu ce problème:

Nick Holden
la source
0

Assurez-vous que tous les autres paramètres avant bAutoWidth & aoColumns sont correctement entrés. Tout paramètre incorrect avant interrompra cette fonctionnalité.

DejanR
la source
0

J'ai eu le même problème et j'ai trouvé que le texte dans les colonnes ne se cassait pas et l'utilisation de ce code css a résolu le problème

th,td{
max-width:120px !important;
word-wrap: break-word
}
h0mayun
la source
0

C'est ma façon de faire.

$('#table_1').DataTable({
    processing: true,
    serverSide: true,
    ajax: 'customer/data',
    columns: [
        { data: 'id', name: 'id' , width: '50px', class: 'text-right' },
        { data: 'name', name: 'name' width: '50px', class: 'text-right' }
    ]
});
Kevin Khew
la source
0

Je rencontre le même problème aujourd'hui.

J'ai utilisé un moyen délicat de le résoudre.

Mon code comme ci-dessous.

$('#tabs').tabs({
    activate: function (event, ui) {
       //redraw the table when the tab is clicked
       $('#tbl-Name').DataTable().draw();
    }
});
Kenneth Wong
la source
0

Vérifiez également cette solution. cela a résolu facilement mon problème de largeur de colonne DataTable

JQuery DataTables 1.10.20 introduit une columns.adjust()méthode qui corrige le problème de l'onglet bascule Bootstrap

 $('a[data-toggle="tab"]').on( 'shown.bs.tab', function (e) {
    $.fn.dataTable.tables( {visible: true, api: true} ).columns.adjust();
} );

Veuillez consulter la documentation: Onglets Scrolling et Bootstrap

PNP
la source
-1

Cela fonctionne très bien.

#report_container {
   float: right;
   position: relative;
   width: 100%;
}
Sam
la source