From 1fc822d30d3f5bd0be4d80826b345cc1dbf5739b Mon Sep 17 00:00:00 2001 From: Thomas Shafer Date: Thu, 13 Aug 2015 11:39:59 -0700 Subject: [PATCH] prototype solution to custom components Since react will not render child components until the parent component is rendered (exploratory hypotheis) We need to render the custom component first and then access the component. This uses a Component function of getData(). The getData function could/should be fast because after the render function all the data could be available via props or state I have not tested this with updating data from the custom component. Or if the custom component internally changes the data and they table needs to resort. --- src/reactable/table.jsx | 48 ++++++++++++++++++++++++++++++++++++---- tests/reactable_test.jsx | 7 ++++++ 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/reactable/table.jsx b/src/reactable/table.jsx index e69f1bd3..74e12ea0 100644 --- a/src/reactable/table.jsx +++ b/src/reactable/table.jsx @@ -13,6 +13,7 @@ export class Table extends React.Component { super(props); this.state = { + parsedCustomComponents: false, currentPage: 0, currentSort: { column: null, @@ -53,7 +54,7 @@ export class Table extends React.Component { } parseChildData(props) { - let data = [], tfoot; + let data = [], tfoot, customComponentsCount = 0; // Transform any children back to a data array if (typeof(props.children) !== 'undefined') { @@ -112,19 +113,26 @@ export class Table extends React.Component { __reactableMeta: true }); break; + default: + // Don't know if there are other acceptable types + // that should be dismissed + // console.log("Table, got custom component", child.type) + customComponentsCount++; + break; } }.bind(this)); } - return { data, tfoot }; + return { data, tfoot, customComponentsCount }; } initialize(props) { this.data = props.data || []; - let { data, tfoot } = this.parseChildData(props); + let { data, tfoot, customComponentsCount } = this.parseChildData(props); this.data = this.data.concat(data); this.tfoot = tfoot; + this.customComponentsCount = customComponentsCount; this.initializeSorts(props); } @@ -206,6 +214,26 @@ export class Table extends React.Component { this.sortByCurrentSort(); } + componentDidMount() { + for (var i = 0; i < this.customComponentsCount; i++) { + let child = this.refs['child-'+i], + childData = child.getData(), + childDataToPush = {}; + for (var key in childData){ + childDataToPush[key] = { + value: childData[key], + __reactableMeta: true + }; + } + this.data.push({ + data: childDataToPush, + props: filterPropsFrom(child.props), + __reactableMeta: true + }); + }; + this.setState({parsedCustomComponents: true}); + } + componentWillReceiveProps(nextProps) { this.initialize(nextProps); this.updateCurrentSort(nextProps.sortBy); @@ -297,8 +325,20 @@ export class Table extends React.Component { this.setState({ currentSort: currentSort }); this.sortByCurrentSort(); } - + renderUnparsedDataTable() { + // http://www.mattzabriskie.com/blog/react-referencing-dynamic-children + let index = 0; + let children = React.Children.map(this.props.children, function (child) { + return React.addons.cloneWithProps(child, {ref: 'child-' + (index++) }); + }); + + return
{children}
; + } render() { + if (!this.state.parsedCustomComponents && this.customComponentsCount > 0){ + return this.renderUnparsedDataTable(); + } + let children = []; let columns; let userColumnsSpecified = false; diff --git a/tests/reactable_test.jsx b/tests/reactable_test.jsx index d9b5fe19..f22da064 100644 --- a/tests/reactable_test.jsx +++ b/tests/reactable_test.jsx @@ -426,6 +426,13 @@ describe('Reactable', function() { age: React.PropTypes.number, position: React.PropTypes.string }, + getData: function(){ + return { + Name: this.props.name, + Age: this.props.age, + Position: this.props.position, + } + }, render: function(){ return (