Skip to content
This repository has been archived by the owner on Jan 15, 2022. It is now read-only.

columnFormatters: assign a component to render a column's cells #333

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
15 changes: 12 additions & 3 deletions build/reactable.js
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,12 @@ window.ReactDOM["default"] = window.ReactDOM;
if ((0, _unsafe.isUnsafe)(this.props.children)) {
return _react['default'].createElement('td', _extends({}, mergedProps, {
dangerouslySetInnerHTML: { __html: this.props.children.toString() } }));
} else if (typeof this.props.formatter !== 'undefined') {
return _react['default'].createElement(
'td',
mergedProps,
_react['default'].createElement(this.props.formatter, _extends({}, mergedProps, { text: this.props.children }))
);
} else {
return _react['default'].createElement(
'td',
Expand Down Expand Up @@ -537,6 +543,9 @@ window.ReactDOM["default"] = window.ReactDOM;
}

children = children.concat(this.props.columns.map((function (column, i) {

var formatter = this.props.columnFormatters ? this.props.columnFormatters[column.key] : undefined;

if (this.props.data.hasOwnProperty(column.key)) {
var value = this.props.data[column.key];
var props = {};
Expand All @@ -548,11 +557,11 @@ window.ReactDOM["default"] = window.ReactDOM;

return _react['default'].createElement(
_td.Td,
_extends({ column: column, key: column.key }, props),
_extends({ column: column, formatter: formatter, key: column.key }, props),
value
);
} else {
return _react['default'].createElement(_td.Td, { column: column, key: column.key });
return _react['default'].createElement(_td.Td, { column: column, formatter: formatter, key: column.key });
}
}).bind(this)));
}
Expand Down Expand Up @@ -1448,7 +1457,7 @@ window.ReactDOM["default"] = window.ReactDOM;
}
}

return _react['default'].createElement(_tr.Tr, _extends({ columns: columns, key: i, data: data }, props));
return _react['default'].createElement(_tr.Tr, _extends({ columns: columns, key: i, data: data, columnFormatters: this.props.columnFormatters }, props));
}).bind(this)));
}

Expand Down
2 changes: 1 addition & 1 deletion lib/reactable/table.js
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ var Table = (function (_React$Component) {
}
}

return _react2['default'].createElement(_tr.Tr, _extends({ columns: columns, key: i, data: data }, props));
return _react2['default'].createElement(_tr.Tr, _extends({ columns: columns, key: i, data: data, columnFormatters: this.props.columnFormatters }, props));
}).bind(this)));
}

Expand Down
6 changes: 6 additions & 0 deletions lib/reactable/td.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ var Td = (function (_React$Component) {
if ((0, _unsafe.isUnsafe)(this.props.children)) {
return _react2['default'].createElement('td', _extends({}, mergedProps, {
dangerouslySetInnerHTML: { __html: this.props.children.toString() } }));
} else if (typeof this.props.formatter !== 'undefined') {
return _react2['default'].createElement(
'td',
mergedProps,
_react2['default'].createElement(this.props.formatter, _extends({}, mergedProps, { text: this.props.children }))
);
} else {
return _react2['default'].createElement(
'td',
Expand Down
7 changes: 5 additions & 2 deletions lib/reactable/tr.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ var Tr = (function (_React$Component) {
}

children = children.concat(this.props.columns.map((function (column, i) {

var formatter = this.props.columnFormatters ? this.props.columnFormatters[column.key] : undefined;

if (this.props.data.hasOwnProperty(column.key)) {
var value = this.props.data[column.key];
var props = {};
Expand All @@ -57,11 +60,11 @@ var Tr = (function (_React$Component) {

return _react2['default'].createElement(
_td.Td,
_extends({ column: column, key: column.key }, props),
_extends({ column: column, formatter: formatter, key: column.key }, props),
value
);
} else {
return _react2['default'].createElement(_td.Td, { column: column, key: column.key });
return _react2['default'].createElement(_td.Td, { column: column, formatter: formatter, key: column.key });
}
}).bind(this)));
}
Expand Down
2 changes: 1 addition & 1 deletion src/reactable/table.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ export class Table extends React.Component {
}

return (
<Tr columns={columns} key={i} data={data} {...props} />
<Tr columns={columns} key={i} data={data} columnFormatters={this.props.columnFormatters} {...props} />
);
}.bind(this)));
}
Expand Down
2 changes: 2 additions & 0 deletions src/reactable/td.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export class Td extends React.Component {
if (isUnsafe(this.props.children)) {
return <td {...mergedProps}
dangerouslySetInnerHTML={{__html: this.props.children.toString()}}/>
} else if (typeof this.props.formatter !== 'undefined') {
return <td {...mergedProps}><this.props.formatter {...mergedProps} text={this.props.children} /></td>;
} else {
return <td {...mergedProps}>
{stringifiedChildProps || this.props.children}
Expand Down
9 changes: 7 additions & 2 deletions src/reactable/tr.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ export class Tr extends React.Component {
) {
if (typeof(children.concat) === 'undefined') { console.log(children); }


children = children.concat(this.props.columns.map(function(column, i) {

const formatter = (this.props.columnFormatters) ? this.props.columnFormatters[column.key] : undefined;

if (this.props.data.hasOwnProperty(column.key)) {
var value = this.props.data[column.key];
var props = {};
Expand All @@ -28,9 +32,10 @@ export class Tr extends React.Component {
value = value.value;
}

return <Td column={column} key={column.key} {...props}>{value}</Td>;

return <Td column={column} formatter={formatter} key={column.key} {...props}>{value}</Td>;
} else {
return <Td column={column} key={column.key} />;
return <Td column={column} formatter={formatter} key={column.key} />;
}
}.bind(this)));
}
Expand Down
32 changes: 25 additions & 7 deletions test.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<script src="https://fb.me/react-0.13.3.js"></script>
<script src="https://fb.me/JSXTransformer-0.13.3.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/react/0.14.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0/react-dom.js"></script>
<script src="http://fb.me/JSXTransformer-0.13.3.js"></script>
<script src="build/reactable.js" type="text/javascript"></script>
<script type="text/jsx">
/** @jsx React.DOM */
Expand All @@ -13,11 +14,28 @@
Td = Reactable.Td,
unsafe = Reactable.unsafe;

React.render(
<Table className="table" id="table" data={[
{ Name: Reactable.unsafe('<span id="griffins-name">Griffin Smith</span>'), Age: '18'},
{ Age: '28', Position: Reactable.unsafe('<span id="who-knows-job">Developer</span>')},
{ Age: '23', Name: Reactable.unsafe('<span id="lees-name">Lee Salminen</span>')},

class Cell extends React.Component {

handleClick(){
alert(this.props.text);
}

render() {
if (this.props.text) {
return <button onClick={this.handleClick.bind(this)}>{this.props.text}</button>;
} else {
return null;
}

}
}

ReactDOM.render(
<Table className="table" columnFormatters={ { 'Name' : Cell, 'Position': Cell } } id="table" data={[
{ Name: 'Griffin Smith', Age: '18'},
{ Age: '28', Name:'Aaron Lisman', Position:'Developer'},
{ Age: '23', Name: <i>Lee Salminen</i> },
]} sortable={['Name']} />,
document.getElementById('test-div')
);
Expand Down
55 changes: 55 additions & 0 deletions tests/reactable_test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,61 @@ describe('Reactable', function() {
});
});


describe('directly passing a data array and columnFormatters', function() {
before(function() {

// class Cell extends React.Component {
// render() {
// if (this.props.text) {
// return <button className="testButton" onClick={this.handleClick.bind(this)}>{this.props.text}</button>;
// } else {
// return null;
// }
// }
// }

var Cell = React.createClass({
render(){
if (this.props.text) {
return <button className="testButton">{this.props.text}</button>;
} else {
return null;
}
}

});

ReactDOM.render(
<Reactable.Table className="table" id="table" data={[
{ Name: 'Griffin Smith', Age: '18'},
{ Age: '23', Name: 'Lee Salminen'},
{ Age: '30', Position: 'Developer'},
{ Name: <i>Leonor Hyatt</i>, Position: null}
]} columnFormatters={{Name:Cell}}/>,
ReactableTestUtils.testNode()
);
});

after(ReactableTestUtils.resetTestEnvironment);

it('uses component to render cells in a column', function() {
expect($('.testButton').size()).to.equal(3);
});


it('handles absence of corresponding data property', function() {
ReactableTestUtils.expectRowText(2, ['', '30', 'Developer']);
});

it('handles jsx in data', function() {
expect($('td button i').text()).to.equal('Leonor Hyatt');
});

});



describe('adding <Tr>s to the <Table>', function() {
before(function() {
ReactDOM.render(
Expand Down