Skip to content
This repository was archived by the owner on Jan 15, 2022. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 44 additions & 4 deletions src/reactable/table.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export class Table extends React.Component {
super(props);

this.state = {
parsedCustomComponents: false,
currentPage: 0,
currentSort: {
column: null,
Expand Down Expand Up @@ -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') {
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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 <div>{children}</div>;
}
render() {
if (!this.state.parsedCustomComponents && this.customComponentsCount > 0){
return this.renderUnparsedDataTable();
}

let children = [];
let columns;
let userColumnsSpecified = false;
Expand Down
64 changes: 64 additions & 0 deletions tests/reactable_test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,70 @@ describe('Reactable', function() {
});
});

describe('adding <CustomComponents>s to the <Table>', 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 (
<Reactable.Tr>
<Reactable.Td column="Name">{this.props.name}</Reactable.Td>
<Reactable.Td column="Age">{this.props.age}</Reactable.Td>
<Reactable.Td column="Position">{this.props.position}</Reactable.Td>
</Reactable.Tr>
);
}
});
React.render(
<Reactable.Table className="table" id="table">
<CustomComponent name='Griffin Smith' age={18} />
<CustomComponent name='Lee Salminen' age={23} />
<CustomComponent age={28} position='Developer' />
</Reactable.Table>,
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 <Tr>s with className to the <Table>', function() {
before(function() {
Expand Down