diff --git a/packages/react-bootstrap-table2-example/src/index.js b/packages/react-bootstrap-table2-example/src/index.js
index 642fdb1..e6730f5 100644
--- a/packages/react-bootstrap-table2-example/src/index.js
+++ b/packages/react-bootstrap-table2-example/src/index.js
@@ -3,8 +3,64 @@ import ReactDom from 'react-dom';
import { BootstrapTable } from 'react-bootstrap-table2';
-const data = [1, 2, 3, 4];
+const products = [];
+
+function addProducts(quantity) {
+ const startId = products.length;
+ for (let i = 0; i < quantity; i += 1) {
+ const id = startId + i;
+ products.push({
+ id,
+ name: `Item name ${id}`,
+ price: 2100 + i,
+ nest: {
+ address: 'Address 1',
+ postcal: '0922-1234'
+ }
+ });
+ }
+}
+
+addProducts(5);
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID',
+ style: {
+ backgroundColor: 'red'
+ },
+ headerTitle: (column, colIndex) => {
+ console.log(column);
+ console.log(colIndex);
+ return 'yes~~~ oh';
+ },
+ classes: 'my-xxx'
+}, {
+ dataField: 'name',
+ text: 'Product Name',
+ headerTitle: true,
+ formatter: (cell, row) =>
+ (
{ cell }::: ${ row.price }
)
+}, {
+ dataField: 'price',
+ text: 'Product Price',
+ style: (cell, row, colIndex) => {
+ console.log(cell);
+ console.log(row);
+ console.log(colIndex);
+ return {
+ backgroundColor: 'blue'
+ };
+ }
+}, {
+ dataField: 'nest.address',
+ text: 'Address'
+}, {
+ dataField: 'nest.postcal',
+ text: 'Postal'
+}];
+
ReactDom.render(
- ,
+ ,
document.getElementById('example'));
diff --git a/packages/react-bootstrap-table2/src/cell.js b/packages/react-bootstrap-table2/src/cell.js
index a585d20..8d082fe 100644
--- a/packages/react-bootstrap-table2/src/cell.js
+++ b/packages/react-bootstrap-table2/src/cell.js
@@ -9,19 +9,28 @@ const Cell = ({ row, rowIndex, column, columnIndex }) => {
formatter,
formatExtraData,
style,
- classes
+ classes,
+ title
} = column;
let content = _.get(row, dataField);
+ let cellTitle;
+
+ const attrs = {};
const cellStyle = _.isFunction(style) ? style(content, row, columnIndex) : style;
const cellClasses = _.isFunction(classes) ? classes(content, row, columnIndex) : classes;
+
+ if (title) {
+ cellTitle = _.isFunction(title) ? title(content, row, columnIndex) : content;
+ attrs.title = cellTitle;
+ }
+
if (formatter) {
content = column.formatter(content, row, rowIndex, formatExtraData);
}
- const attrs = {
- style: cellStyle,
- className: cellClasses
- };
+ attrs.style = cellStyle;
+ attrs.className = cellClasses;
+
return (
{ content } |
);
diff --git a/packages/react-bootstrap-table2/src/header-cell.js b/packages/react-bootstrap-table2/src/header-cell.js
index e43713b..2385017 100644
--- a/packages/react-bootstrap-table2/src/header-cell.js
+++ b/packages/react-bootstrap-table2/src/header-cell.js
@@ -1,18 +1,36 @@
import React from 'react';
import PropTypes from 'prop-types';
+import _ from './utils';
-const HeaderCell = ({ column }) => (
-
- { column.text }
- |
-);
+
+const HeaderCell = ({ column, index }) => {
+ const { headerTitle, text } = column;
+ const attrs = {};
+
+ if (headerTitle) {
+ attrs.title = _.isFunction(headerTitle) ? headerTitle(column, index) : text;
+ }
+
+ return (
+
+ { column.text }
+ |
+ );
+};
HeaderCell.propTypes = {
column: PropTypes.shape({
dataField: PropTypes.string.isRequired,
- text: PropTypes.string.isRequired
- }).isRequired
+ text: PropTypes.string.isRequired,
+ formatter: PropTypes.func,
+ formatExtraData: PropTypes.any,
+ classes: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
+ style: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
+ headerTitle: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),
+ title: PropTypes.oneOfType([PropTypes.bool, PropTypes.func])
+ }).isRequired,
+ index: PropTypes.number.isRequired
};
export default HeaderCell;
diff --git a/packages/react-bootstrap-table2/src/header.js b/packages/react-bootstrap-table2/src/header.js
index 692e920..eddf6a2 100644
--- a/packages/react-bootstrap-table2/src/header.js
+++ b/packages/react-bootstrap-table2/src/header.js
@@ -7,7 +7,10 @@ import HeaderCell from './header-cell';
const Header = ({ columns }) => (
- { columns.map(column => ) }
+ {
+ columns.map((column, i) =>
+ )
+ }
);
diff --git a/packages/react-bootstrap-table2/test/cell.test.js b/packages/react-bootstrap-table2/test/cell.test.js
index 45157c2..1b204ed 100644
--- a/packages/react-bootstrap-table2/test/cell.test.js
+++ b/packages/react-bootstrap-table2/test/cell.test.js
@@ -161,4 +161,53 @@ describe('Cell', () => {
});
});
});
+
+ describe('when column.title prop is defined', () => {
+ let column;
+ const columnIndex = 1;
+
+ beforeEach(() => {
+ column = {
+ dataField: 'id',
+ text: 'ID'
+ };
+ });
+
+ describe('when title is boolean', () => {
+ beforeEach(() => {
+ column.title = true;
+ wrapper = shallow(
+ | );
+ });
+
+ it('should render title as cell value as default', () => {
+ expect(wrapper.length).toBe(1);
+ expect(wrapper.find('td').prop('title')).toEqual(row[column.dataField]);
+ });
+ });
+
+ describe('when title is custom function', () => {
+ const customTitle = 'test_title';
+ let titleCallBack;
+
+ beforeEach(() => {
+ titleCallBack = sinon.stub()
+ .withArgs(row[column.dataField], row, columnIndex)
+ .returns(customTitle);
+ column.title = titleCallBack;
+ wrapper = shallow(
+ | );
+ });
+
+ it('should render title correctly by custom title function', () => {
+ expect(wrapper.length).toBe(1);
+ expect(wrapper.find('td').prop('title')).toBe(customTitle);
+ });
+
+ it('should call custom title function correctly', () => {
+ expect(titleCallBack.callCount).toBe(1);
+ expect(titleCallBack.calledWith(row[column.dataField], row, columnIndex)).toBe(true);
+ });
+ });
+ });
});
diff --git a/packages/react-bootstrap-table2/test/header-cell.test.js b/packages/react-bootstrap-table2/test/header-cell.test.js
index e0cc3f7..56a9727 100644
--- a/packages/react-bootstrap-table2/test/header-cell.test.js
+++ b/packages/react-bootstrap-table2/test/header-cell.test.js
@@ -1,18 +1,21 @@
import React from 'react';
+import sinon from 'sinon';
import { shallow } from 'enzyme';
import HeaderCell from '../src/header-cell';
describe('HeaderCell', () => {
let wrapper;
- const column = {
- dataField: 'id',
- text: 'ID'
- };
+ const index = 1;
describe('simplest header cell', () => {
+ const column = {
+ dataField: 'id',
+ text: 'ID'
+ };
+
beforeEach(() => {
- wrapper = shallow();
+ wrapper = shallow();
});
it('should render successfully', () => {
@@ -21,4 +24,49 @@ describe('HeaderCell', () => {
expect(wrapper.contains({ column.text } | )).toBe(true);
});
});
+
+ describe('when column.headerTitle prop is defined', () => {
+ let column;
+ beforeEach(() => {
+ column = {
+ dataField: 'id',
+ text: 'ID'
+ };
+ });
+
+ describe('when headerTitle is boolean', () => {
+ beforeEach(() => {
+ column.headerTitle = true;
+ wrapper = shallow();
+ });
+
+ it('should render title as column.text as default', () => {
+ expect(wrapper.length).toBe(1);
+ expect(wrapper.find('th').prop('title')).toBe(column.text);
+ });
+ });
+
+ describe('when headerTitle is custom function', () => {
+ const customTitle = 'test_title';
+ let titleCallBack;
+
+ beforeEach(() => {
+ titleCallBack = sinon.stub()
+ .withArgs(column)
+ .returns(customTitle);
+ column.headerTitle = titleCallBack;
+ wrapper = shallow();
+ });
+
+ it('should render title correctly by custom title function', () => {
+ expect(wrapper.length).toBe(1);
+ expect(wrapper.find('th').prop('title')).toBe(customTitle);
+ });
+
+ it('should call custom title function correctly', () => {
+ expect(titleCallBack.callCount).toBe(1);
+ expect(titleCallBack.calledWith(column)).toBe(true);
+ });
+ });
+ });
});