How can I make the columns automatically adjust the the longest text a corresponding cell?
You would probably need to do that dynamically by measuring the text
beforehand and adjusting the column width accordingly. Since the text and
table style cannot be consistently measured for every single scenario, this
is likely something that would turn into a plugin instead of a core feature
On Sun, Feb 19, 2017 at 4:50 PM Steven Shaginyan notifications@github.com
wrote:
How can I make the columns automatically adjust the the longest text a
corresponding cell?—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/tannerlinsley/react-table/issues/94, or mute the
thread
https://github.com/notifications/unsubscribe-auth/AFUmCWBoiwLyRuz2_4if9INQBlTHm-cKks5reNVfgaJpZM4MFpIE
.
I did something like this. Not great, but it works.
` getColumnWidth (accessor, headerText) {
let {data} = this.state;
let max = 0;
const maxWidth = 400;
const magicSpacing = 18;
for (var i = 0; i < data.length; i++) {
if (data[i] !== undefined && data[i][accessor] !== null) {
if (stringify(data[i][accessor] || 'null').length > max) {
max = stringify(data[i][accessor] || 'null').length;
}
}
}
return Math.min(maxWidth, Math.max(max, headerText.length) * magicSpacing);
}`
The last bit ensures the width doesn't go over a universal maximum, and is never smaller than the header text (because that's annoying AF).
That's exactly what I would have done.
On Mon, Feb 20, 2017 at 12:50 PM Darcy notifications@github.com wrote:
I did something like this. Not great, but it works.
` getColumnWidth (accessor, headerText) {
let {data} = this.state;
let max = 0;const maxWidth = 400; const magicSpacing = 18; for (var i = 0; i < data.length; i++) { if (data[i] !== undefined && data[i][accessor] !== null) { if (stringify(data[i][accessor] || 'null').length > max) { max = stringify(data[i][accessor] || 'null').length; } } } return Math.min(maxWidth, Math.max(max, headerText.length) * magicSpacing);}`
The last bit ensures the width doesn't go over a universal maximum, and is
never smaller than the header text (because that's annoying AF).—
You are receiving this because you commented.Reply to this email directly, view it on GitHub
https://github.com/tannerlinsley/react-table/issues/94#issuecomment-281167538,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AFUmCXt61L7Wu-fKWHLNg1p0oR7xYgKeks5ree59gaJpZM4MFpIE
.
Thanks guys
Hi @spacedarcy, I might ask the stupid question here, but how/where do you use this function ? In ReactTable props or did you build a wrapper around it ?
A wrapper.
@spacedarcy Could you please give a little example? I think i'm kind of miss :S
Please, @spacedarcy, where did you place your code? I'm confused
Based on @spacedarcy answer I rewrote the function to something like this:
const getColumnWidth = (rows, accessor, headerText) => {
const maxWidth = 400
const magicSpacing = 10
const cellLength = Math.max(
...rows.map(row => (`${row[accessor]}` || '').length),
headerText.length,
)
return Math.min(maxWidth, cellLength * magicSpacing)
}
Not sure about the magicSpacing 10 seems to work for me, I guess it's about your font size, and I also have to handle pivoting. To use this I just call the function in the columns definitions something like:
{
Header: 'My header',
accessor: 'accessor',
width: getColumnWidth(rows, 'accessor', 'My header'),
},
Hope this helps
@dbertella how you passing rows to getColumnWidth method.
I get ReferenceError: rows is not defined, would really appreciate your help
rows is whatever you pass as data to your table, so a complete example is this:
<ReactTable
data={data}
columns={[
{
Header: 'My header',
accessor: 'accessor',
width: getColumnWidth(data, 'accessor', 'My header'),
},
]}
defaultPageSize={10}
className="-striped -highlight"
/>
Edit the above will work just if data in this case is an array, for an object you will need to modify the helper, since I'm using ...row.map
@dbertella Thanks!
How can I have access to the nested accessor property in the custom width function.
accessor: d => moment(d.partner_created_date),
width: (d) => { return getColumnWidth(data, d.partner_created_date, "Date")}
I am trying this. But it's not working
well your accessor is the whole function I guess, did you with moment(d.partner_created_date) I guess you have an object with 2018-01-01 as a key, not sure but basically you have to pass wathever is the key because it needs to work inside the map as: row[accessor] so in your case possibly should be row['2018-01-01'] (I'm guessing). If it doesn't work I'm afraid you should come up with something more custom sorry
Yes I guess more custom, Not a problem with date
accessor: d => d.partner_status,
width:(d) => getColumnWidth(this.state.partners, d.partner_status, "Status")
even nothing gets logged inside getColumnWidth function
Any Idea where to break and start
oh I see sorry, yeah no that will not work because width is not expecting a function there, just a value so d will be undefined I don't know how you can work around this. You will have to find somehow how to provide the name of the property you want to check inside your object.
Thanks guys, it works. But what about general table with. I have a lot of tables on the different pages and when there are few colums on wide screens the last column of the table takes all free space and becomes too wide, maxWidth for this column visually doesn't works.
P.S. display:inline-block for .ReactTable class.
Thanks @dbertella. I made another slight tweak to make the accessor accept both strings and functions. The latter adds some more flexibility to the use of this function.
const getColumnWidth = (data, accessor, headerText) => {
if (typeof accessor === 'string' || accessor instanceof String) {
accessor = d => d[accessor]; // eslint-disable-line no-param-reassign
}
const maxWidth = 600;
const magicSpacing = 10;
const cellLength = Math.max(
...data.map(row => (`${accessor(row)}` || '').length),
headerText.length,
);
return Math.min(maxWidth, cellLength * magicSpacing);
};
Good one thank you!
And one finally improvement, to allow string accessors of type 'objectA.objectB' you can use lodash.get() and also a check if value is a number along with conversion to string:
export const getColumnWidth = (data, accessor, headerText) => {
const cellLength = Math.max(
...data.map(row => {
let value = '';
if (typeof accessor === 'string') {
value = _.get(row, accessor);
} else {
value = accessor(row);
}
if (typeof value === 'number') return value.toString().length;
return (value || '').length;
}),
headerText.length
);
const magicSpacing = 12;
return cellLength * magicSpacing;
};
rows is whatever you pass as data to your table, so a complete example is this:
<ReactTable data={data} columns={[ { Header: 'My header', accessor: 'accessor', width: getColumnWidth(data, 'accessor', 'My header'), }, ]} defaultPageSize={10} className="-striped -highlight" />Edit the above will work just if data in this case is an array, for an object you will need to modify the helper, since I'm using
...row.map
how to implementation in v.7
Most helpful comment
Based on @spacedarcy answer I rewrote the function to something like this:
Not sure about the
magicSpacing10 seems to work for me, I guess it's about your font size, and I also have to handle pivoting. To use this I just call the function in the columns definitions something like:Hope this helps