Open neerajmangal opened 6 years ago
Please share what you have tried, or some sort of starter code so we can point you in the right direction!
Also how I can restrict users to select more than one row
Not sure what you mean by this?
Thanks @dahlbyk for taking a look.
This is I have been trying.
I am trying to create a common component for TableView using griddle which other component in my application will use. Below is the CustomTableView I have created.
const rowDataSelector = (state, { griddleKey }) => {
return state
.get('data')
.find(rowMap => rowMap.get('griddleKey') === griddleKey)
.toJSON();
};
/** use griddle's connect function only*/
const enhancedWithRowData = utils.connect((state, props) => {
return {
// rowData will be available into customComponents
rowData: rowDataSelector(state, props)
};
});
const getAllRowsData = (state, props) => {
return state.get('data').toJSON();
};
const enhanceedWithTableData = utils.connect((state, props) =>{
return {
allRowsData: getAllRowsData(state, props)
};
});
/* This seems to be a stateless function but as we are using "ref" in Griddle
* It will throw error if converted to pure/smart component.
*/
class CustomTableView extends React.Component {
constructor(props) {
super(props);
/*Default fallback to CustomFilter in case Platform/Tool
specific Filter is not provided.*/
this.customFilters = props.tblFilters ? props.tblFilters : CustomFilter;
}
render() {
return (
<Griddle
ref="Griddle"
useCustomFilterComponent
/** This storeKey is very important here, without providing it
* Custom Component will not be able to connect to global store.
* https://github.com/GriddleGriddle/Griddle/issues/626
* https://github.com/GriddleGriddle/Griddle/issues/647
*/
storeKey="griddle"
customFilterComponent={this.customFilters}
styleConfig={styleConfig}
data={this.props.data}
showSettings={false}
sortProperties={this.props.sortProperties}
pageProperties={{
currentPage: 1,
pageSize: 10,
recordCount: 10,
useGriddleStyles: false
}}
components={
/* Make sure your custom filter component pass setFilter to children*/
{ Filter: (filter) =>
this.props.tblFilters ? <this.props.tblFilters {...this.props} filter={filter.setFilter}/>
: <CustomFilter {...this.props} filterRef={filter.setFilter}/>,
Layout: Layout
} //SettingsToggle: CustomFilter //TableContainer: CustomTableComponent
}
plugins={[plugins.LocalPlugin]}
>
<RowDefinition>
{this.props.columns.map((column, i) => {
let columnComponent;
let CustomHeader;
if (typeof column.CustomComponent !== 'undefined') {
columnComponent = enhancedWithRowData(column.CustomComponent);
}
if (typeof column.CustomHeader !== 'undefined') {
CustomHeader = enhanceedWithTableData(column.CustomHeader);
}
return(
<ColumnDefinition
key={i}
id={column.key}
title={column.title}
width={column.width}
customComponent={columnComponent}
customHeadingComponent={CustomHeader}
//sortable={column.sortable}
{...this.props}
/>
);
}
)}
</RowDefinition>
</Griddle>
);
}
}
CustomTableView.propTypes = {
/* Table Data to be rendered*/
data: PropTypes.array.isRequired,
/* Table Columns to be rendered and mapped to data*/
columns: PropTypes.array.isRequired,
/* Any shortProperties for pagination*/
sortProperties: PropTypes.array,
/* Custom filters for table data*/
tblFilters: PropTypes.func
};
export default CustomTableView;
The Table Columns are defined like this.
export const ServerlessTableDataColumns = [
{
title: "Select",
key: "IsSelected",
width: 20,
sortable: false,
CustomComponent: RowSelection,
CustomHeader: SelectAllRow
},
{
title: 'Function Name',
key: 'functionName',
width: 100,
sortable:true
},
{
title: 'Runtime',
key: 'runtime',
minWidth: 50,
sortable: true,
divider: true
},
{
title: 'Namespace',
key: 'namespace',
minWidth: 50,
sortable: true
},
{
title: 'Web Action',
key: 'webAction',
minWidth: 20,
sortable: true,
CustomComponent: ToggleWebAction
},
{
title: 'Shared',
key: 'shared',
minWidth: 20,
sortable: true,
CustomComponent: togglePublish
},
{
title: 'Version',
key: 'version',
minWidth: 20,
sortable: true
},
{
title: 'Delete',
key: 'delete',
minWidth: 20,
sortable: false,
CustomComponent: DeleteFunction
},
{
title: 'More',
key: 'more',
minWidth: 20,
sortable: false,
CustomComponent: ExtendedActions
}
];
As you can see first colum is having customHeadingComponent as CustomHeader: SelectAllRow and customComponent as columnComponent:RowSelection I passed in to
// SelectAllRow CustomHeader Component for header checkBox.
export const SelectAllRow = (props) => {
function onSelectAllRow(e) {
console.log("All rows selected", e);
/*
if (props.allRowsData !== null) {
props.allRowsData.forEach(
(data, index) => {
let RowData = {
value: e,
griddleKey: index,
rowData: data
};
RowSelection(RowData);
}
);
}
*/
}
return (
<div style={{ paddingTop: "4px" }}>
<Checkbox
label=""
onChange={onSelectAllRow}
/>
</div>);
};
In SelectAllRow i am not able to figure out how I can pass the onChange event to all table rows. Please let me know how I can do this or is there anything I am missing. Let me know if more information is needed, i will provide that.
Regarding restriction on user to select more than one row, I mean to say is there any property I can pass to Griddle to not allow multiple row selection at a time (i.e user can select only one row at a time or all rows by header checkbox).
Thanks.
OK, based on your commented code in onSelectAllRow
I think you need to shift how you're thinking about selection. You're not going to be able to make changes to props.allRowsData
and expect the app to update accordingly; you need to approach this as a state
change. Since you have a CustomTableView
wrapper around your <Griddle />
, you could have your which-row(s)-selected state live there (passed down into RowSelection
and SelectAllRow
). Or it might be easier to use Griddle's internal Redux store, similar to PositionPlugin.
Thanks @dahlbyk , I moved to the first approach and make it working somewhat. Here are the changes I made in RowSelection and SelectAllRows. Basically I have a state enabled in my global store and based on that update the state of all checkboxes in RowSelection.
class RowSelection extends Component {
constructor(props) {
super(props);
this.props = props;
this.onRowSelection = this.onRowSelection.bind(this);
this.state = {
isSelected: this.props.isAllChecked
};
}
onRowSelection(e) {
console.log("value, propsValue, GriddleKey, rowData",
e, this.props.vale, this.props.griddleKey, this.props.rowData);
this.setState({
isSelected: e
});
/*
this.dispatch(updateWebActionStatus(this.props.cellProperties.userDetails.ldapId,
this.props.cellProperties.token,
this.props.rowData, !this.props.value));
*/
}
componentWillReceiveProps(nextProps) {
console.log(nextProps);
this.setState({
isSelected: nextProps.isAllChecked
});
}
render() {
return (
<Checkbox
label=""
value={this.state.isSelected}
checked={this.state.isSelected}
onChange={this.onRowSelection}
/>
);
}
}
const mapStateToProps = (state) => {
return {
isAllChecked: state.platforms.serverless.isAllChecked
};
};
export default connect(mapStateToProps)(RowSelection);
class SelectAllRow extends Component {
constructor(props) {
super(props);
this.props = props;
this.dispatch = this.props.cellProperties.dispatch;
this.onAllRowSelection = this.onAllRowSelection.bind(this);
this.state = {
isSelected: this.props.isAllChecked
};
}
onAllRowSelection(e) {
this.dispatch(selectAll(e));
this.setState({
isSelected: e
});
/*
this.dispatch(updateWebActionStatus(this.props.cellProperties.userDetails.ldapId,
this.props.cellProperties.token,
this.props.rowData, !this.props.value));
*/
}
componentWillReceiveProps(nextProps) {
console.log(nextProps);
this.setState({
isSelected: nextProps.isAllChecked
});
}
render() {
return (
<Checkbox
label=""
value={this.state.isSelected}
checked={this.state.isSelected}
onChange={this.onAllRowSelection}
/>
);
}
}
const mapStateToProps = (state) => {
return {
isAllChecked: state.platforms.serverless.isAllChecked
};
};
export default connect(mapStateToProps)(SelectAllRow);
With this I am able to see all checkboxes selected when header checkbox is selected. I am now looking for better solution to update the internal Griddle State for more features for this checkbox flow and will check position plugin for reference to do that.
Thanks for the guidance. I will post once I am done with that.
Griddle version
1.13.1
Expected Behavior
I have a customHeaderComponent which is a check box and CustomColumnComponent which has a checkBox for each row in table.
I want to select Header checkbox to select all rows in the table.
Actual Behavior
Could not figure out a way to achieve it. Can someone please help on this? Also how I can restrict users to select more than one row