How to wrap a long text in table cell (react-bootstrap-table-next)? - css

I am introduced to react/redux/sagas/redux-form web application development. I used react-bootstrap-table-next in order to display data in a table format.
It has two columns as Title, Description however data for Title column is a long string data.
foo1,foo2,foo3,foo4,foo5,foo6,foo7 bar
And the problem I am having is it overflows or occupies cell/row under Description so that data under Description column is masked.
I tried something like this but it didn't make a difference.
const rowStyle = (row, rowIndex) => {
return { whiteSpace: 'pre-line'; };
};
<BootstrapTable data={ data } columns={ columns } rowStyle={ rowStyle } />
What would be the way to wrap this long string so that it can be contained within fixed width of cell under Title column?
[update]
Found an answer with following css instead.
return { overflowWrap: 'break-word' };

You can do it by providing certain styling in your tag.
<BootstrapTable data={data} bodyStyle={ {width: 500, maxWidth: 500, wordBreak: 'break-all' } }>

Related

put icon and text in the same column

I have the interface shown in the image, and this interface contains several columns, and in the column "الاسم الثلاثي" I want to put an icon "FastBackwardOutlined" next to each name, but instead of placing an icon, I see the "[object][object]" table as shown in the image.
How can I solve the problem?
return data?.map((row: any) => {
return {
...row,
supervisoryDoctor:
row.supervisoryDoctor?.label,
trinomialName:
`${<FastBackwardOutlined />}` + row.trinomialName
};
});
You cannot put it in a string.
You could use
trinomialName: (<React.Fragment>
<FastBackwardOutlined /> {row.trinomialName}
</React.Fragment>)

Autoheight in MUI DataGrid

I'm using the MUI DataGrid component, and the behavior I hope to have is that:
When there's a small number of rows, the table is only the size it needs to for those rows.
When there's a large number of rows, more than the current viewport can hold (given whatever else is on the screen), the table takes up the available space in the layout (given its flex: 1) and the extra rows scroll inside the table.
I can achieve each of these behaviors, but only one at a time.
If I use the autoHeight property on the DataGrid, then the table will be as small as it can be. BUT it will also be as big as it can be, so with a large number of rows the container scrolls the entire table, rather than the rows scrolling within the table.
If I don't use autoHeight, and wrap the DataGrid in a container with flex: 1, then the table will grow to fill the available space and the rows will scroll within the table. BUT a table with only a few rows will also grow to fill its container, so that there is empty space under the rows (above the footer, "Table rows: #")
You can see the situation in this screenshot, showing the exact same page, with different data.
I've tried what feels like every permutation of heights and flexes under the sun. For example:
Setting autoHeight with a maxHeight (and .MuiDataGrid-main { overflow: scroll; } ) allows few-rows to be small, and many-rows to be not too small, but obviously any discrete maxHeight, be it px or %, is not the flexible layout I'm going for.
Turning off autoHeight (as in scenario #2) and setting flex-grow: 0 on the rows container within the table (.MuiDataGrid-main) just makes the rows disappear since they then shrink to a height of 0.
The code for the component:
const S = {
Wrapper: styled.div`
width: 100%;
display: flex;
flex: 1;
background: white;
border: solid thick red;
`,
DataGrid: styled(DataGridPro)`
&& {
.MuiDataGrid-main {
//overflow: scroll;
//flex-grow: 0;
}
background: lightgreen;
font-size: 14px;
}
`,
};
type Props = {
columns: ReadonlyColumns;
rows: AnyObject[];
filterModel?: GridFilterModel;
} & Omit<DataGridProps, 'columns'>;
const DataTable: React.FC<Props> = ({
columns = [],
rows = [],
filterModel,
className,
...props
}) => {
const memoizedColumns = useMemo(
() =>
columns.map(col => ({
headerClassName: 'columnHeader',
flex: 1, // all columns expand to fill width
...col, // but could override that behavior
})),
[columns],
);
return (
<S.Wrapper className={className}>
<S.DataGrid
// autoHeight
rows={rows}
columns={memoizedColumns}
filterModel={filterModel}
{...props}
/>
</S.Wrapper>
);
};
Using a combination of autoHeight and pageSize will create a table whose height is only as big as needed for the current number of rows as long as the number of rows is <= pageSize. Additional rows will be added to a new page.
<DataGrid
rows={rows}
columns={columns}
pageSize={20} //integer value representing max number of rows
autoHeight={true}
/>
Below solved the issue:
<DataGrid getRowHeight={() => 'auto'} />
Source:
https://mui.com/x/react-data-grid/row-height/#dynamic-row-height
I had a similar issue days ago and I solved recalculating the row height every time a new item was added to my row.
getRowHeight={(props: GridRowHeightParams) => {
const serviceRowHeight = 45 // <-- default height, if I have no data for the row
const addServiceBtnHeight = 45 // <-- a component that's always on the row
const height = props.model?.services // services is each dynamic item for my row, so you should access like props.yourObj
? props.model.services.length * serviceRowHeight + addServiceBtnHeight
: 115
return height < 115 ? 115 : height // final height to be returned
}}

Changing parent row color based on child column value- jqWidgets

I have a nested grid, and I am able to change the nested grid row background color based on the value of one of its columns. But I would like to also be able to change the color of the parent row.
For example: Parent:Study, Child:Site, Condition:column Status=pending.
If a site has a status of pending, I would like to change the row color for the pending site, and also change the row color for the study the contains that pending site.
var cellclassname = function (row, column, value, rowdata) {
if (rowdata.Status =="Pending") {
return "red";
}
}
The code above works for the nested grid:
columns: [
{ text: '<b>Site ID</b>', datafield: 'ID', width: '15%', cellclassname: cellclassname},
{ text: '<b>Organization Name</b>', datafield: 'SiteName', width: '70%', cellclassname: cellclassname},
{ text: '<b>DSA</b>', datafield: 'Status', width: '15%', cellclassname: cellclassname} ]
but not for the parent grid:
columns: [
{ text: '<b>Study Filter</b>',
datafield: 'StudyName', width: '100%', cellclassname: cellclassname }
]
How can I modify my cellclassname function so it will change the row color for the parent row as well?
Thanks in advance!
I created a work around solution.
From the database side, I was able to generate the parent data with an extra column, which says if any of the child information has a pending, then the parent study will also have a pending status. So when generating the grid, I was able to color the parent row based on that information, and I made the status column hidden.
I am still curious to know how I could have done it using the jqwidgets functions instead of modifying the source data.

Wrap text of Office UI Fabric DetailsRow

I am trying to get my text to wrap around and display in multiple lines in Office UI Fabric's DetailsRow. At the moment some of my rows that have long text go off the screen, and I would like them to wrap around so the user does not have to scroll to read the entire row.
This is my GroupedList
<GroupedList
items={this._items}
onRenderCell={this._onRenderCell}
groups={this._groups}
selectionMode={SelectionMode.none}
compact={true}
/>
This is my render method for each cell.
_onRenderCell = (nestingDepth, item, itemIndex) => {
return (
<DetailsRow
columns={this._columns}
groupNestingDepth={nestingDepth}
item={item}
itemIndex={itemIndex}
selection={this._selection}
selectionMode={SelectionMode.none}
onClick={() => this.insertComment(item.key, item.link)}
/>
);
};
Any ideas on how to make the text wrap? I am a beginner when it comes to styling.
If you have specific columns whose text are known to require more than "1 line" of text, you can use the isMultiLine property on the column. This is the example that sets isMultiLine to true for a column to wrap the text, which in turn enlarges the height of the corresponding row: "DetailsList - Variable Row Heights".

How to remove extra space in the detail grid style in ag-grid master detail setup?

I have an ag-grid master-detail grid where one master row typically has only 1 or 2 sub-rows in the detail grid (there's always 2 columns for the detail grid). When I write up the code matching the examples on ag-grid's documentation, it always leaves huge whitespace under the detail grid and it auto-expands the detail grid's width to the width of the container.
I would like to get rid of the extra whitespace under the detail grid and also size the detail grid so the columns are only as wide as they need to be to fit the data. (Thus there would be whitespace to the right side of the detail-grid)
I've tried looking through the styles in chrome dev tools but I can't figure out what controls those 2 styling aspects. In addition, setting domLayout = 'autoHeight' in the detail grid options just moves the bottom of the detail grid to the last row, but it doesn't get rid of the extra whitespace in the cases where there's only 1 detail-row.
Plunkr MVPs (includes domLayout = 'autoHeight' in detail-grid's options):
React: https://plnkr.co/edit/K76FssFF4Ex538fn
Angular: https://plnkr.co/edit/0n5EllKejfyq9x4E
The original plunkr samples came from the "Simple Example" plunkr on the ag-grid master-detail documentation.
All you need to do is refer the documentation here, as for the additional things needed.
We need to use this method from the ag-grid documentation.
this.getRowHeight = function(params) {
if (params.node && params.node.detail) {
var offset = 80;
var allDetailRowHeight =
params.data.callRecords.length *
params.api.getSizesForCurrentTheme().rowHeight;
var gridSizes = params.api.getSizesForCurrentTheme();
return allDetailRowHeight + gridSizes.headerHeight + offset;
}
};
Also on the detail panel grid options we need to add this property, which will set the height dynamically.
this.detailCellRendererParams = {
detailGridOptions: {
columnDefs: [
{ field: 'callId' },
{
field: 'duration',
valueFormatter: "x.toLocaleString() + 's'",
}
],
defaultColDef: {
flex: 1,
editable: true,
resizable: true,
},
onGridReady: function(params) {
params.api.setDomLayout('autoHeight');
},
},
getDetailRowData: function(params) {
params.successCallback(params.data.callRecords);
},
};
Below is a working example for your reference
Plunkr example
After combining Naren's answer with some css adjustments, this is the best result I could get. I'm not accepting this answer because it's not what I want, but I can live with it until I (or someone else) can figure out something better.
https://plnkr.co/edit/d9emrRiavR9gCpQl
Basically I added these 2 things to the plunkr:
this.getRowHeight = params => {
const defRowHeight = params.api.getSizesForCurrentTheme().rowHeight;
if(params.node.detail) {
const offset = 80;
const detailRowHeight =
params.data.callRecords.length * defRowHeight;
var gridSizes = params.api.getSizesForCurrentTheme();
return detailRowHeight + gridSizes.headerHeight + offset;
} else {
return defRowHeight;
}
}
styles: ['::ng-deep .ag-details-row { width: 50% }']
An acceptable solution would provide a way to resize the detail grid directly to the width of the actual columns (rather than an arbitrary percentage)
Image:
(You can remove that little extra space under the 1st row of the detail grid by overriding min-height of one of the grid's css classes. It only appears if there's 1 row in the detail grid)

Resources