* redefine cell callback function

* it takes 4 argus `content`, `row`, `rowIndex` and `columnIndex` in
* sequence.

* [test] fix unit test for new callback

* correct the version of story for new cell callback

* [DOC] re-define structure of Contents of Table

* [DOC] update document for attrs

* re-write description for each column props

* [DOC] update document for headerCell

* re-write and add extra description for each header column props
This commit is contained in:
ChunMing, Chen 2017-09-16 13:03:07 +08:00 committed by Allen
parent 79fb2523d4
commit ec1a927001
8 changed files with 258 additions and 75 deletions

View File

@ -2,23 +2,26 @@
Available properties in a column object:
#### Required
* [dataField (**required**)](#dataField)
* [text (**required**)](#text)
#### Optional
* [hidden](#hidden)
* [formatter](#formatter)
* [headerFormatter](#headerFormatter)
* [formatExtraData](#formatExtraData)
* [headerFormatter](#headerFormatter)
* [classes](#classes)
* [style](#style)
* [title](#title)
* [events](#events)
* [align](#align)
* [attrs](#attrs)
* [headerClasses](#headerClasses)
* [headerStyle](#headerStyle)
* [headerTitle](#headerTitle)
* [headerEvents](#headerEvents)
* [headerAlign](#headerAlign)
* [headerClasses](#headerClasses)
* [headerStyle](#headerStyle)
* [headerAttrs](#headerAttrs)
Following is a most simplest and basic usage:
@ -91,14 +94,27 @@ It's availabe to have custom class on table column:
classes: 'id-custom-cell'
}
```
In addition, `classes` also accept a callback function which have more power to custom the css class on each columns. This callback function take three arguments and a string is expect to return:
In addition, `classes` also accept a callback function which have more power to custom the css class on each columns. This callback function take `4` arguments and a `string` is expect to return:
* `cell`
* `row`
* `colIndex`
```js
{
classes: function callback(cell, row, rowIndex, colIndex) { ... }
}
```
**Parameters**
* `cell`: The value of current cell.
* `row`: The value of `row` being processed in the `BootstrapTable`.
* `rowIndex`: The index of the current `row` being processed in the `BootstrapTable`.
* `colIndex`: The index of the current `column` being processed in `BootstrapTable`.
**Return value**
A new `String` will be the result of element class.
## <a name='headerClasses'>column.headerClasses - [String | Function]</a>
It's availabe to have customized class on table header column:
It's similar to [`column.classes`](#classes), `headerClasses` is availabe to have customized class on table header column:
```js
{
@ -106,13 +122,24 @@ It's availabe to have customized class on table header column:
headerClasses: 'id-custom-cell'
}
```
In addition, similar to [`column.classes`](#classes), `headerClasses` also accept a callback function which have more power to custom the css class on header column. This callback function take two arguments and a string is expect to return:
Furthermore, it also accept a callback function which takes 2 arguments and a `String` is expect to return:
* `column`
* `colIndex`
```js
{
headerClasses: function callback(column, colIndex) { ... }
}
```
**Parameters**
* `column`: The value of current column.
* `colIndex`: The index of the current `column` being processed in `BootstrapTable`.
**Return value**
A new `String` will be the result of element headerClasses.
## <a name='style'>column.style - [Object | Function]</a>
It's availabe to have custom class on table column:
It's availabe to have custom style on table column:
```js
{
@ -120,7 +147,26 @@ It's availabe to have custom class on table column:
style: { backgroundColor: 'green' }
}
```
`style` like [`column.classes`](#classes), it accept a callback function too and have same arguments: `cell`, `row` and `colIndex`.
In addition, similar to [`column.classes`](#classes), `style` also accept a callback function which have more power to customize the `inline style` on each columns. This callback function takes `4` arguments and an `Object` is expect to return:
```js
{
style: function callback(cell, row, rowIndex, colIndex) { ... }
}
```
**Parameters**
* `cell`: The value of current cell.
* `row`: The value of `row` being processed in the `BootstrapTable`.
* `rowIndex`: The index of the current `row` being processed in the `BootstrapTable`.
* `colIndex`: The index of the current `column` being processed in `BootstrapTable`.
**Return value**
A new `Object` will be the result of element style.
## <a name='headerStyle'>column.headerStyle - [Object | Function]</a>
It's availabe to have customized inline-style on table header column:
@ -131,42 +177,104 @@ It's availabe to have customized inline-style on table header column:
headerStyle: { backgroundColor: 'green' }
}
```
`headerStyle` like [`column.headerClasses`](#headerClasses), it accept a callback function as well and have same arguments: `column` and `colIndex`.
Moreover, it also accept a callback function which takes 2 arguments and an `Object` is expect to return:
```js
{
headerStyle: function callback(column, colIndex) { ... }
}
```
**Parameters**
* `column`: The value of current column.
* `colIndex`: The index of the current `column` being processed in `BootstrapTable`.
**Return value**
A new `Object` will be the result of element headerStyle.
## <a name='title'>column.title - [Bool | Function]</a>
`react-bootstrap-table2` is disable [`HTML title`](https://www.w3schools.com/tags/tag_title.asp) as default. You can assign `title` as `true` to enable the HTML title on table column. In addition, you can custom the title via a callback function:
`react-bootstrap-table2` is disable [`HTML title`](https://www.w3schools.com/tags/tag_title.asp) as default. You can assign `title` as `true` to enable the HTML title on table column and take `cell content` as default value. Additionally, you could customize title via a callback. It takes `4` arguments and a `String` is expect to return:
```js
{
// omit...
title: (cell, row, colIndex) => {
// return custom title here
}
title: function callback(cell, row, rowIndex, colIndex) { ... }
// return custom title here
}
```
**Parameters**
* `cell`: The value of current cell.
* `row`: The value of `row` being processed in the `BootstrapTable`.
* `rowIndex`: The index of the current `row` being processed in the `BootstrapTable`.
* `colIndex`: The index of the current `column` being processed in `BootstrapTable`.
**Return value**
A new `String` will be the result of element title.
## <a name='headerTitle'>column.headerTitle - [Bool | Function]</a>
`headerTitle` is only for the title on header column, default is disable. The usage almost same as [`column.title`](#title), it's also availabe to custom via a callback function:
`headerTitle` is only for the title on header column, default is disable. The usage almost same as [`column.title`](#title),
```js
{
// omit...
headerTitle: (column, colIndex) => {
// column is an object and perform itself
// return custom title here
}
headerTitle: true
}
```
## <a name='align'>column.align - [String | Function]</a>
You can configure the [CSS text-align](https://www.w3schools.com/cssref/pr_text_text-align.asp) for table column by `align` property. However, `align` also accept a callback function for customizable reason and this function take fore arguments:
It's also availabe to custom via a callback function:
```js
{
headerTitle: function callback(column, colIndex) { ... }
}
```
* `cell`
* `row`
* `colIndex`
**Parameters**
* `column`: The value of current column.
* `colIndex`: The index of the current `column` being processed in `BootstrapTable`.
**Return value**
A new `String` will be the result of element headerTitle.
## <a name='align'>column.align - [String | Function]</a>
You can configure the [CSS text-align](https://www.w3schools.com/cssref/pr_text_text-align.asp) for table column by `align` property.
Besides, `align` also accept a callback function for dynamically setting text align. It takes `4` arguments and a `String` is expect to return:
```js
{
// omit...
align: function callback(cell, row, rowIndex, colIndex) { ... }
}
```
**Parameters**
* `cell`: The value of current cell.
* `row`: The value of `row` being processed in the `BootstrapTable`.
* `rowIndex`: The index of the current `row` being processed in the `BootstrapTable`.
* `colIndex`: The index of the current `column` being processed in `BootstrapTable`.
**Return value**
A new `String` will be the result of element text alignment.
## <a name='headerAlign'>column.headerAlign - [String | Function]</a>
It's almost same as [`column.align`](#align), but it's for the [CSS text-align](https://www.w3schools.com/cssref/pr_text_text-align.asp) on header column. Also, you can custom the align by a callback function:
It's almost same as [`column.align`](#align), but it's for the [CSS text-align](https://www.w3schools.com/cssref/pr_text_text-align.asp) on header column.
```js
{
// omit...
headerAlign: 'center'
}
```
Also, you can custom the align by a callback function:
```js
{
@ -177,6 +285,14 @@ It's almost same as [`column.align`](#align), but it's for the [CSS text-align](
}
}
```
**Parameters**
* `column`: The value of current column.
* `colIndex`: The index of the current `column` being processed in `BootstrapTable`.
**Return value**
A new `String` will be the result of element headerAlign.
## <a name='events'>column.events - [Object]</a>
You can assign any [HTML Event](https://www.w3schools.com/tags/ref_eventattributes.asp) on table column via event property:
@ -193,17 +309,44 @@ You can assign any [HTML Event](https://www.w3schools.com/tags/ref_eventattribut
## <a name='headerEvents'>column.headerEvents - [Object]</a>
`headerEvents` same as [`column.events`](#events) but this is for header column.
```js
{
// omit...
headerEvents: {
onClick: e => { ... }
}
}
```
## <a name='attrs'>column.attrs - [Object | Function]</a>
Via `attrs` property, You can costomize table column [HTML attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes) which allow user to configure the elements or adjust their behavior. It takes `Object` and `callback function` is also acceptable.
Via `attrs` property, You can customize table column [HTML attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes) which allow user to configure the elements or adjust their behavior.
```js
{
// omit...
attrs: (cell, row, colIndex) => ({
// return customized HTML attribute here
})
attrs: {
title: 'bar',
'data-test': 'foo'
}
}
```
Not only `Object`, `callback function` is also acceptable. It takes `4` arguments and an `Object` is expect to return:
```js
{
attrs: function callback(cell, row, rowIndex, colIndex) { ... }
}
```
**Parameters**
* `cell`: The value of current cell.
* `row`: The value of `row` being processed in the `BootstrapTable`.
* `rowIndex`: The index of the current `row` being processed in the `BootstrapTable`.
* `colIndex`: The index of the current `column` being processed in `BootstrapTable`.
**Return value**
A new `Object` will be the result of element HTML attributes.
#### * Caution
@ -218,7 +361,18 @@ If `column.classes`, `column.style`, `column.title`, `column.hidden` or `column.
```
## <a name='headerAttrs'>column.headerAttrs - [Object | Function]</a>
`headerAttrs` is similiar to [`column.attrs`](#attrs) but it's for header column.
`headerAttrs` is similiar to [`column.attrs`](#attrs) but it works for header column.
```js
{
// omit...
headerAttrs: {
title: 'bar',
'data-test': 'foo'
}
}
```
Additionally, customize the header attributes by a `2-arguments` callback function:
```js
{
@ -228,3 +382,14 @@ If `column.classes`, `column.style`, `column.title`, `column.hidden` or `column.
})
}
```
**Parameters**
* `column`: The value of current column.
* `colIndex`: The index of the current `column` being processed in `BootstrapTable`.
**Return value**
A new `Object` will be the result of element headerAttrs.
#### * Caution
Same as [column.attrs](#attrs), it has lower priority and will be overwrited when other props related to HTML attributes were given.

View File

@ -14,8 +14,8 @@ const columns = [{
}, {
dataField: 'name',
text: 'Product Name',
align: (cell, row, colIndex) => {
if (row.id % 2 === 0) return 'right';
align: (cell, row, rowIndex, colIndex) => {
if (rowIndex % 2 === 0) return 'right';
return 'left';
}
}, {
@ -31,8 +31,8 @@ const columns = [{
}, {
dataField: 'name',
text: 'Product Name',
align: (cell, row, colIndex) => {
if (row.id % 2 === 0) return 'right';
align: (cell, row, rowIndex, colIndex) => {
if (rowIndex % 2 === 0) return 'right';
return 'left';
}
}, {

View File

@ -14,7 +14,7 @@ const columns = [{
}, {
dataField: 'name',
text: 'Product Name',
attrs: (cell, row, colIndex) => ({ 'data-test': `customized data ${colIndex}` })
attrs: (cell, row, rowIndex, colIndex) => ({ 'data-test': `customized data ${rowIndex}` })
}, {
dataField: 'price',
text: 'Product Price'
@ -28,7 +28,7 @@ const columns = [{
}, {
dataField: 'name',
text: 'Product Name',
attrs: (cell, row, colIndex) => ({ 'data-test': \`customized data \${colIndex}\` })
attrs: (cell, row, rowIndex, colIndex) => ({ 'data-test': \`customized data \${rowIndex}\` })
}, {
dataField: 'price',
text: 'Product Price'

View File

@ -14,8 +14,8 @@ const columns = [{
}, {
dataField: 'name',
text: 'Product Name',
classes: (cell, row, colIndex) => {
if (row.id % 2 === 0) return 'demo-row-even';
classes: (cell, row, rowIndex, colIndex) => {
if (rowIndex % 2 === 0) return 'demo-row-even';
return 'demo-row-odd';
}
}, {
@ -31,8 +31,8 @@ const columns = [{
}, {
dataField: 'name',
text: 'Product Name',
classes: (cell, row, colIndex) => {
if (row.id % 2 === 0) return 'demo-row-even';
classes: (cell, row, rowIndex, colIndex) => {
if (rowIndex % 2 === 0) return 'demo-row-even';
return 'demo-row-odd';
}
}, {

View File

@ -17,8 +17,8 @@ const columns = [{
}, {
dataField: 'name',
text: 'Product Name',
style: (cell, row, colIndex) => {
if (row.id % 2 === 0) {
style: (cell, row, rowIndex, colIndex) => {
if (rowIndex % 2 === 0) {
return {
backgroundColor: '#81c784'
};
@ -43,8 +43,8 @@ const columns = [{
}, {
dataField: 'name',
text: 'Product Name',
style: (cell, row, colIndex) => {
if (row.id % 2 === 0) {
style: (cell, row, rowIndex, colIndex) => {
if (rowIndex % 2 === 0) {
return {
backgroundColor: '#81c784'
};

View File

@ -14,7 +14,7 @@ const columns = [{
}, {
dataField: 'name',
text: 'Product Name',
title: (cell, row, colIndex) => `this is custom title for ${cell}`
title: (cell, row, rowIndex, colIndex) => `this is custom title for ${cell}`
}, {
dataField: 'price',
text: 'Product Price'
@ -28,7 +28,7 @@ const columns = [{
}, {
dataField: 'name',
text: 'Product Name',
title: (cell, row, colIndex) => \`this is custom title for \${cell}\`
title: (cell, row, rowIndex, colIndex) => \`this is custom title for \${cell}\`
}, {
dataField: 'price',
text: 'Product Price'

View File

@ -21,18 +21,20 @@ const Cell = ({ row, rowIndex, column, columnIndex }) => {
let content = _.get(row, dataField);
const cellAttrs = {
..._.isFunction(attrs) ? attrs(content, row, columnIndex) : attrs,
..._.isFunction(attrs) ? attrs(content, row, rowIndex, columnIndex) : attrs,
...events
};
const cellClasses = _.isFunction(classes) ? classes(content, row, columnIndex) : classes;
const cellClasses = _.isFunction(classes)
? classes(content, row, rowIndex, columnIndex)
: classes;
if (style) {
cellStyle = _.isFunction(style) ? style(content, row, columnIndex) : style;
cellStyle = _.isFunction(style) ? style(content, row, rowIndex, columnIndex) : style;
}
if (title) {
cellTitle = _.isFunction(title) ? title(content, row, columnIndex) : content;
cellTitle = _.isFunction(title) ? title(content, row, rowIndex, columnIndex) : content;
cellAttrs.title = cellTitle;
}
@ -41,7 +43,7 @@ const Cell = ({ row, rowIndex, column, columnIndex }) => {
}
if (align) {
cellStyle.textAlign = _.isFunction(align) ? align(content, row, columnIndex) : align;
cellStyle.textAlign = _.isFunction(align) ? align(content, row, rowIndex, columnIndex) : align;
}
if (hidden) {

View File

@ -81,6 +81,7 @@ describe('Cell', () => {
describe('when column.style prop is defined', () => {
let column;
const columnIndex = 1;
const rowIndex = 1;
beforeEach(() => {
column = {
@ -93,7 +94,7 @@ describe('Cell', () => {
beforeEach(() => {
column.style = { backgroundColor: 'red' };
wrapper = shallow(
<Cell row={ row } columnIndex={ columnIndex } rowIndex={ 1 } column={ column } />);
<Cell row={ row } columnIndex={ columnIndex } rowIndex={ rowIndex } column={ column } />);
});
it('should render successfully', () => {
@ -108,11 +109,11 @@ describe('Cell', () => {
beforeEach(() => {
styleCallBack = sinon.stub()
.withArgs(row[column.dataField], row, columnIndex)
.withArgs(row[column.dataField], row, rowIndex, columnIndex)
.returns(returnStyle);
column.style = styleCallBack;
wrapper = shallow(
<Cell row={ row } columnIndex={ columnIndex } rowIndex={ 1 } column={ column } />);
<Cell row={ row } columnIndex={ columnIndex } rowIndex={ rowIndex } column={ column } />);
});
afterEach(() => { styleCallBack.reset(); });
@ -124,7 +125,9 @@ describe('Cell', () => {
it('should call custom style function correctly', () => {
expect(styleCallBack.callCount).toBe(1);
expect(styleCallBack.calledWith(row[column.dataField], row, columnIndex)).toBe(true);
expect(
styleCallBack.calledWith(row[column.dataField], row, rowIndex, columnIndex)
).toBe(true);
});
});
});
@ -132,6 +135,7 @@ describe('Cell', () => {
describe('when column.classes prop is defined', () => {
let column;
const columnIndex = 1;
const rowIndex = 1;
beforeEach(() => {
column = {
@ -144,7 +148,7 @@ describe('Cell', () => {
beforeEach(() => {
column.classes = 'td-test-class';
wrapper = shallow(
<Cell row={ row } columnIndex={ columnIndex } rowIndex={ 1 } column={ column } />);
<Cell row={ row } columnIndex={ columnIndex } rowIndex={ rowIndex } column={ column } />);
});
it('should render successfully', () => {
@ -159,11 +163,11 @@ describe('Cell', () => {
beforeEach(() => {
classesCallBack = sinon.stub()
.withArgs(row[column.dataField], row, columnIndex)
.withArgs(row[column.dataField], row, rowIndex, columnIndex)
.returns(returnClasses);
column.classes = classesCallBack;
wrapper = shallow(
<Cell row={ row } columnIndex={ columnIndex } rowIndex={ 1 } column={ column } />);
<Cell row={ row } columnIndex={ columnIndex } rowIndex={ rowIndex } column={ column } />);
});
afterEach(() => { classesCallBack.reset(); });
@ -175,7 +179,9 @@ describe('Cell', () => {
it('should call custom classes function correctly', () => {
expect(classesCallBack.callCount).toBe(1);
expect(classesCallBack.calledWith(row[column.dataField], row, columnIndex)).toBe(true);
expect(
classesCallBack.calledWith(row[column.dataField], row, rowIndex, columnIndex)
).toBe(true);
});
});
});
@ -183,6 +189,7 @@ describe('Cell', () => {
describe('when column.title prop is defined', () => {
let column;
const columnIndex = 1;
const rowIndex = 1;
beforeEach(() => {
column = {
@ -195,7 +202,7 @@ describe('Cell', () => {
beforeEach(() => {
column.title = true;
wrapper = shallow(
<Cell row={ row } columnIndex={ columnIndex } rowIndex={ 1 } column={ column } />);
<Cell row={ row } columnIndex={ columnIndex } rowIndex={ rowIndex } column={ column } />);
});
it('should render title as cell value as default', () => {
@ -210,11 +217,11 @@ describe('Cell', () => {
beforeEach(() => {
titleCallBack = sinon.stub()
.withArgs(row[column.dataField], row, columnIndex)
.withArgs(row[column.dataField], row, rowIndex, columnIndex)
.returns(customTitle);
column.title = titleCallBack;
wrapper = shallow(
<Cell row={ row } columnIndex={ columnIndex } rowIndex={ 1 } column={ column } />);
<Cell row={ row } columnIndex={ columnIndex } rowIndex={ rowIndex } column={ column } />);
});
it('should render title correctly by custom title function', () => {
@ -224,7 +231,9 @@ describe('Cell', () => {
it('should call custom title function correctly', () => {
expect(titleCallBack.callCount).toBe(1);
expect(titleCallBack.calledWith(row[column.dataField], row, columnIndex)).toBe(true);
expect(
titleCallBack.calledWith(row[column.dataField], row, rowIndex, columnIndex)
).toBe(true);
});
});
});
@ -232,6 +241,7 @@ describe('Cell', () => {
describe('when column.events prop is defined', () => {
let column;
const columnIndex = 1;
const rowIndex = 1;
beforeEach(() => {
column = {
@ -243,7 +253,7 @@ describe('Cell', () => {
};
wrapper = shallow(
<Cell row={ row } columnIndex={ columnIndex } rowIndex={ 1 } column={ column } />);
<Cell row={ row } columnIndex={ columnIndex } rowIndex={ rowIndex } column={ column } />);
});
it('should attachs DOM event successfully', () => {
@ -260,6 +270,7 @@ describe('Cell', () => {
describe('when column.align prop is defined', () => {
let column;
const columnIndex = 1;
const rowIndex = 1;
beforeEach(() => {
column = {
@ -272,7 +283,7 @@ describe('Cell', () => {
beforeEach(() => {
column.align = 'center';
wrapper = shallow(
<Cell row={ row } columnIndex={ columnIndex } rowIndex={ 1 } column={ column } />);
<Cell row={ row } columnIndex={ columnIndex } rowIndex={ rowIndex } column={ column } />);
});
it('should render style.textAlign correctly', () => {
@ -287,11 +298,11 @@ describe('Cell', () => {
beforeEach(() => {
alignCallBack = sinon.stub()
.withArgs(row[column.dataField], row, columnIndex)
.withArgs(row[column.dataField], row, rowIndex, columnIndex)
.returns(customAlign);
column.align = alignCallBack;
wrapper = shallow(
<Cell row={ row } columnIndex={ columnIndex } rowIndex={ 1 } column={ column } />);
<Cell row={ row } columnIndex={ columnIndex } rowIndex={ rowIndex } column={ column } />);
});
it('should render style.textAlign correctly', () => {
@ -301,7 +312,9 @@ describe('Cell', () => {
it('should call custom headerAlign function correctly', () => {
expect(alignCallBack.callCount).toBe(1);
expect(alignCallBack.calledWith(row[column.dataField], row, columnIndex)).toBe(true);
expect(
alignCallBack.calledWith(row[column.dataField], row, rowIndex, columnIndex)
).toBe(true);
});
});
});
@ -309,6 +322,7 @@ describe('Cell', () => {
describe('when column.attrs prop is defined', () => {
let column;
const columnIndex = 1;
const rowIndex = 1;
beforeEach(() => {
column = {
@ -412,11 +426,11 @@ describe('Cell', () => {
beforeEach(() => {
attrsCallBack = sinon.stub()
.withArgs(row[column.dataField], row, columnIndex)
.withArgs(row[column.dataField], row, rowIndex, columnIndex)
.returns(customAttrs);
column.attrs = attrsCallBack;
wrapper = shallow(
<Cell row={ row } columnIndex={ columnIndex } rowIndex={ 1 } column={ column } />);
<Cell row={ row } columnIndex={ columnIndex } rowIndex={ rowIndex } column={ column } />);
});
it('should render style.attrs correctly', () => {
@ -427,7 +441,9 @@ describe('Cell', () => {
it('should call custom attrs function correctly', () => {
expect(attrsCallBack.callCount).toBe(1);
expect(attrsCallBack.calledWith(row[column.dataField], row, columnIndex)).toBe(true);
expect(
attrsCallBack.calledWith(row[column.dataField], row, rowIndex, columnIndex)
).toBe(true);
});
});
});