diff --git a/src/reactable/table.jsx b/src/reactable/table.jsx index f7082d91..db0e41f9 100644 --- a/src/reactable/table.jsx +++ b/src/reactable/table.jsx @@ -12,6 +12,7 @@ export class Table extends React.Component { super(props); this.state = { + parsedCustomComponents: false, currentPage: 0, currentSort: { column: null, @@ -52,7 +53,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') { @@ -111,19 +112,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); } @@ -205,6 +213,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); @@ -296,8 +324,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 45137eb4..54e0b557 100644 --- a/tests/reactable_test.jsx +++ b/tests/reactable_test.jsx @@ -417,6 +417,70 @@ describe('Reactable', function() { }); }); + describe('adding s to the ', function() { + before(function() { + var CustomComponent = React.createClass({ + displayName: "CustomComponent", + propTypes:{ + name: React.PropTypes.string, + 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 ( + + {this.props.name} + {this.props.age} + {this.props.position} + + ); + } + }); + React.render( + + + + + , + ReactableTestUtils.testNode() + ); + }); + + after(ReactableTestUtils.resetTestEnvironment); + + it('renders the table', function() { + expect($('table#table.table')).to.exist; + }); + + it('renders the column headers in the table', function() { + var headers = []; + $('thead th').each(function() { + headers.push($(this).text()); + }); + + expect(headers).to.eql([ 'Name', 'Age', 'Position' ]); + }); + + it('renders the first row with the correct data', function() { + ReactableTestUtils.expectRowText(0, ['Griffin Smith', '18', '']); + }); + + it('renders the second row with the correct data', function() { + ReactableTestUtils.expectRowText(1, ['Lee Salminen', '23', '']); + }); + + it('renders the third row with the correct data', function() { + ReactableTestUtils.expectRowText(2, ['', '28', 'Developer']); + }); + }); + describe('passing through HTML props', function() { describe('adding s with className to the
', function() { before(function() {