Material-ui: [Table] Définir la largeur de la colonne du tableau

Créé le 19 oct. 2015  ·  54Commentaires  ·  Source: mui-org/material-ui

Est-il possible de définir la largeur des colonnes du tableau?

DataGrid question

Commentaire le plus utile

Dans mon tableau HTML vanille, la largeur des colonnes est automatiquement définie en fonction du contenu. material-ui semble appliquer une largeur égale sur toutes les colonnes. Existe-t-il un moyen de définir la largeur de la colonne pour qu'elle soit dynamique à la place, comme les tableaux HTML vanille?

Tous les 54 commentaires

+1

Rien de bien spécial à ce sujet:

const colWidth {
    width: '2rem'
};

<TableRowColumn style={ colWidth }>
    ...
</TableRowColumn>
<TableRowColumn style={{ width: 100 }}>

ne se comporte pas très bien avec TableHeaderColumn

Existe-t-il un moyen d'attribuer dynamiquement la largeur de col en fonction du contenu?

Dans mon tableau HTML vanille, la largeur des colonnes est automatiquement définie en fonction du contenu. material-ui semble appliquer une largeur égale sur toutes les colonnes. Existe-t-il un moyen de définir la largeur de la colonne pour qu'elle soit dynamique à la place, comme les tableaux HTML vanille?

@sanfilippopablo , <Table> utilise la prop table-layout: 'fixed' css, menant à toutes les colonnes ayant la même largeur, combinée avec white-space: 'nowrap' sur chaque cellule du tableau pour gérer le débordement.

Vous ne pouvez pas passer en toute sécurité à table-layout: 'auto' car la table se développe alors à l'infini avec son contenu à moins que vous ne supprimiez le prop css d'espaces blancs mentionné ci-dessus. Et si tu fais ça,
vous ne pouvez plus utiliser le prop fixedHeader={true} puisque les en-têtes sont alors contenus dans une table séparée: cry :.

Certains commentaires seraient appréciés.

Ce que j'ai fait pour définir la largeur des colonnes est pour le

style, définissez la mise en page du tableau sur auto, comme mentionné ci-dessus, puis je donne des largeurs en pourcentages à mes colonnes. c'est à direlargeur 30% etlargeur 70%. Il s’agit d’un exemple de disposition à deux colonnes, avec des colonnes d’en-tête de tableau dans la première première colonne plutôt que dans l’en-tête.

Vous ne pouvez pas passer en toute sécurité à la mise en page du tableau: 'auto' car le tableau grandit alors à l'infini avec son contenu

Qu'en est-il de l'ajustement de la largeur de l'en-tête du tableau lorsque la largeur du tableauRowColumn change avec le contenu?
Je n'arrive pas à le configurer pour que ces 2 soient alignés.

Je suppose que vous utilisez fixedHeader={true} et que vous ne pouvez pas définir de largeur personnalisée ou que vous ne le faites pas et que vous devez garder vos en-têtes dans votre <TableBody> .

D'accord, mettre l'en-tête dans le corps fonctionne! Maintenant, je dois comprendre comment créer des colonnes d'en-tête multilignes. Des conseils?

Essayez-vous de réaliser quelque chose comme ça ? (sinon, vous pouvez probablement trouver le bon exemple sur ce site)

Je pense que vous pouvez faire à peu près tout ce que vous voulez avec les attributs colSpan sur TableHeaderColumn et TableRowColumn et rowSpan sur TableRow .

Je ne comprends pas - pourquoi est-ce fermé?

Mettre TableHeader dans TableBody ne fonctionne pas pour moi.

@ tvtri96
Ce que nous avons suggéré était de mettre tableRow comme en-tête de table dans tableBody,
mais il me semble que cela fonctionne maintenant bien.

voici à quoi cela ressemble maintenant dans mon code:

<Table fixedHeader={true}>
          <TableHeader>
            <TableHeaderComponent schema={schema}/>
          </TableHeader>
          <TableBody displayRowCheckbox={false} showRowHover={true}>
            {this.props.data.map((item, index) => (
              <TableRowComponent key={index} schema={this.props.schema}
                item={item} onRemoveClick={this.handleRemoveItem}
                onEditClick={this.handleEditItem}
              />
            ))}
          </TableBody>
</Table>

et les colonnes d'en-tête sont correctement alignées avec les colonnes de corps.

Tks de m'avoir répondu. Que contient TableHeaderComponent? Je suppose que ce n'est pas comme un TableHeader normal, non?
''

Horodatage

Oui, c'est juste emballé pour des raisons.

des nouvelles à ce sujet? Comment puis-je laisser les colonnes s'ajuster automatiquement au contenu?

Cela fonctionne pour moi, le dimensionnement automatique:

      <Table style={{tableLayout: 'auto'}}>

@arjan

 <Table style={{tableLayout: 'auto'}}>

Cela n'a aucun effet sur l'en-tête.

<Table fixedHeader={false} style={{ tableLayout: 'auto' }}> fonctionne (dimensionnement dynamique basé sur le contenu).

J'avais besoin d'ajouter width: "auto" , ce qui donne:

<Table fixedHeader={false} style={{ width: "auto", tableLayout: "auto" }}>

@nathanmarks , veuillez rouvrir.

Table devrait avoir une propriété intégrée pour lui permettre de s'adapter automatiquement au contenu, et il ne devrait pas nécessiter de désactiver fixedHeader . J'irais plus loin et je dirais que la taille automatique du contenu devrait être le comportement par défaut.

@devuxer Désolé, mais nous

@mbrookes , merci de nous l'avoir fait savoir. Êtes-vous en train de dire que le tableau de la v1.x résout ce problème?

@devuxer Je crois que oui, il a été réécrit à partir de

https://material-ui-next.com/demos/tables/

J'avais un tableau avec trois colonnes, où les première et troisième colonnes contiendraient toujours une petite quantité de texte. Je voulais que la deuxième colonne occupe la majeure partie de l'espace afin que les première et troisième colonnes soient respectivement poussées vers les bords gauche et droit de la table. Cela a fonctionné pour moi (en utilisant style ici par opposition à className par souci de concision):

<Table style={{ tableLayout: "auto" }} />
<TableRowColumn style={{ width: "10%" }}>{text}</TableRowColumn>
<TableRowColumn style={{ width: "80%" }}>{text}</TableRowColumn>
<TableRowColumn style={{ width: "10%" }}>{text</TableRowColumn>

J'ai trouvé une meilleure solution ... donc, chaque colonne a la même largeur.
Disons que j'ai trois colonnes et que je veux que la première occupe la moitié de la largeur totale, et la troisième devrait représenter environ un tiers de la ligne; celui du milieu soit le plus petit:

  <TableRowColumn colSpan='3'>twice as big!</TableRowColumn>
  <TableRowColumn> I'm small</TableRowColumn>
  <TableRowColumn colSpan='2'>I'm in between</TableRowColumn>

En fait, j'ai 7 colonnes, mais la somme de mes colspans est égale à 20 - le dernier ne contient qu'une icône de suppression, la plupart des autres sont colspan 3 - le grand champ de texte est colspan 6, et un champ de sélection et un sélecteur de date sont sur colspan 2 ...

Fonctionne comme un charme!

C'est bon d'aller dans la v1.4.3

const styles = { 
    narrowCell: {
        'width': '150px',
    }
};

<Table>
    <TableHead>
        <TableRow>
            <TableCell>Company Name</TableCell>
            <TableCell className={classes.narrowCell} numeric>Amount</TableCell>
        </TableRow>
    </TableHead>
    <TableBody>
    <TableRow>
        <TableCell> name 1 </TableCell>
        <TableCell className={classes.narrowCell}> $100 </TableCell>
    </TableRow>
    </TableBody>
</Table>


Peut également donner des largeurs en pourcentage, le reste des cellules s'étendant également

Comment puis-je utiliser cette solution si je dois utiliser colspan={2} dans une ligne TableHead?

Si j'ajoute colspan={2} tous les cols auront la même largeur. Quelque chose comme ça:

const styles = { 
    narrowCell: {
        'width': '150px',
    },
    miniCell: {
        'width': '75px',
    },
};

<Table>
    <TableHead>
        <TableRow>
            <TableCell>Company Name</TableCell>
            <TableCell className={classes.narrowCell} numeric colspan={2}>Amounts</TableCell>
        </TableRow>
    </TableHead>
    <TableBody>
    <TableRow>
        <TableCell> name 1 </TableCell>
        <TableCell className={classes.miniCell}> $100 </TableCell>
        <TableCell className={classes.miniCell}> $100 </TableCell>
    </TableRow>
    </TableBody>
</Table>

@Bowfish Si vous voulez changer la largeur de la cellule colspan = {2}, essayez de changer la largeur du tableau, étant donné qu'il couvre tout le tableau. Les petites cellules peuvent être ajustées individuellement.

L'application de ce style m'a aidé d'une manière ou d'une autre:
Je suis juste assis différent maxWidth pour différents cels dans la ligne mais même dans chaque colonne en utilisant des styles en ligne.

const styles = (theme) => ({
  tableCell: {
    whiteSpace: 'nowrap',
    overflow: 'hidden',
    textOverflow: 'ellipsis',
    maxWidth: '40px',
  },
});

Aucune des solutions affichées ci-dessus ne fonctionne. Pourquoi est-ce si difficile à réaliser?

  <Table fixedHeader={false} style={{tableLayout: "auto" }}>
        <colgroup>
            <col width="250px" />
            <col />
            <col width="40px" />
            <col width="40px" />
        </colgroup>
        <TableHead>
          <TableRow>

la deuxième colonne est flex

Je ne sais pas si quelqu'un a toujours un problème avec cela, mais j'ai fini par utiliser withStyles et cela a fonctionné, voici le pseudo code:

import {withStyles} from '@material-ui/core/styles';  

const styles = theme => ({
    cell: {
        width:'20%'
    },
    cellLarge: {
        width:'60%'
    } 
});

<Table >
       <TableHead>
               <TableRow>
                        <TableCell className={this.props.classes.cell}>header 1</TableCell>
                         <TableCell className={this.props.classes.cell}>header 2</TableCell>
                         <TableCell className={this.props.classes.cellLarge}>header 3</TableCell>
                </TableRow>
          </TableHead>
                <TableBody>
                        <TableRow>
                            <TableCell>value 1</TableCell>
                            <TableCell>value 2</TableCell>
                            <TableCell>value 3</TableCell>
                        </TableRow>
               </TableBody>
   </Table>

export default withStyles(styles)({ComponentName})

Aucune des solutions affichées ci-dessus ne fonctionne. Pourquoi est-ce si difficile à réaliser?

D'une manière ou d'une autre, je reconnais pourquoi cela ne fonctionne pas, car nous ne définissons que width uniquement pour TableHead ou TableBody ! Pour que cela fonctionne, nous devons définir minWidth et maxWidth bot sur TableCell dans TableHead et TableBody , voici l'exemple

<Table>
    <TableHead>
        <TableRow>
            <TableCell column='data1' style={{minWidth:100, maxWidth:100}}>{content}</TableCell>
            <TableCell column='data2' style={{minWidth:'200px', maxWidth:'200px'}}>{content}</TableCell>
        </TableRow>
    </TableHead>
    <TableBody>
            <TableRow>
            <TableCell column='data1' style={{minWidth:100, maxWidth:100}}>{content}</TableCell>
            <TableCell column='data2' style={{minWidth:200, maxWidth:200}}>{content}</TableCell>
            </TableRow>
    </TableBody>
</Table>

Comme vous pouvez le voir, nous pouvons utiliser à la fois la valeur du style par nombre entier et par chaîne. Mais pour la chaîne, cela ne fonctionne que si vous l'avez défini par px , si vous utilisez un pourcentage, comme minWidth:'25%' , cela ne fonctionnera pas , je l'ai déjà essayé.

Pourquoi utiliser à la fois minWidth et maxWidth ? Pas width ? Parce que je l'ai déjà essayé, si vous voulez créer votre colonne avec une largeur fixe, vous devez utiliser minWidth et maxWidth au lieu de width . Je ne savais pas pourquoi, mais width ne semble pas fonctionner pour résoudre ce problème.

Remarque: _Les deux TableCell in TableHead et TableBody qui contiennent les mêmes données doivent avoir le même style ! _

J'espère que ce code vous aidera les gars, bravo

J'ai littéralement défini width: 10%, minWidth: 10% et maxWidth: 10% pour chaque TableCell, y compris celles sous les en-têtes de table. J'ai ensuite créé des éléments <colgroup>..etc et leur ai appliqué les mêmes styles. J'ai également défini l'élément Table sur tableLayout: auto et width: auto. J'ai essayé toutes les solutions de ce fil et les ai toutes combinées à cette sortie finale. de plus, j'ai également utilisé l'outil "inspect element" en chrome et j'ai piraté chaque élément de la table pour utiliser la largeur: 10% min-width: 10% et max-width: 10%. cela se reflétait également dans l'inspecteur React dans devtools. il m'a littéralement montré tous les éléments modifiés par "largeur 10%", etc.

résultat: n'ajuste toujours pas la largeur des colonnes

Je pense qu'il est prudent de supposer maintenant qu'il existe en fait un impossible. et c'est dans ce fil même

Éditer:

En fait, j'ai fini par faire quelque chose qui allait à l'encontre de ce que les gens de ce fil suggéraient ... j'ai défini autoLayout: fixed dans ma table et cela a commencé à fonctionner. Qu'est-ce que dans le monde est cette magie noire

Avoir aussi du mal à essayer de définir des largeurs. J'ai dû définir la largeur de la case à cocher: 0,01% pour qu'elle reste à une largeur raisonnable, rien d'autre ne fonctionne

Pour ceux qui sont bloqués sur l'ancienne version et qui ont du mal avec le pied de page, ajouter fixedFooter = {false} à la solution de @devenovil fonctionne pour moi.

@nathanmarks Pouvez-vous au moins clarifier pourquoi vous avez fermé cela?
Cela devrait être une fonctionnalité requise très récurrente.

@pbassut a raison. C'est une fonctionnalité très basique pour un composant de table ... Y a-t-il une mise à jour?
Ou une explication pourquoi la mise en œuvre est si problématique ...

@devenovil Au lieu de maxWidth , si vous voulez utiliser % , vous pouvez utiliser width comme:

<TableCell style={{ width: '35%' }}>
  Table Data
</TableCell>
<TableCell>
  Another Table Data
</TableCell>

Pour moi, cela a fonctionné pour définir la largeur uniquement pour les cellules de l'en-tête: <TableCell width={props.colWidths[index] + '%'}> , cela a pour résultat que les colonnes de la table entière se comportent comme prévu.

J'ai défini les largeurs de colonne avec le pourcentage et cela fonctionne en quelque sorte, mais pour une raison quelconque, cela ajoute une colonne fantôme à l'extrême droite. En inspectant l'élément, il semble ajouter un élément "TableStubCell" à la table. Je n'ai aucune idée d'où cela vient.

J'ai eu des problèmes similaires avec d'autres tables MUI, et mes solutions de contournement ne sont jamais aussi bonnes. Ce serait cool si vous ouvriez tous ce problème et le résolviez ... Il est clair que d'autres personnes sont aux prises avec cela aussi.

edit: le TableStubCell vient du paquet dx-react-grid-material-ui npm, donc désolé de pointer du doigt!

Ma solution est de faire

<Table>
  <TableHeader>
    <TableRow>
      <TableCell>
        <Box width="200px">
          User Fullname
        </Box>
      </TableCell>
      {/* ...rest of the columns */}
    </TableRow>
  </TableHeader>
  <TableBody>
    <TableRow>
      <TableCell>
        April Mintac Pineda
      </TableCell>
      {/* ...rest of the columns */}
    </TableRow>
    {/* ...rest of the rows */}
  </TableBody>
</Table>

Mais ce serait bien si nous pouvions juste faire

<Table>
  <TableHeader>
    <TableRow>
      <TableCell width="200px">
        User Fullname
      </TableCell>
      {/* ...rest of the columns */}
    </TableRow>
  </TableHeader>
  <TableBody>
    <TableRow>
      <TableCell>
        April Mintac Pineda
      </TableCell>
      {/* ...rest of the columns */}
    </TableRow>
    {/* ...rest of the rows */}
  </TableBody>
</Table>

Cela fonctionne pour moi avec la version "@material-ui/core": "4.9.0"

<TableContainer className={classes.container}>
          <Table className={classes.table} stickyHeader size="small">
            <TableHead>
              <TableRow>
                <TableCell width="30%">User Name</TableCell>
                <TableCell width="20%">Designation</TableCell>
                <TableCell width="10%">Nid</TableCell>
                <TableCell width="20%">Email</TableCell>
                <TableCell width="10%">Mobile</TableCell>
                <TableCell width="10%">Gender</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {props.isGridLoading && (
                <TableRow>
                  <TableCell colSpan={6}>
                    <LoadingGridSpinner open={props.isGridLoading} />
                  </TableCell>
                </TableRow>
              )}

              {props.profileObj.lists &&
                props.profileObj.lists.map(row => (
                  <TableRow key={row.userProfileId} hover={true}>
                    <TableCell width="30%">
                      {row.userName}
                    </TableCell>
                    <TableCell width="20%">{row.designation}</TableCell>
                    <TableCell width="10%">{row.nid}</TableCell>
                    <TableCell width="20%">{row.email}</TableCell>
                    <TableCell width="10%">{row.mobile}</TableCell>
                    <TableCell width="10%">{row.gender}</TableCell>
                  </TableRow>
                ))}
            </TableBody>
          </Table>

L'approche utilisée par @nazrulcsebd et @crizant a fonctionné pour moi. Voici mon code:

<TableContainer component={Paper} style={{ marginTop: 10 }}>
          <Table style={{ width: 'auto', tableLayout: 'auto' }}>
          <TableHead>
            <TableRow>
              <TableCell>Team Member</TableCell>
              <TableCell align="left">Level</TableCell>
              <TableCell align="left">Last Login</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            { tableArray.map(({ id, name, accessLevel, login }) => (
              <TableRow key={id}>
                <TableCell component="th" scope="row" style={{ width: '35%' }}>
                  {name}
                </TableCell>
                <TableCell align="left">{accessLevel}</TableCell>
                <TableCell align="left">{login}</TableCell>
              </TableRow>
            ))
          }
          </TableBody>
        </Table>
      </TableContainer>

Dans mon cas, je voulais avoir la plus petite colonne possible pour tenir un bouton "action" à la fin du tableau. L'ajout de style={{ width: 1 }} à TableCell dans TableHead a fait l'affaire.

        <TableContainer component={Paper}>
            <Table className={classes.table} aria-label="simple table">
                <TableHead>
                    <TableRow>
                        {header.map((th, i) => (
                            <TableCell key={i}>{th}</TableCell>
                        ))}
                        <TableCell style={{ width: 1 }}>actions</TableCell>
                    </TableRow>
                </TableHead>
                <TableBody>
                    {data.map((row, i) => (
                        <TableRow key={i} hover>
                            {header.map((h, i) => (
                                <TableCell key={i} align="left">{row[h]}</TableCell>
                            ))}
                            <TableCell>
                                <IconButton aria-label="edit">
                                    <MoreHorizIcon fontSize="small" />
                                </IconButton>
                            </TableCell>
                        </TableRow>
                    ))}
                </TableBody>
            </Table>
        </TableContainer>
const useStyles = makeStyles(theme => ({
  table: {
    "& tr:nth-child(2), & td:nth-child(2) {
      width: '32px',
    }
  }
}));

Et puis, utilisez le style à la racine du tableau

 <Table
     ....
     className={classes.table}
>

Je n'ai pas encore beaucoup testé (en-tête fixe, etc.)

ce serait bien mieux si nous pouvions simplement donner le même système de 12 colonnes aux tables par exemple:

   <TableContainer component={Paper}>
      <Table className={classes.table} aria-label="simple table">
        <TableHead>
          <TableRow>
            <TableCell>Dessert (100g serving)</TableCell>
            <TableCell align="right">Calories</TableCell>
            <TableCell align="right">Fat&nbsp;(g)</TableCell>
            <TableCell align="right">Carbs&nbsp;(g)</TableCell>
            <TableCell align="right">Protein&nbsp;(g)</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {rows.map((row) => (
            <TableRow key={row.name}>
              <TableCell component="th" scope="row" xs={4}>
                {row.name}
              </TableCell>
              <TableCell align="right" xs={2}>{row.calories}</TableCell>
              <TableCell align="right" xs={2}>{row.fat}</TableCell>
              <TableCell align="right" xs={2}>{row.carbs}</TableCell>
              <TableCell align="right" xs={2}>{row.protein}</TableCell>
            </TableRow>
          ))}
        </TableBody>
      </Table>
    </TableContainer>

Quelqu'un connaît-il un moyen de laisser le tableau défiler dans la direction x s'il y a trop de colonnes? Je ne peux y arriver qu'en donnant minWidth = quelque chose de codé en dur (ce qui n'est pas génial pour un nombre inconnu de colonnes)

Il semble que les fixedHeader={false} style={{width: "auto", tableLayout: "auto"}} sont ignorés dans la dernière version.

Des idées?

J'ai fini avec une solution de contournement en utilisant un élément de liste à l'intérieur du tableau et en définissant la largeur de l'élément de liste ...
Quelque chose comme:

<TableCell>
  <ul style={{ width: "150px" }}>
    <li>{row.whatever}</li>
    <li>{row.whatever1}</li>
    <li>{row.whatever2}</li>
  </ul>
</TableCell>

2020 et toujours difficile à réaliser, le plus étrange est que j'essaie de définir la largeur d'une colonne, les autres colonnes s'ajustent automatiquement même lorsque j'ai également défini la largeur pour elles! ce qui donne? C'est comme si la table s'assurait que toute la largeur de la table ne dépasse pas 100%, ce qui me donne du fil à retordre. Si je n'utilisais pas la table de material-ui, ce serait très très facile, semble-t-il que l'interface utilisateur matérielle ne fait que compliquer les choses?

@aprilmintacpineda Avez-vous essayé avec des éléments natifs <table> ?

@oliviertassinari Je n'ai pas converti le code existant en élément <table> natif.

Cet exemple fonctionne en définissant la largeur de toutes les colonnes
https://codesandbox.io/s/fragrant-framework-oy6uz?file=/src/App.js

Cette page vous a été utile?
0 / 5 - 0 notes