diff --git a/build/reactable.js b/build/reactable.js index 7671bed2..64bb7cc9 100644 --- a/build/reactable.js +++ b/build/reactable.js @@ -538,29 +538,49 @@ window.ReactDOM["default"] = window.ReactDOM; console.log(children); } - children = children.concat(this.props.columns.map((function (_ref, i) { + var columnsFromProps = []; + var columnsToSkip = 0; + this.props.columns.forEach((function (_ref, i) { var _ref$props = _ref.props; var props = _ref$props === undefined ? {} : _ref$props; var column = _objectWithoutProperties(_ref, ['props']); - if (this.props.data.hasOwnProperty(column.key)) { - var value = this.props.data[column.key]; + var component = null; - if (typeof value !== 'undefined' && value !== null && value.__reactableMeta === true) { - props = value.props; - value = value.value; + if (columnsToSkip <= 0) { + + if (this.props.data.hasOwnProperty(column.key)) { + var value = this.props.data[column.key]; + + if (typeof value !== 'undefined' && value !== null && value.__reactableMeta === true) { + props = value.props; + value = value.value; + } + + var colSpan = props.colSpan || 1; + + // we will use 1 column (ourself), no need to skip that + columnsToSkip = colSpan - 1; + + component = _react['default'].createElement( + _td.Td, + _extends({ column: column, key: column.key }, props), + value + ); + } else { + component = _react['default'].createElement(_td.Td, { column: column, key: column.key }); } - return _react['default'].createElement( - _td.Td, - _extends({ column: column, key: column.key }, props), - value - ); + if (component !== null) { + columnsFromProps.push(component); + } } else { - return _react['default'].createElement(_td.Td, { column: column, key: column.key }); + columnsToSkip--; } - }).bind(this))); + }).bind(this)); + + children = children.concat(columnsFromProps); } // Manually transfer props diff --git a/lib/reactable/tr.js b/lib/reactable/tr.js index 03331792..aa5b95b7 100644 --- a/lib/reactable/tr.js +++ b/lib/reactable/tr.js @@ -47,29 +47,49 @@ var Tr = (function (_React$Component) { console.log(children); } - children = children.concat(this.props.columns.map((function (_ref, i) { + var columnsFromProps = []; + var columnsToSkip = 0; + this.props.columns.forEach((function (_ref, i) { var _ref$props = _ref.props; var props = _ref$props === undefined ? {} : _ref$props; var column = _objectWithoutProperties(_ref, ['props']); - if (this.props.data.hasOwnProperty(column.key)) { - var value = this.props.data[column.key]; + var component = null; - if (typeof value !== 'undefined' && value !== null && value.__reactableMeta === true) { - props = value.props; - value = value.value; + if (columnsToSkip <= 0) { + + if (this.props.data.hasOwnProperty(column.key)) { + var value = this.props.data[column.key]; + + if (typeof value !== 'undefined' && value !== null && value.__reactableMeta === true) { + props = value.props; + value = value.value; + } + + var colSpan = props.colSpan || 1; + + // we will use 1 column (ourself), no need to skip that + columnsToSkip = colSpan - 1; + + component = _react2['default'].createElement( + _td.Td, + _extends({ column: column, key: column.key }, props), + value + ); + } else { + component = _react2['default'].createElement(_td.Td, { column: column, key: column.key }); } - return _react2['default'].createElement( - _td.Td, - _extends({ column: column, key: column.key }, props), - value - ); + if (component !== null) { + columnsFromProps.push(component); + } } else { - return _react2['default'].createElement(_td.Td, { column: column, key: column.key }); + columnsToSkip--; } - }).bind(this))); + }).bind(this)); + + children = children.concat(columnsFromProps); } // Manually transfer props diff --git a/src/reactable/tr.jsx b/src/reactable/tr.jsx index 003da33c..bb73da15 100644 --- a/src/reactable/tr.jsx +++ b/src/reactable/tr.jsx @@ -14,24 +14,44 @@ export class Tr extends React.Component { ) { if (typeof(children.concat) === 'undefined') { console.log(children); } - children = children.concat(this.props.columns.map(function({ props = {}, ...column}, i) { - if (this.props.data.hasOwnProperty(column.key)) { - var value = this.props.data[column.key]; + var columnsFromProps = []; + var columnsToSkip = 0; + this.props.columns.forEach(function({ props = {}, ...column}, i) { + var component = null; - if ( - typeof(value) !== 'undefined' && + if (columnsToSkip <= 0) { + + if (this.props.data.hasOwnProperty(column.key)) { + var value = this.props.data[column.key]; + + if ( + typeof(value) !== 'undefined' && value !== null && - value.__reactableMeta === true - ) { - props = value.props; - value = value.value; + value.__reactableMeta === true + ) { + props = value.props; + value = value.value; + } + + var colSpan = props.colSpan || 1; + + // we will use 1 column (ourself), no need to skip that + columnsToSkip = colSpan - 1; + + component = {value}; + } else { + component = ; } - return {value}; + if (component !== null) { + columnsFromProps.push(component) + } } else { - return ; + columnsToSkip--; } - }.bind(this))); + }.bind(this)); + + children = children.concat(columnsFromProps); } // Manually transfer props diff --git a/tests/reactable_test.jsx b/tests/reactable_test.jsx index cd98a33c..a8bb6157 100644 --- a/tests/reactable_test.jsx +++ b/tests/reactable_test.jsx @@ -461,6 +461,93 @@ describe('Reactable', function() { }); }); + describe('using colSpan', function() { + describe('basic colSpan', function() { + before(function() { + ReactDOM.render( + React.createElement(Reactable.Table, {className: "table", id: "table"}, + React.createElement(Reactable.Tr, {data: { Name: 'Griffin Smith', Age: '18'}}), + React.createElement(Reactable.Tr, {data: { Age: '23', Name: 'Lee Salminen'}}), + React.createElement(Reactable.Tr, {data: { Age: '28', Position: 'Developer'}}), + React.createElement(Reactable.Tr, null, + React.createElement(Reactable.Td, {column: "Name", colSpan: "3"}, "This summary spans 3 cols") + ) + ), + 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']); + }); + + it('renders the fourth row with the correct data', function() { + ReactableTestUtils.expectRowText(3, ['This summary spans 3 cols']); + }); + }); + + describe('filtering with colSpan', function() { + before(function() { + this.component = React.render( + React.createElement(Reactable.Table, {filterable: ['Name'], className: "table", id: "table"}, + React.createElement(Reactable.Tr, {data: { Name: 'Griffin Smith', Age: '18'}}), + React.createElement(Reactable.Tr, {data: { Age: '23', Name: 'Lee Salminen'}}), + React.createElement(Reactable.Tr, {data: { Age: '28', Position: 'Developer'}}), + React.createElement(Reactable.Tr, null, + React.createElement(Reactable.Td, {column: "Name", colSpan: "3"}, "This summary spans 3 cols") + ) + ), + ReactableTestUtils.testNode() + ); + }); + + after(ReactableTestUtils.resetTestEnvironment); + + context('select colspan value', function() { + before(function() { + this.component.filterBy('summary'); + }); + + it('applies the filtering', function() { + ReactableTestUtils.expectRowText(0, ['This summary spans 3 cols']); + }); + }); + + context('select value from other row', function() { + before(function() { + this.component.filterBy('Griffin'); + }); + + it('applies the filtering', function() { + ReactableTestUtils.expectRowText(0, ['Griffin Smith', '18', '']); + }); + }); + }); + }); + describe('passing through HTML props', function() { describe('adding s with className to the ', function() { before(function() {