Implement column title (#22)

fix #21
This commit is contained in:
Allen
2017-08-26 02:24:00 -05:00
committed by GitHub
parent 1c07b6cbd3
commit 20bb9c0d1b
6 changed files with 203 additions and 20 deletions

View File

@@ -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) =>
(<h3>{ cell }::: ${ row.price }</h3>)
}, {
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(
<BootstrapTable data={ data } />,
<BootstrapTable keyField="id" data={ products } columns={ columns } />,
document.getElementById('example'));

View File

@@ -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 (
<td { ...attrs }>{ content }</td>
);

View File

@@ -1,18 +1,36 @@
import React from 'react';
import PropTypes from 'prop-types';
import _ from './utils';
const HeaderCell = ({ column }) => (
<th>
{ column.text }
</th>
);
const HeaderCell = ({ column, index }) => {
const { headerTitle, text } = column;
const attrs = {};
if (headerTitle) {
attrs.title = _.isFunction(headerTitle) ? headerTitle(column, index) : text;
}
return (
<th { ...attrs }>
{ column.text }
</th>
);
};
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;

View File

@@ -7,7 +7,10 @@ import HeaderCell from './header-cell';
const Header = ({ columns }) => (
<thead>
<tr>
{ columns.map(column => <HeaderCell key={ column.dataField } column={ column } />) }
{
columns.map((column, i) =>
<HeaderCell key={ column.dataField } column={ column } index={ i } />)
}
</tr>
</thead>
);

View File

@@ -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(
<Cell row={ row } columnIndex={ columnIndex } rowIndex={ 1 } column={ column } />);
});
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(
<Cell row={ row } columnIndex={ columnIndex } rowIndex={ 1 } column={ column } />);
});
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);
});
});
});
});

View File

@@ -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(<HeaderCell column={ column } />);
wrapper = shallow(<HeaderCell column={ column } index={ index } />);
});
it('should render successfully', () => {
@@ -21,4 +24,49 @@ describe('HeaderCell', () => {
expect(wrapper.contains(<th>{ column.text }</th>)).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(<HeaderCell column={ column } index={ index } />);
});
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(<HeaderCell column={ column } index={ index } />);
});
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);
});
});
});
});