React - Antd - Show/Hide Columns in table - reactjs

I would like to resolve one problem.
How can I show/hide columns in table using Ant Design in React?
export const columns = () => [
{
key: "anyKeyOne",
title: "Title one",
dataSource: "AnyOne",
hide: true
},
{
key: "anyKeyTwo",
title: "TitleTwo",
dataSource: "AnyTwo",
hide: false
}
]
hideColumns = () => {
//
}
render() {
return (
<div>
<Table
dataSource={store.data}
columns={this.hideColumns}
/>
</div>
)
}
Thank you for answers.

You can set a boolean state property like hideColumn
<div>
<Table
dataSource={store.data}
columns={this.state.hideColumn? this.state.columns: this.state.columns}
/>
</div>

Use this function to build your visible column array. It uses dataIndex to compare the column name needed to be shown.
Form the arrayOfColumnNeeded by pushing values from a checkbox group maybe.
let columnsDisplayed = _.remove(columns, function(n) {
return arrayOfColumnsNeeded.includes(n.dataIndex);
});

You can add a className field in the object and add a css property 'display: none' to that class
{
key: "anyKeyOne",
title: "Title one",
dataSource: "AnyOne",
className: "hide"
}

Related

AntD Tree: need help! can't pass react element as icon OR title for antd tree

I'm using the AntD tree and I have a react element that I want to pass as either an icon or a title because it has custom styling. Due to it being IP I can't share too much code, but my question is:
how can I pass a react element (see below i.e. generic name) as either a title or icon and have antD tree render it?
i.e. this is what I want to pass as a prop to the icon or title
import React from 'react';
const genericName = (props) => {
// code uses props to get some infor for Color
// cant share code due to proprietary reasons
// but it is not needed for this question
const colorHTML = getColor(Color);
return (
<div>
<div className={`colors from`}>${colorHTML}</div>
{pin}
</div>
);
};
export default genericName;
in my console you can see node.icon is a typeof react.element. I want to target that and just pass the prop into antD tree as either title or icon
i.e.
return (
<Tree
icon={node.icon}
/>
)
I've searched and similar answers were given before antD forbid the use of children and strictly allows treeData. All examples I see only use strings in titles/icons, but since antD documentation is very limited, I need to know if my use case is possible. Right now, for the life of me I can't understand why it doesn't populate.
Thank you in advance.
It should definitely work to put a JSX component as title within treeData. Take a look at this snippet, I added a Icon here in one of the titles:
import React from 'react'
import { RightCircleOutlined } from '#ant-design/icons'
type Props = {}
import { Tree } from 'antd';
import type { DataNode, TreeProps } from 'antd/es/tree';
const treeData: DataNode[] = [
{
title: <span>{<RightCircleOutlined />} parent</span>, //icon added here
key: '0-0',
children: [
{
title: 'parent 1-0',
key: '0-0-0',
disabled: true,
children: [
{
title: 'leaf',
key: '0-0-0-0',
disableCheckbox: true,
},
{
title: 'leaf',
key: '0-0-0-1',
},
],
},
{
title: 'parent 1-1',
key: '0-0-1',
children: [{ title: <span style={{ color: '#1890ff' }}>sss</span>, key: '0-0-1-0' }],
},
],
},
];
const Demo: React.FC = () => {
const onSelect: TreeProps['onSelect'] = (selectedKeys, info) => {
console.log('selected', selectedKeys, info);
};
const onCheck: TreeProps['onCheck'] = (checkedKeys, info) => {
console.log('onCheck', checkedKeys, info);
};
return (
<Tree
checkable
defaultExpandedKeys={['0-0-0', '0-0-1']}
defaultSelectedKeys={['0-0-0', '0-0-1']}
defaultCheckedKeys={['0-0-0', '0-0-1']}
onSelect={onSelect}
onCheck={onCheck}
treeData={treeData}
/>
);
};
export default Demo;

React DataTable fails to change the font-size

I work on a React app and there is a component using DataTable (reference is here).
The default font-size looks too small so I want to change to make it look bigger.
I try to set the style to the table as the code below but it doesn't work.
Here is my code:
import React from 'react';
import ReactDOM from 'react-dom';
import DataTable from 'react-data-table-component';
export default class MyTable2 extends React.Component {
constructor(props) {
super(props);
const data = [];
for (var i = 0; i < 200; i++) {
data.push({ id: i, title: 'Conan the Barbarian' + i, summary: 'Orphaned boy Conan is enslaved after his village is destroyed...', year: '1982', expanderDisabled: true, image: 'http://conan.image.png' })
}
this.state = {
rs: data
}
}
render() {
const columns = [
{
name: 'Title',
selector: 'title',
sortable: true,
},
{
name: 'Year',
selector: 'year',
sortable: true
},
];
const handleChange = (state) => {
console.log('Selected Rows: ', state.selectedRows);
};
let styleobj = { "font-size": "25px" } //try to set the font-size here
return (
<DataTable
className="dataTables_wrapper"
title="Arnold Movies"
columns={columns}
data={this.state.rs}
selectableRows // add for checkbox selection
onTableUpdate={handleChange}
pagination
style={styleobj}
/>
)
}
}
Is there anyone here can suggest me a solution?
Thank you in advanced.
Can you try this
// Override the row font size
const myNewTheme= {
rows: {
fontSize: '25px'
}
}
<DataTable
className="dataTables_wrapper"
title="Arnold Movies"
columns={columns}
data={this.state.rs}
selectableRows // add for checkbox selection
onTableUpdate={handleChange}
pagination
customTheme={myNewTheme}
/>
Theme reference
Source file
If you want to change an individual cell font size, you can do this
const columns = [
{
name: 'Title',
selector: 'title',
sortable: true,
cell: row => <div style={{fontSize: 25}}>{row.title}</div>
}]
Hi #humanbean answer is correct, you can fix the inline stile or, if you want, you also can set the style directly in your app.css
Based on your custom classname (.dataTables_wrapper) I think that this css should work.
.dataTables_wrapper .rdt_TableCell{
font-size:25px;
}
this is the className used by react-data-table-component
rdt_Table
rdt_TableRow
rdt_TableCol
rdt_TableCol_Sortable
rdt_TableCell
rdt_TableHeader
rdt_TableFooter
rdt_TableHead
rdt_TableHeadRow
rdt_TableBody
rdt_ExpanderRow

Is it possible to display html formatted text in antd table?

My backend service(elasticsearch percolator) annotates text with html tags to highlight matches.
I can't find a way to display such html data in antd Table.
I've tried Highlighter component, but it applies keywords to whole column, but I need to highlight different words in each row.
link to fiddle
const { Table } = antd
class TableColor extends React.Component {
constructor (props) {
super(props)
this.state = {
data: []
}
}
componentDidMount() {
this.setState({
data: [
{id:1, name: 'Lazy < bclass="myBackgroundColor">fox</b>', match: 'fox'},
{id:2, name: '<b class="myBackgroundColor">Dog</b> runs', match: 'Dog'},
{id:3, name: 'I saw <b class="myBackgroundColor">duck</b>', match: 'duck'}
]
})
}
render () {
const columns = [{
title: 'ID',
dataIndex: 'id',
}, {
title: 'Name',
dataIndex: 'name',
}, {
title: 'Match',
dataIndex: 'match',
}]
return (
<div style={{padding: '20px'}}>
<Table
columns={columns}
dataSource={this.state.data}
/>
</div>
)
}
}
ReactDOM.render(<TableColor />, document.querySelector('#app'))
Since it looks like the name column already has highlighted html you could just add a render property to the name column definition that uses dangerouslySetInnerHtml to render the raw html.
...something like:
render: function(html) { return <div dangerouslySetInnerHtml({__html: html}) />
https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
https://ant.design/components/table/#Column
If you wanted to use react-highlight-words you could do the same thing with a render property but use the second argument passed to that function to get the .match property of the record and use that as the highlighted word.

Antd: Is it possible to move the table row expander inside one of the cells?

I have an antd table where the data inside one of the columns can get pretty large. I am showing this data in full when the row is expanded but because the cell with a lot of data is on the right side of the screen and the expander icon is on the left side of the screen it is not very intuitive. What I would like to do is move the expander icon inside the actual cell so that the user knows they can click the + to see the rest of the data.
Thanks in advance.
Yes, you can and you have to dig a little deeper their docucmentation...
According to rc-table docs you can use expandIconColumnIndex for the index column you want to add the +, also you have to add expandIconAsCell={false} to make it render as part of the cell.
See Demo
This is how you can make any column expendable.
First add expandedRowKeys in your component state
state = {
expandedRowKeys: [],
};
Then you need to add these two functions onExpand and updateExpandedRowKeys
<Table
id="table-container"
rowKey={record => record.rowKey}
className={styles['quote-summary-table']}
pagination={false}
onExpand={this.onExpand}
expandedRowKeys={this.state.expandedRowKeys}
columns={columns({
updateExpandedRowKeys: this.updateExpandedRowKeys,
})
}
dataSource={this.data}
oldTable={false}
/>
This is how you need to define the function so
that in expandedRowKeys we will always have
updates values of expanded rowKeys
onExpand = (expanded, record) => {
this.updateExpandedRowKeys({ record });
};
updateExpandedRowKeys = ({ record }) => {
const rowKey = record.rowKey;
const isExpanded = this.state.expandedRowKeys.find(key => key === rowKey);
let expandedRowKeys = [];
if (isExpanded) {
expandedRowKeys = expandedRowKeys.reduce((acc, key) => {
if (key !== rowKey) acc.push(key);
return acc;
}, []);
} else {
expandedRowKeys.push(rowKey);
}
this.setState({
expandedRowKeys,
});
}
And finally, you need to call the function updateExpandedRowKeys
for whichever column you want to have the expand-collapse functionality available.
Even it can be implemented for multiple columns.
export const columns = ({
updateExpandedRowKeys,
}) => {
let columnArr = [
{
title: 'Product',
key: 'productDes',
dataIndex: 'productDes',
className: 'productDes',
render: (text, record) => (
<span onClick={rowKey => updateExpandedRowKeys({ record })}>
{text}
</span>
),
}, {
title: 'Product Cat',
key: 'productCat',
dataIndex: 'productCat',
className: 'product-Cat',
}]
}

Using react-datepicker in react-data-grid compoent

I am using react-data-grid component. It provides a grid structure with edit and lot more options. When we click on each cell, we are able to edit the content of the cell. In my project, I have a situation like when the date column is focused I want to bind a UI where the user can able to select the date.for that, I have used react-datepicker component. I am able to give react-datepicker component as a formatter in the date column option. I can able to change the date in the react datepicker component, but that is not updating the cell value (when you click on the console data button you can able to see the changes have been updated or not).so guys help me how I can update the cell value when a different date is selected in the react-datepicker component. It happening automatically when the value is changed in other cells.
import React from 'react';
import ReactDOM from 'react-dom';
import ReactDataGrid from 'react-data-grid';
import DatePicker from 'react-datepicker';
import moment from 'moment';
//helper to generate a random date
function randomDate(start, end) {
return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())).toLocaleDateString();
}
//helper to create a fixed number of rows
function createRows(numberOfRows){
var _rows = [];
for (var i = 1; i < numberOfRows; i++) {
_rows.push({
id: i,
task: 'Task ' + i,
startDate: randomDate(new Date(2015, 3, 1), new Date())
});
}
return _rows;
}
//function to retrieve a row for a given index
var rowGetter = function(i){
return _rows[i];
};
//renders react datepicker component
var ExampleDate = React.createClass({
displayName: 'Example',
getInitialState: function() {
return {
startDate:moment(this.props.value,"MM-DD-YYYY")
};
},
consoleDate:function(){
console.log(this.state.startDate);
},
handleChange: function(date) {
this.setState({
startDate: date
});
},
render: function() {
return (
<div>
<DatePicker selected={this.state.startDate} onChange={this.handleChange} />
</div>
);
}
});
//Columns definition
var columns = [
{
key: 'id',
name: 'ID',
width: 80
},
{
key: 'task',
name: 'Title',
editable : true,
width:100
},
{
key: 'startDate',
name: 'Start Date',
editable : true,
formatter:<ExampleDate />,
width:100
}
]
var Example = React.createClass({
getInitialState : function(){
return {rows : createRows(5)}
},
rowGetter : function(rowIdx){
return this.state.rows[rowIdx]
},
handleRowUpdated : function(e){
//merge updated row with current row and rerender by setting state
var rows = this.state.rows;
Object.assign(rows[e.rowIdx], e.updated);
this.setState({rows:rows});
},
output:function(){
console.log(this.state.rows);
},
render:function(){
return(
<div>
<ReactDataGrid
enableCellSelect={true}
columns={columns}
rowGetter={this.rowGetter}
rowsCount={this.state.rows.length}
minHeight={200}
onRowUpdated={this.handleRowUpdated} />
<button onClick={this.output} > Console data </button>
</div>
)
}
});
ReactDOM.render(<Example />, document.getElementById('container'));
I encounter some issues when I tried to reproduce. Anyway, after some changes I works fine:
- I removed the random date to avoid "Invalid Date"
- I fixed the formatter like this
formatter: ({value}) => <ExampleDate value={value} />
All works fine, but I always get the warning, because of the key props of your columns :(

Resources