import * as React from 'react';
import { render } from 'react-dom';
import {
ApplyFilterParameter,
BootstrapTable,
ButtonGroupProps,
CellEdit,
ColumnDescription,
CustomSelectProps,
DeleteButton,
EditableAttrs,
EditValidatorObject,
ExpandColumnComponentProps,
ExpandColumnOptions,
ExportCSVButton,
Filter,
FilterData,
FooterData,
InsertButton,
InsertModalColumnDescription,
InsertModalFooter,
InsertModalHeader,
ModalBodyInterface,
Options,
PaginationPanelProps,
SearchField,
SearchFieldInterface,
SearchFieldProps,
SearchPanelProps,
SelectRow,
ShowSelectedOnlyButton,
SizePerPageDropDown,
SortOrder,
TableHeaderColumn,
ToolBarProps
} from 'react-bootstrap-table';
interface Product {
id: number;
name: string;
price?: number;
quality?: number;
inStockStatus?: number;
sales?: number;
}
const products: Product[] = [{
id: 1,
name: "Item name 1",
price: 100
}, {
id: 2,
name: "Item name 2",
price: 100
}];
type JobType = 'A' | 'B' | 'C' | 'D';
interface Job {
id: number;
status: string;
name: string;
type: JobType;
active: 'Y' | 'N';
}
const jobs = [
{ id: 1, status: '200', name: 'Item name 1', type: 'B', active: 'N' },
{ id: 2, status: '200', name: 'Item name 2', type: 'B', active: 'Y' }
];
const jobTypes = ['A', 'B', 'C', 'D'];
interface ExtendedJob {
id: number;
name: string;
type1: JobType;
type2: JobType;
active: 'Y' | 'N';
datetime: Date;
}
const extendedJobs = [
{ id: 1, name: 'Item name 1', type1: 'A', type2: 'B', active: 'N', datetime: '2001-12-28T14:57:00' },
{ id: 2, name: 'Item name 2', type1: 'A', type2: 'B', active: 'Y', datetime: '2002-12-28T14:57:00' }
];
const inStockStatus = {
1: 'yes',
2: 'no'
};
// It's a data format example.
function priceFormatter(cell: number, row: Product) {
return ' ' + cell;
}
render(
Product ID
Product Name
Product Price
,
document.getElementById("app")
);
const qualityType = {
0: 'good',
1: 'bad',
2: 'unknown'
};
function enumFormatter(cell: any, row: any, enumObject: any, rowIndex: number) {
console.log(`The row index: ${rowIndex}`);
return enumObject[cell];
}
class SelectFilterWithDefaultValue extends React.Component {
render() {
return (
Product ID
Product Name
Product Quality
);
}
}
class TextFilterWithCondition extends React.Component {
render() {
return (
Product ID
Product Name
Product Price
);
}
}
function getCustomFilter(filterHandler: (parameters?: ApplyFilterParameter) => void, customFilterParameters: any) {
return (
);
}
class CustomFilter extends React.Component {
render() {
const filter: Filter = { type: 'CustomFilter', getElement: getCustomFilter, customFilterParameters: { textOK: 'yes', textNOK: 'no' } };
return (
Product ID
Product Name
Product Is In Stock
);
}
}
class RemoteProps extends React.Component {
render() {
const filter: Filter = { type: 'CustomFilter', getElement: getCustomFilter, customFilterParameters: { textOK: 'yes', textNOK: 'no' } };
return (
{
remoteObj.cellEdit = true;
return remoteObj;
}}
options={{
onCellEdit: (row: any, fieldName: string, value: any) => { console.info(row); return value; }
}}
>
Product ID
Product Name
Product Is In Stock
);
}
}
class RemoteBool extends React.Component {
render() {
const filter: Filter = { type: 'CustomFilter', getElement: getCustomFilter, customFilterParameters: { textOK: 'yes', textNOK: 'no' } };
return (
Product ID
Product Name
Product Is In Stock
);
}
}
/**
* See http://allenfang.github.io/react-bootstrap-table/docs.html#tdAttr
*/
const tdAttrExample =
Product ID
Product Name
Product Price
;
/**
* See http://allenfang.github.io/react-bootstrap-table/docs.html#tdStyle
*/
const tdStyleExample =
Product ID
Product Name
Product Price
;
/**
* See http://allenfang.github.io/react-bootstrap-table/docs.html#thStyle
*/
const thStyleExample =
Product ID
Product Name
Product Price
;
/**
* Adopted from https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/column-header-span/column-header-span-complex.js
*/
class ColumnHeaderSpanComplex extends React.Component {
render() {
const options: Options = { exportCSVSeparator: '##' };
return (
ID
Product
name
price
Coupon
In stock
Customer
name
order
);
}
}
/**
* Pagination options
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/pagination/custom-pagination-table.js
*/
class PaginationTable extends React.Component {
sizePerPageListChange = (sizePerPage: number) => {
alert(`sizePerPage: ${sizePerPage}`);
}
onPageChange = (page: number, sizePerPage: number) => {
alert(`page: ${page}, sizePerPage: ${sizePerPage}`);
}
renderShowsTotal = (start: number, to: number, total: number) => {
return (
From {start} to {to}, totals is {total} (its a customize text)
);
}
render() {
const options: Options = {
onPageChange: this.onPageChange,
onSizePerPageList: this.sizePerPageListChange,
page: 2, // which page you want to show as default
sizePerPageList: [{
text: '5', value: 5
}, {
text: '10', value: 10
}, {
text: 'All', value: products.length
}], // you can change the dropdown list for size per page
sizePerPage: 5, // which size per page you want to locate as default
pageStartIndex: 0, // where to start counting the pages
paginationSize: 3, // the pagination bar size.
prePage: 'Prev', // Previous page button text
nextPage: 'Next', // Next page button text
firstPage: 'First', // First page button text
lastPage: 'Last', // Last page button text
prePageTitle: 'Go to previous', // Previous page button title
nextPageTitle: 'Go to next', // Next page button title
firstPageTitle: 'Go to first', // First page button title
lastPageTitle: 'Go to Last', // Last page button title
paginationShowsTotal: this.renderShowsTotal, // Accept bool or function
paginationPosition: 'top', // default is bottom, top and both is all available
keepSizePerPageState: true, // default is false, enable will keep sizePerPage dropdown state(open/clode) when external rerender happened
hideSizePerPage: true, // You can hide the dropdown for sizePerPage
alwaysShowAllBtns: true, // Always show next and previous button
withFirstAndLast: false, // Hide the going to First and Last page button
hidePageListOnlyOnePage: true // Hide the page list if only one page.
};
return (
Product ID
Product Name
Product Price
);
}
}
/**
* Adopted from https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/cell-edit/blur-to-escape-table.js
*/
class BlurToEscapeTable extends React.Component {
render() {
const cellEditProp: CellEdit = {
mode: 'click',
blurToEscape: true
};
return (
Product ID
Product Name
Product Price
);
}
}
/**
* Cell classnames, row saving hooks.
* @see https://githum.com/AllenFang/react-bootstrap-table/blob/master/examples/js/cell-edit/cell-edit-classname.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/cell-edit/cell-edit-hook-table.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/manipulation/insert-row-table.js
*/
class EditCellClassNameTable extends React.Component {
jobNameValidator = (value: string) => {
const response: EditValidatorObject = { isValid: true, notification: { type: 'success', msg: '', title: '' } };
if (!value) {
response.isValid = false;
response.notification.type = 'error';
response.notification.msg = 'Value must be inserted';
response.notification.title = 'Requested Value';
} else if (value.length < 10) {
response.isValid = false;
response.notification.type = 'error';
response.notification.msg = 'Value must have 10+ characters';
response.notification.title = 'Invalid Value';
}
return response;
}
jobStatusValidator = (value: string) => {
const nan = isNaN(parseInt(value, 10));
if (nan) {
return 'Job Status must be a integer!';
}
return true;
}
invalidJobStatus = (cell: string, row: Job) => {
console.log(`${cell} at row id: ${row.id} fails on editing`);
return 'invalid-jobstatus-class';
}
editingJobStatus = (cell: string, row: Job) => {
console.log(`${cell} at row id: ${row.id} in current editing`);
return 'editing-jobstatus-class';
}
onBeforeSaveCellAsync = (row: Job, cellName: K, cellValue: Job[K], done: (ok: boolean) => void): boolean | 1 => {
setTimeout(() => {
done(false); // it's not ok to save :(
}, 3000);
return 1; // return 1 === async operation.
}
onAfterSaveCell(row: Job, cellName: string, cellValue: any) {
alert(`Save cell ${cellName} with value ${cellValue}`);
let rowStr = '';
for (const prop in row) {
rowStr += `${prop}: ${row[prop as keyof Job]}\n`;
}
alert('The whole row :\n' + rowStr);
}
onAfterInsertRow = (row: any) => {
let newRowStr = '';
for (const prop in row) {
newRowStr += `${prop}: ${row[prop]} \n`;
}
alert('The new row is:\n ' + newRowStr);
}
render() {
const cellEditProp: CellEdit = {
mode: 'dbclick',
blurToSave: true,
beforeSaveCell: this.onBeforeSaveCellAsync,
afterSaveCell: this.onAfterSaveCell
};
const options: Options = {
afterInsertRow: this.onAfterInsertRow // A hook for after insert rows
};
return (
Job ID
Job Status
Job Name
Job Type
Active
);
}
}
/**
* Multiple field sorting, filtering, searching and clearing
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/manipulation/filter-table.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/manipulation/multi-search-table.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/manipulation/search-clear-table.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/manipulation/strict-multi-search-table.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/remote/remote-store-search.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/sort/custom-caret-sort-table.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/sort/custom-sort-table.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/sort/sort-style-table.js
*/
class MultiSortAndFiltering extends React.Component {
tableRef: BootstrapTable | null;
idRef: TableHeaderColumn | null;
state = { data: products };
onSortChange = (name: string, order: SortOrder) => {
console.log(`Next sort = ${name}:${order}`);
}
cleanSort = () => { this.tableRef.cleanSort(); };
cleanSelected = () => { this.tableRef.cleanSelected(); };
onFilterChange = (filter: FilterData) => {
Object.keys(filter).forEach((column) => {
console.log(`Filtering ${column}: ${JSON.stringify(filter[column])}`);
});
}
cleanFilters = () => { this.idRef.cleanFiltered(); };
afterColumnFilter = (filterConds: ReadonlyArray, result: ReadonlyArray) => {
console.log('Filter Conditions: ');
filterConds.forEach((filterCond: FilterData) => {
Object.keys(filterCond).forEach((fieldName: string) =>
console.log(`Filter column = ${fieldName}, Filter value = ${filterCond[fieldName]}`));
});
console.log('Result is:');
for (const resultItem of result) {
console.log(`Product: ${resultItem.id}, ${resultItem.name}, ${resultItem.price}`);
}
}
onSearchChange = (searchText: string, colInfos: ReadonlyArray>, multiColumnSearch: boolean) => {
this.setState({ data: products.filter((product) => product.name = searchText) });
}
afterSearch = (searchText: string, result: ReadonlyArray) => {
console.log(`Your search text is ${searchText}`);
console.log('Result is:');
for (const resultItem of result) {
console.log(`Product: ${resultItem.id}, ${resultItem.name}, ${resultItem.price}`);
}
}
getNameCaret = (direction: SortOrder | null, fieldName: string) =>
(direction === 'asc')
? ( up)
: (direction === 'desc')
? ( down)
: ( up/down)
revertSortFunc = (a: Product, b: Product, order: SortOrder) =>
(order === 'desc') ? a.price - b.price : b.price - a.price
customSortStyle = (order: SortOrder, dataField: string) =>
(order === 'desc') ? 'sort-desc' : 'sort-asc'
render() {
const options: Options = {
onSortChange: this.onSortChange,
onFilterChange: this.onFilterChange,
noDataText: 'This is custom text for empty data',
withoutNoDataText: false,
afterColumnFilter: this.afterColumnFilter,
onSearchChange: this.onSearchChange,
afterSearch: this.afterSearch,
clearSearch: true,
sortIndicator: true
};
return (
Product ID
Product Name
=', '<=', '='] }}>Product Price
);
}
}
/**
* Sort with extra data.
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/sort/custom-sort-with-extra-data-table.js
*/
class CustomSortWithExtraDataTable extends React.Component {
sortByName = (a: any, b: any, order: SortOrder, field: string, enumObject: any) => {
if (order === 'desc') {
if (enumObject[a[field]] > enumObject[b[field]]) {
return -1;
} else if (enumObject[a[field]] < enumObject[b[field]]) {
return 1;
}
return 0;
}
if (enumObject[a[field]] < enumObject[b[field]]) {
return -1;
} else if (enumObject[a[field]] > enumObject[b[field]]) {
return 1;
}
return 0;
}
render() {
return (
Product ID
Product Name
Product Quality
);
}
}
/**
* Render custom pagination with provided SizePerPageDropDown component.
*/
class CustomPagination extends React.Component {
renderPagination = (props: PaginationPanelProps) => (
)
render() {
const options: Options = {
paginationPanel: this.renderPagination
};
return (
);
}
}
/**
* Customize the entire insert modal.
* Adapted from https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/custom/insert-modal/custom-insert-modal.js
*/
class CustomModal extends React.Component {
handleSaveBtnClick = (columns: ReadonlyArray>, onSave: (row: any) => void) => {
const newRow: {[field: string]: string} = {};
columns.forEach((column, i) => {
newRow[column.field] = (this.refs[column.field] as HTMLInputElement).value;
}, this);
onSave(newRow);
}
createCustomModal = (
onModalClose: () => void,
onSave: (row: any) => void,
columns: ReadonlyArray>,
validateState: { [dataField: string]: string },
ignoreEditable: boolean
) => (
Custom Insert Modal
{
columns.map((column, i) => {
const {
editable,
format,
field,
name,
hiddenOnInsert
} = column;
if (hiddenOnInsert) {
return null;
}
const error = validateState[field] ?
(
{validateState[field]}) :
null;
return (
{error}
);
})
}
)
render() {
const options: Options = {
insertModal: this.createCustomModal
};
return (
Product ID
Product Name
Product Price
);
}
}
/**
* Custom Insert Modal Fields, both as a custom component and as custom fields.
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/custom/insert-modal/custom-insert-modal-field.js
*/
class SalesRadioField extends React.Component<{editorClass: string, ignoreEditable: boolean}> {
yes: HTMLInputElement | null;
no: HTMLInputElement | null;
getFieldValue = () => {
return this.yes.checked ? 'Yes' : 'No';
}
render() {
return (
);
}
}
class CustomInsertModalFieldTable extends React.Component {
customKeyField = (
column: InsertModalColumnDescription,
attr: EditableAttrs,
editorClass: string,
ignoreEditable: boolean
) => {
const seqId = products.length;
return (
);
}
customNameField = (
column: InsertModalColumnDescription,
attr: EditableAttrs,
editorClass: string,
ignoreEditable: boolean,
defaultValue: any) => {
const fruits = ['banana', 'apple', 'orange', 'tomato', 'strawberries'];
return (
);
}
customSaleField = (
column: InsertModalColumnDescription,
attr: EditableAttrs,
editorClass: string,
ignoreEditable: boolean,
defaultValue: any) => {
return (
);
}
render() {
return (
Product ID
Product Name
On Sales?
Product Price
);
}
}
/**
* Custom modal header, body & footer.
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/custom/insert-modal/default-custom-insert-modal-header.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/custom/insert-modal/custom-insert-modal-body.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/custom/insert-modal/default-custom-insert-modal-footer.js
*/
interface MyCustomBodyProps {
columns: ReadonlyArray>;
validateState: { [dataField: string]: string };
ignoreEditable: boolean;
}
class MyCustomBody extends React.Component implements ModalBodyInterface {
getFieldValue() {
const newRow: Partial = {};
this.props.columns.forEach((column, i) => {
newRow[column.field] = (this.refs[column.field] as HTMLInputElement).value;
}, this);
return newRow as Product;
}
render() {
const { columns, validateState } = this.props;
return (
Custom body
{
this.props.columns.map((column, i) => {
const {
editable,
format,
field,
name,
hiddenOnInsert
} = column;
if (hiddenOnInsert) {
return null;
}
const error = validateState[field] ?
(
{validateState[field]}) :
null;
return (
{error}
);
})
}
);
}
}
class DefaultCustomInsertModalHeaderFooterTable extends React.Component {
createCustomModalFooter = (closeModal: () => void, save: () => void) => {
return (
{}}
beforeSave={(e) => {}}
onModalClose={closeModal}
onSave={save} />
);
}
createCustomModalHeader = (closeModal: () => void, save: () => void) => {
return (
{ }}
onModalClose={closeModal}
hideClose={true} />
);
}
createCustomModalBody = (
columns: ReadonlyArray>,
validateState: { [dataField: string]: string },
ignoreEditable: boolean
) => (
)
render() {
const options: Options = {
insertModalFooter: this.createCustomModalFooter,
insertModalHeader: this.createCustomModalHeader,
insertModalBody: this.createCustomModalBody
};
return (
Product ID
Product Name
Product Price
);
}
}
/**
* Custom Toolbar, including Search Panel & Buttons, and custom delete confirmation.
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/custom/toolbar/custom-button-group.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/custom/toolbar/custom-toolbar-1.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/custom/search/default-custom-search-field.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/custom/search/custom-search-panel-1.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/custom/search/fully-custom-search-field.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/custom/insert-button/default-custom-insert-button.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/custom/delete-button/default-custom-delete-button.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/custom/csv-button/default-custom-csv-button.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/manipulation/del-row-custom-confirm.js
*/
class MySearchField extends React.Component implements SearchFieldInterface {
field: SearchField | null;
getValue() {
return this.field.getValue();
}
setValue(search: string) {
this.field.setValue(search);
}
render() {
const { ...rest} = this.props;
return (
{ this.field = node; }}
/>
);
}
}
class CustomButtonGroup extends React.Component {
createInsertButton = (onClick: (e: React.MouseEvent<{}>) => void) => (
)
createDeleteButton = (onClick: (e: React.MouseEvent<{}>) => void) => (
)
createExportCSVButton = (onClick: (e: React.MouseEvent<{}>) => void) => (
)
createShowSelectedOnlyButton = (onClick: (e: React.MouseEvent<{}>) => void, showSelected: boolean) => (
)
createCustomButtonGroup = (props: ButtonGroupProps) => (
{props.showSelectedOnlyBtn}
{props.exportCSVBtn}
{props.insertBtn}
{props.deleteBtn}
)
createCustomSearchField = (props: SearchFieldProps) => (
)
createCustomClearSearch = (onClick: (e: React.MouseEvent<{}>) => void) => (
)
createCustomSearchPanel = (props: SearchPanelProps) => (
{props.clearBtn}
{props.searchField}
)
createCustomToolBar = (props: ToolBarProps) => {
return (
{props.components.btnGroup}
{props.components.searchPanel}
);
}
customConfirm = (next: () => void, dropRowKeys: ReadonlyArray) => {
const dropRowKeysStr = dropRowKeys.join(',');
if (confirm(`(It's a custom confirm)Are you sure you want to delete ${dropRowKeysStr}?`)) {
next();
}
}
render() {
const selectRow: SelectRow = {
mode: 'checkbox',
showOnlySelected: true
};
const options: Options = {
insertBtn: this.createInsertButton,
deleteBtn: this.createDeleteButton,
exportCSVBtn: this.createExportCSVButton,
showSelectedOnlyBtn: this.createShowSelectedOnlyButton,
btnGroup: this.createCustomButtonGroup,
clearSearch: true,
clearSearchBtn: this.createCustomClearSearch,
searchField: this.createCustomSearchField,
searchPanel: this.createCustomSearchPanel,
toolBar: this.createCustomToolBar,
searchDelayTime: 3000,
handleConfirmDeleteRow: this.customConfirm
};
return (
Product ID
Product Name
Product Price
);
}
}
/**
* Expanding Rows & Selection
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/expandRow/expand-row-by-column.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/expandRow/expand-row-with-selection.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/expandRow/custom-expand-indicator.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/expandRow/custom-expand-class.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/expandRow/auto-collapse.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/expandRow/manage-expanding.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/selection/all-select.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/selection/custom-multi-select-table.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/selection/default-select-table.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/selection/select-bgcolor-dynamic-table.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/selection/select-filter-table.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/selection/select-hook-table.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/selection/select-row-class-table.js
*/
class ExpandRowExample extends React.Component<{}, {expanding: number[]}> {
isExpandableRow = (row: any) => row.id === 2;
expandComponent = (row: any) => (
You expanded the row.
)
expandColumnComponent = ({ isExpandableRow, isExpanded }: ExpandColumnComponentProps) => {
const content = isExpandableRow
? (isExpanded ? '(-)' : '(+)')
: ' ';
return (
{content}
);
}
handleExpand = (rowKey: number, isExpand: boolean) => {
if (isExpand) {
this.setState({ expanding: [...this.state.expanding] });
} else {
this.setState({ expanding: [...this.state.expanding.filter(id => id !== rowKey)] });
}
}
onSelectAll = (isSelected: boolean) => (isSelected) ? products.map(row => row.id) : [];
onSelect = (row: Product, isSelected: boolean, e: React.MouseEvent, rowIndex: number) => {
const rowStr = `id: "${row.id}", name: ${row.name}, price: ${row.price}`;
console.log(e);
alert(`Selected: ${isSelected}, rowIndex: ${rowIndex}, row: ${rowStr}`);
}
customMultiSelect = (props: CustomSelectProps) => (
)
selectedRowClass = (row: Product, isSelect: boolean) =>
(isSelect)
? ((row.id >= 3) ? 'bigger-than-three-select-row' : 'less-than-three-select-row')
: ''
render() {
const options: Options = {
expandRowBgColor: 'rgb(242, 255, 163)',
expandBy: 'column',
onlyOneExpanding: true,
expanding: this.state.expanding,
onExpand: this.handleExpand,
expandParentClass: 'custom-expand-parent',
expandBodyClass: (row, rowIndex, isExpanding) => {
return (!isExpanding)
? 'current-is-hidden'
: (rowIndex > 1)
? 'custom-expand-body-1'
: 'custom-expand-body-0';
}
};
const selectRow: SelectRow = {
mode: 'checkbox',
bgColor: (row: Product, isSelect: boolean) =>
(isSelect)
? ((row.id < 2) ? 'blue' : ((row.id < 4) ? 'red' : 'yellow'))
: null,
clickToSelect: true, // click to select, default is false
clickToExpand: true, // click to expand row, default is false
onSelect: this.onSelect,
onSelectAll: this.onSelectAll,
customComponent: this.customMultiSelect,
hideSelectColumn: false,
selected: [0, 2],
showOnlySelected: true,
onlyUnselectVisible: true,
className: this.selectedRowClass,
columnWidth: '60px',
unselectable: [1, 3]
};
const expandColumnOptions: ExpandColumnOptions = {
expandColumnVisible: true,
expandColumnBeforeSelectColumn: false,
expandColumnComponent: this.expandColumnComponent,
columnWidth: 50
};
return (
Product ID
Product Name
Product Price
);
}
}
/**
* Table mouse enter/leave events
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/others/mouse-event-table.js
*/
class MouseEventTable extends React.Component {
render() {
const options: Options = {
onMouseLeave: () => { console.log('mouse left table'); },
onMouseEnter: () => { console.log('mouse entered table'); },
onRowMouseOut: (row: any, e: React.MouseEvent<{}>) => {
console.log(e);
console.log('mouse left row ' + row.id);
},
onRowMouseOver: (row: any, e: React.MouseEvent<{}>) => {
console.log(e);
console.log('mouse entered row ' + row.id);
}
};
return (
Product ID
Product Name
Product Price
);
}
}
/**
* Hidden on insert modal with async row error callback & read-only field
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/advance/hide-on-insert-table.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/advance/insert-error-handle-table.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/advance/validator-table-read-only.js
*/
class HideOnInsertTable extends React.Component {
handleAddRowWithASyncError = (row: any, colInfo: ReadonlyArray>, errorCallback: (msg: string) => void) => {
setTimeout(() => {
errorCallback('Sorry, There\'s some error happend');
}, 5000);
return false;
}
render() {
const options: Options = {
onAddRow: this.handleAddRowWithASyncError
};
return (
Job ID
Job Name
Job Type
Active
);
}
}
/**
* Edit field types
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/advance/edit-type-table.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/advance/insert-default-value-table.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/advance/insert-error-handle-table.js
*/
class EditTypeTable extends React.Component {
formatType = (cell: string) => `TYPE_${cell}`;
jobTypes = (row: ExtendedJob) => (row.id > 2) ? ['A', 'B'] : ['B', 'C', 'D', 'E'];
handleAddRowWithSyncError = () => {
return 'Sorry, There\'s some error happend';
}
render() {
const attrs = {
rows: 10,
onKeyDown: () => { console.log('keydown event trigger'); }
};
const cellEditProp: CellEdit = {
mode: 'click',
blurToSave: true
};
const options: Options = {
onAddRow: this.handleAddRowWithSyncError
};
return (
Job ID
Job Name
Job Type1
Job Type2
Active
Date Time
);
}
}
/**
* React component format for column.
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/column-format/react-column-format-table.js
*/
class ActiveFormatter extends React.Component<{ active: boolean }> {
render() {
return (
);
}
}
export default class ReactColumnFormatTable extends React.Component {
activeFormatter = (cell: boolean, row: ExtendedJob) => ();
render() {
return (
Job ID
Job Name
Active
);
}
}
/**
* Format Extra Data
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/column-format/extra-data-column-format-table.js
*/
class ExtraDataColumnFormatTable extends React.Component {
enumFormatter = (cell: number, row: Product, enumObject: {[id: number]: string}) => enumObject[cell];
render() {
return (
Product ID
Product Name
Product Quality
Product Stock Status
);
}
}
/**
* Column titles
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/column/column-title-table.js
*/
class ColumnAlignTable extends React.Component {
customTitle = (cell: number, row: any, rowIndex: number, colIndex: number) => `${row.name} for ${cell}`;
render() {
const options: Options = {
exportCSVText: 'my_export',
insertText: 'my_insert',
deleteText: 'my_delete',
saveText: 'my_save',
closeText: 'my_close'
};
return (
Product ID
Product Name
Product Price
);
}
}
/**
* Table Footer
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/footer/footer-table.js
*/
class FooterTable extends React.Component {
render() {
const footerData: FooterData[][] = [
[
{ label: 'Total', columnIndex: 0 },
{
label: 'Total value',
columnIndex: 2,
align: 'right',
formatter: (tableData: Array<{price: number}>) => {
let label = 0;
for (let i = 0, tableDataLen = tableData.length; i < tableDataLen; i++) {
label += tableData[i].price;
}
return (
{label}
);
}
}
]
];
return (
Product ID
Product Name
Product Price
);
}
}
/**
* Keyboard navigation
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/keyboard-nav/custom-style-nav-table.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/keyboard-nav/custom-style-nav-with-cell-edit-table.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/keyboard-nav/disable-click-to-nav-table.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/keyboard-nav/enter-to-edit-with-nav-table.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/keyboard-nav/nav-with-expand-table.js
*/
class CustomStyleNavTable extends React.Component {
customStyle = (cell: any, row: any) => {
return {
backgroundColor: 'red'
};
}
render() {
const cellEdit: CellEdit = {
mode: 'click',
blurToSave: true
};
const keyBoardNav = {
customStyleOnEditCell: this.customStyle,
customStyle: this.customStyle,
clickToNav: false,
enterToEdit: true,
enterToExpand: false
};
return (
Product ID
Product Name
Product Price
);
}
}
/**
* Table body styles
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/style/inline-style-table.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/style/table-class-table.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/style/td-class-string-table.js
*/
class TrClassStringTable extends React.Component {
render() {
return (
Product ID
Product Name
Product Price
);
}
}
/**
* Table styles set by functions.
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/style/td-class-function-table.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/style/tr-class-function-table.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/style/tr-style-table.js
*/
class TrClassFunctionTable extends React.Component {
headerColumnClassNameFormat = () => 'th-string-example';
columnClassNameFormat = (fieldValue: string | number, row: Product, rowIdx: number, colIdx: number) =>
rowIdx % 2 === 0 ? 'td-column-function-even-example' : 'td-column-function-odd-example'
trClassFormat = (rowData: ReadonlyArray, rIndex: number) =>
rIndex % 3 === 0 ? 'tr-function-example' : ''
trStyle = (row: Product, rowIndex: number) => ({ backgroundColor: '#FFFAFA' });
render() {
return (
Product ID
Product Name
Product Price
);
}
}
/**
* Filter types.
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/column-filter/all-filters.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/column-filter/date-filter-programmatically.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/column-filter/number-filter-programmatically.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/column-filter/regex-filter-programmatically.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/column-filter/select-filter-programmatically.js
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/column-filter/text-filter-programmatically.js
*/
class AllFilters extends React.Component {
name1: TableHeaderColumn | null;
name2: TableHeaderColumn | null;
quality: TableHeaderColumn | null;
price: TableHeaderColumn | null;
satisfaction: TableHeaderColumn | null;
inStockDate: TableHeaderColumn | null;
handlerClickCleanFiltered = () => {
this.name1.cleanFiltered();
this.name2.cleanFiltered();
this.quality.cleanFiltered();
this.price.cleanFiltered();
this.satisfaction.cleanFiltered();
this.inStockDate.cleanFiltered();
}
applyFiltersProgramatically = () => {
this.name1.applyFilter('Item 1');
this.name2.applyFilter('[name]');
this.quality.applyFilter(1);
this.price.applyFilter({
number: 10.5,
comparator: '<='
});
this.satisfaction.applyFilter({
number: 2,
comparator: '>'
});
this.inStockDate.applyFilter({
date: new Date(2015, 0, 1),
comparator: '='
});
}
dateFormatter = (cell: Date, row: any) => {
if (typeof cell !== 'object') {
cell = new Date(cell);
}
return `${('0' + cell.getDate()).slice(-2)}/${('0' + (cell.getMonth() + 1)).slice(-2)}/${cell.getFullYear()}`;
}
render() {
const satisfaction = [0, 1, 2, 3, 4, 5];
return (
Product ID
clear filters
{ this.name1 = node; }} dataField='name' filter={{ type: 'TextFilter', placeholder: 'Please enter a value' }}>Product Name
{ this.name2 = node; }} dataField='name' filter={{ type: 'RegexFilter', placeholder: 'Please enter a regex' }}>Product Name
< TableHeaderColumn ref={(node) => { this.quality = node; }} dataField='quality' filter={{ type: 'SelectFilter', options: qualityType }}
dataFormat={enumFormatter} formatExtraData={qualityType}>Product Quality
{ this.price = node; }} dataField='price' filter={{ type: 'NumberFilter', delay: 1000 }}>Product Price
< TableHeaderColumn ref= {(node) => { this.satisfaction = node; }} dataField='satisfaction' filter={{ type: 'NumberFilter', options: satisfaction }}>Buyer Satisfaction
< TableHeaderColumn ref= {(node) => { this.inStockDate = node; }} dataField='inStockDate' filter={{ type: 'DateFilter' }} dataFormat={this.dateFormatter}>In Stock From
);
}
}
/**
* Set Array filter programatically
* @see https://github.com/AllenFang/react-bootstrap-table/blob/master/examples/js/column-filter/array-filter-programmatically.js
*/
class ProgrammaticallyArrayFilter extends React.Component {
table: BootstrapTable | null;
/* Filtering passing an array of values */
handleBtnClick = () => {
this.table.handleFilterData({
name: { type: 'ArrayFilter', value: ['Item name 3', 'Item name 4'] },
price: { type: 'ArrayFilter', value: [2100, 2104] }
});
}
render() {
return (
{ this.table = node; }} data={products}>
Product ID
Product Name
Product Price
);
}
}