how add react-loading in react bootstrap table - reactjs

i'm new in reactjs and react bootstrap table. i want add react-loading in my react component before data show. because data show so long. but doesn't work.
this is my code
import React, { Component } from 'react';
import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table';
import PageHeader from 'react-bootstrap/lib/PageHeader';
import database from './database';
import root from 'window-or-global';
import Loading from 'react-loading';
class User extends Component {
constructor(props) {
super(props);
this.state = {
text:'',
products: []
};
this.userRef = database.ref('users');
}
componentDidMount() {
this.userRef.on('value', this.gotData, this.errData);
}
gotData = (data) => {
let newProducts = []
const userdata = data.val();
const keys = Object.keys(userdata);
for (let i = 0; i < keys.length; i++) {
const k = keys[i];
newProducts.push({
name: userdata[k].nama, address: userdata[k].address, email: userdata[k].email
});
}
this.setState({products : newProducts});
}
errData = (err) => {
console.log(err);
}
handleClick = (rowKey) => {
alert(this.refs.table.getPageByRowKey(rowKey));
}
render() {
return (
<div>
<Loading type ='spinning-bubbles' color='#e3e3e3' />
<div className="col-lg-12">
<PageHeader>Members</PageHeader>
</div>
<BootstrapTable
ref='table'
data={ this.state.products }
pagination={ true }
search={ true }>
<TableHeaderColumn dataField='name' isKey={true} dataSort={true}>Name</TableHeaderColumn>
<TableHeaderColumn dataField='address' dataSort={true}>Address</TableHeaderColumn>
<TableHeaderColumn dataField='email'>Email</TableHeaderColumn>
</BootstrapTable>
</div>
);
}
}
export default User;
Best wishes! Wish for replying.

For that, first maintain a bool in state variable that will track whether data fetched or not, initial value of that bool will be false.
constructor(){
super();
this.state = {
isDataFetched: false,
}
}
Now there a property of React-Bootstrap-Table, option that is used to set the default values and customise the noDataText, you can use that, like this:
<BootstrapTable
....
options={tableOtions}>
</BootstrapTable>
Now define this tableOtions object and edit the noDataText property, like this:
let tableOtions = {
noDataText: this._setTableOption(),
};
If data is fetched successfully then return some text, that will be displayed if data will be empty, otherwise return a loader:
_setTableOption(){
if(this.state.isDataFetched){
return "No expenses found";
}else{
return(
<RefreshIndicator size={40} left={0} top={0} status="loading" style={{position: 'relative', margin: '0px auto'}}/>
);
}
}
Note: I used a Material-UI RefreshIndicator, you can replace that by any other loader also.
Reference of option object in React Bootstrap Table: http://allenfang.github.io/react-bootstrap-table/docs.html#noDataText
Update: Use this code, and replace the RefreshIndicator by Loader that you want to show:
import React, { Component } from 'react';
import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table';
import PageHeader from 'react-bootstrap/lib/PageHeader';
import database from './database';
import root from 'window-or-global';
import Loading from 'react-loading';
class User extends Component {
constructor(props) {
super(props);
this.state = {
text:'',
products: [],
isDataFetched: false,
};
this.userRef = database.ref('users');
}
componentDidMount() {
this.userRef.on('value', this.gotData, this.errData);
}
gotData = (data) => {
let newProducts = []
const userdata = data.val();
const keys = Object.keys(userdata);
for (let i = 0; i < keys.length; i++) {
const k = keys[i];
newProducts.push({
name: userdata[k].nama, address: userdata[k].address, email: userdata[k].email
});
}
this.setState({products : newProducts, isDataFetched: true});
}
errData = (err) => {
console.log(err);
}
handleClick = (rowKey) => {
alert(this.refs.table.getPageByRowKey(rowKey));
}
_setTableOption(){
if(this.state.isDataFetched){
return "No expenses found";
}else{
return(
<RefreshIndicator size={40} left={0} top={0} status="loading" style={{position: 'relative', margin: '0px auto'}}/>
);
}
}
render() {
let tableOtions = {
noDataText: this._setTableOption(),
};
return (
<div>
<Loading type ='spinning-bubbles' color='#e3e3e3' />
<div className="col-lg-12">
<PageHeader>Members</PageHeader>
</div>
<BootstrapTable
ref='table'
data={ this.state.products }
pagination={ true }
search={ true }
options={tableOtions}>
>
<TableHeaderColumn dataField='name' isKey={true} dataSort={true}>Name</TableHeaderColumn>
<TableHeaderColumn dataField='address' dataSort={true}>Address</TableHeaderColumn>
<TableHeaderColumn dataField='email'>Email</TableHeaderColumn>
</BootstrapTable>
</div>
);
}
}
export default User;

Related

this.state.account and this.state.followers are not updated onMouseOver?

When Bootstrap table rows are hovered the twitter_account in Twitter state is updated.But when passed as props for TwitterChart class It is not updated.
const twitterData = [
{
account: "marwilliamson",
followers: 2610335,
},
{
account: "BernieSanders",
followers: 9254423,
},
{
account: "Hickenlooper",
followers: 144816,
}
]
export {twitterData};
/////////
import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table';
import {twitterData} from './twitter_data'
export const Twitter = () => {
const data = useMemo(() => twitterData, [])
const [twitter_account,settwitter_account] = useState('');
const [twitter_followers,settwitter_followers] = useState(0);
function onRowMouseOver(row){
settwitter_account(row.account);
settwitter_followers(row.followers);
}
const options = {
onRowMouseOver: onRowMouseOver,
};
return (
<div>
<div className="twitter-followers">
<div className="followers-header">
<BootstrapTable data={ data } options={options}>
<TableHeaderColumn dataField='account' dataFormat={CellFormatter} isKey={true} dataSort={ true } dataAlign='left' width='120' headerAlign='left' className="header">ACCOUNT</TableHeaderColumn>
<TableHeaderColumn dataField='followers' dataSort={ true } width='120' dataAlign='center' headerAlign='left' className="header">FOLLOWERS</TableHeaderColumn>
</BootstrapTable>
</div>
</div>
<TwitterBarChart account={twitter_account} followers={twitter_followers}/>
</div>
)
}
/////////
class TwitterBarChart extends React.Component {
constructor(props){
super(props);
this.state = {
data : twitterData,
account:props.account,
followers:props.followers,
}
}
render() {
console.log(this.state.account);
return(
<div className="barchart-msg-container">
<p className="barchart-message"><strong>{this.state.account}</strong> has <span>{this.state.followers}</span> followers on Twitter</p>
</div>
)
}
twitter_account , twitter_followers are not getting updated on props.
console.log(this.state.account) //account value is not updating onMouseOver.
Finally after many references I got the answer.
should use componentWillRecieveProps(newprops){}
Thanks for contributing

React Bootstrap remote row insert

I am attempting insert a row into a table once it has been successfully stored in the database.
I am getting the following error:
Warning: Each child in a list should have a unique "key" prop.
I have added the "rowKey="id" parameter to the table component but I am still facing the same issue.
import React, { Component} from "react";
import editImage from '../../src/images/edit.png';
import './Payrolls.css';
import {BootstrapTable,TableHeaderColumn, RemoteInsertRow} from 'react-bootstrap-table';
import '../../node_modules/react-bootstrap-table/css/react-bootstrap-table.css'
import { Link } from 'react-router-dom'
import axios from "axios";
var currentComponent = null;
class Payrolls extends Component {
componentDidMount() {
this.getData();
}
constructor(props, context) {
super(props, context);
this.tableData = [Array]
this.state = {
tableData: [],
selected: []
};
this.getData = this.getData.bind(this);
this.onAddRow = this.onAddRow.bind(this);
}
getData = () => {
var self=this;
axios.get('http://******.co.uk/payrolls.php', {
})
.then(function (response) {
self.state.tableData.push(response.data)
self.setState({tableData: response.data});
})
.catch(function (error) {
self.props.history.push('/login');
console.log(error);
});
}
dateValidator(value, row) {
if(value === ""){
return 'You must select a date!';
}else{
return true;
}
}
onAddRow = (row) => {
// Save to server and on success:
this.state.tableData.push(row)
this.setState({
tableData: this.tableData
});
}
render() {
const { tableData } = this.state;
const selectRowProp = {
mode: 'checkbox'
};
function editButton(cell, row){
if(row.status !== "Complete") {
return (<img alt="logo" className="imageIcon" src={editImage}/>);
}
}
return (
<div className="grid-item-dashboard-title">
Active Payrolls
</div>
<div className="payroll-table">
<BootstrapTable data={ this.state.tableData } remote={ true } insertRow={ true } pagination={ true } deleteRow={ true } selectRow={ selectRowProp } options={ { onAddRow: this.onAddRow } } striped hover rowKey="id">
<TableHeaderColumn dataField='id' autoValue ={true} isKey={ true } hidden hiddenOnInsert>Payroll ID</TableHeaderColumn>
<TableHeaderColumn dataAlign="center" dataField='creation_date' hiddenOnInsert>Creation Date</TableHeaderColumn>
<TableHeaderColumn dataAlign="center" dataField='created_by' hiddenOnInsert>Created By</TableHeaderColumn>
<TableHeaderColumn dataAlign="center" dataField='week_ending' editable={ { type: 'date' ,validator: this.dateValidator} } >Week Ending</TableHeaderColumn>
<TableHeaderColumn dataAlign="center" dataField='status' hiddenOnInsert>Status</TableHeaderColumn>
<TableHeaderColumn dataAlign="center" dataFormat={editButton}></TableHeaderColumn>
</BootstrapTable>
</div>
</div>
);
}
}
export default Payrolls;

React and table does not sync

I'm using react antd table with pagination,sort & etc. it'll fetch data when component is loaded. when te user clicks on pagination it should call Api and get new data accordingly. it's getting bada but the table won't update with new data.
I'm new with react. please help me with this,
import PropTypes from 'prop-types';
import React, { Component } from "react";
import { connect } from "react-redux";
import { bindActionCreators } from 'redux';
import { Row, Col } from "antd";
import clone from "clone";
import Button from "../../components/uielements/button";
import PageHeader from "../../components/utility/pageHeader";
import Box from "../../components/utility/box";
import LayoutWrapper from "../../components/utility/layoutWrapper";
import SignUpForm from "../../components/vendorSignup";
import basicStyle from "../../settings/basicStyle";
import actions from "../../redux/vendorSignUp/actions";
import { createColumns } from "./config";
import { ButtonWrapper } from "../../components/card/cardModal.style";
import SimpleTable from "./antTables/tableViews/sortView";
import ContentHolder from '../../components/utility/contentHolder';
import Spin from '../Feedback/Spin/spin.style';
const { addVendor, getVendors } = actions;
class Cards extends Component {
static propTypes = {
dispatch: PropTypes.func
};
constructor(props) {
super(props);
this.addColumn = this.addColumn.bind(this);
this.editColumn = this.editColumn.bind(this);
this.handleCancel = this.handleCancel.bind(this);
this.submitCard = this.submitCard.bind(this);
this.updateCard = this.updateCard.bind(this);
this.tableInfo = {
title: "Sort Table",
value: "sortView",
columns: []
};
this.tableInfo.columns = createColumns(this.editColumn);
this.state = {
editView: false,
selectedCard: null,
modalType: ""
};
}
componentWillMount() {
const { getVendors } = this.props.actions;
}
render() {
const style = {
textAlign: 'center',
background: '#f1f3f6',
padding: '30px 50px'
};
const { rowStyle, colStyle, gutter } = basicStyle;
const { editView, selectedCard, modalType } = this.state;
const vendorSignUp = clone(this.props.vendorSignUp);
if (vendorSignUp.length == 0) {
return (<LayoutWrapper>
<PageHeader>Vendors</PageHeader>
<ContentHolder>
<div style={style}>
<Spin spinning={vendorSignUp.length === 0} />
</div>
</ContentHolder>
</LayoutWrapper>);
}
return (
<LayoutWrapper>
<PageHeader>Vendors</PageHeader>
<Row style={rowStyle} gutter={gutter} justify="start">
<Col md={24} sm={24} xs={24} style={colStyle}>
<Box>
<ButtonWrapper className="isoButtonWrapper">
<Button type="primary" className="" onClick={this.addColumn}>
Add New Vendor
</Button>
</ButtonWrapper>
<SimpleTable columns={this.tableInfo.columns} dataSource={vendorSignUp} loading={this.loading} onChange={this.onChange} />
{selectedCard ? (
<SignUpForm
saveFormRef={this.saveFormRef}
editView={editView}
modalType={modalType}
onCancel={this.handleCancel}
onCreate={this.submitCard}
onOk={this.submitCard}
wrappedComponentRef={this.saveFormRef}
/>
) : ("")}
</Box>
</Col>
</Row>
</LayoutWrapper>
);
}
}
function mapStateToProps(state) {
return {
...state.vendorSignUp.toJS()
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators({
getVendors, addVendor
}, dispatch)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Cards);
Here is my table view;
import React, { Component } from 'react';
import { connect } from 'react-redux';
import TableWrapper from '../antTable.style';
import actions from "../../../../redux/vendorSignUp/actions";
const { getVendors } = actions;
class SignIn extends Component {
constructor(props) {
super(props);
this.onChange = this.onChange.bind(this);
this.state = {
dataList: this.props.dataSource || this.props.dataList.getAll()
};
this.columns = this.props.columns || this.props.tableInfo.columns;
}
onChange(pagination, filters, sorter) {
if (sorter.order) {
if (sorter.order == "ascend") {
const { getVendors } = this.props;
this.setState({
loading: true,
});
getVendors('3-5');
}
else {
this.props.dataSource.sort(function (a, b) {
var x = a[sorter.field].toLowerCase();
var y = b[sorter.field].toLowerCase();
if (y < x) { return -1; }
if (y > x) { return 1; }
return 0;
});
}
}
}
render() {
return (
<TableWrapper
columns={this.columns}
onChange={this.onChange}
dataSource={this.state.dataList}
className="isoSortingTable"
pagination={{ pageSize: 10 }}
loading={this.state.loading}
/>
);
}
}
function mapStateToProps(state) {
return {
...state
};
}
export default connect(mapStateToProps,
{ getVendors }
)(SignIn);
problem was in the constructor.it's will be executed only one time. therefore this.state.datalist will be the same. that's why it did not work.

error display data from firebase to react bootstrap table

I want to display data from my firebase database to react bootstrap table. But, I can't show live data if after refresh.
This is my react component code
import React, { Component } from 'react';
import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table';
import PageHeader from 'react-bootstrap/lib/PageHeader';
import database from './database';
const ref = database.ref('users');
ref.on('value', gotData, errData);
const products = [];
function gotData(data) {
const userdata = data.val();
const keys = Object.keys(userdata);
for (let i = 0; i < keys.length; i++) {
const k = keys[i];
products.push({
name: userdata[k].nama, address: userdata[k].address, email: userdata[k].email
});
}
}
function errData(err) {
console.log(err);
}
class Member extends Component {
constructor(props) {
super(props);
this.state = {
text:''
};
}
handleClick = (rowKey) => {
alert(this.refs.table.getPageByRowKey(rowKey));
}
render(){
return (
<div>
<div className="col-lg-12">
<PageHeader>Members</PageHeader>
</div>
<BootstrapTable
ref='table'
data={ products }
pagination={ true }
search={ true }>
<TableHeaderColumn dataField='name' isKey={true} dataSort={true}>Name</TableHeaderColumn>
<TableHeaderColumn dataField='address' dataSort={true}>Address</TableHeaderColumn>
<TableHeaderColumn dataField='email'>Email</TableHeaderColumn>
</BootstrapTable>
</div>
);
}
}
export default Member;
and this is my initialize database code
import firebase from 'firebase';
const config = {
apiKey: '......',
authDomain: '......',
databaseURL: '....',
projectId: '....',
storageBucket: '....',
messagingSenderId: '....'
};
firebase.initializeApp(config);
const database = firebase.database();
export default database;
Help me in this, Thanks.
You have to tell the component to re-render, when there is a change in data. I don't think the functions related to firebase should live outside the component. Instead they should live within the component. You should do something like below. Hope it helps
import React, { Component } from 'react';
import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table';
import PageHeader from 'react-bootstrap/lib/PageHeader';
import database from './database';
class Member extends Component {
constructor(props) {
super(props);
this.state = {
text:'',
products: []
};
this.userRef = database.ref('users');
}
componentDidMount() {
this.userRef.on('value', this.gotData, this.errData);
}
gotData = (data) => {
let newProducts = []
const userdata = data.val();
const keys = Object.keys(userdata);
for (let i = 0; i < keys.length; i++) {
const k = keys[i];
newProducts.push({
name: userdata[k].nama, address: userdata[k].address, email: userdata[k].email
});
}
this.setState({products: newProducts});
}
errData = (err) => {
console.log(err);
}
handleClick = (rowKey) => {
alert(this.refs.table.getPageByRowKey(rowKey));
}
render(){
return (
<div>
<div className="col-lg-12">
<PageHeader>Members</PageHeader>
</div>
<BootstrapTable
ref='table'
data={ this.state.products }
pagination={ true }
search={ true }>
<TableHeaderColumn dataField='name' isKey={true} dataSort={true}>Name</TableHeaderColumn>
<TableHeaderColumn dataField='address' dataSort={true}>Address</TableHeaderColumn>
<TableHeaderColumn dataField='email'>Email</TableHeaderColumn>
</BootstrapTable>
</div>
);
}
}
export default Member;
All subscription related code goes into componentDidMount and you have to unsubscribe when the component will unmount.

react-virtualized getting error - TypeError: list.get is not a function

Getting error - TypeError: list.get is not a function
My Parent component :
import TableExample from './TableExample';
// Map Redux state to component props
function mapStateToProps(state) {
return {
dirList: state.filelistReducer.dirList,
showFileViewer: state.sidenavReducer.showFileViewer,
}
}
// Map Redux actions to component props
function mapDispatchToProps(dispatch) {
return {
onDirClick: (path) => { dispatch(actions.fetchFileListAction(path, dispatch)); },
};
}
/**
*
*
* #class FileViewerComponent
* #extends {Component}
*/
class FileListViewComponent extends Component {
constructor(props) {
super(props);
this.state = { width: 0 }
}
render() {
return (
<div>
<div className="col-md-10">
<div className="contentviewdivider" style={{ width: (this.state.width) + 'px' }}></div>
<div className="mainContainer" style={{ width: (this.state.width) + 'px' }}>
<div className="tilerow">
{this.renderList()}
</div>
</div>
</div>
</div>
);
}
renderList() {
return (
<div>
<div className={this.props.showFileViewer}>
<div className='row'>
<TableExample filelist={this.props.dirList} />
</div>
</div>
</div>
);
}
}
export default connect(mapStateToProps, mapDispatchToProps)(FileListViewComponent);
Now in TableExample.jsx
/** #flow */
import Immutable from 'immutable';
import { List } from 'immutable';
import React, { PropTypes, PureComponent } from 'react';
import ReactDom from 'react-dom';
import { ContentBox, ContentBoxHeader, ContentBoxParagraph } from '../demo/ContentBox'
import { LabeledInput, InputRow } from '../demo/LabeledInput'
import {AutoSizer,Column, Table, SortDirection, SortIndicator} from 'react-virtualized'
import styles from '../../../styles/css/components/tableexample.css'
//import { generateRandomList } from './utils'
export default class TableExample extends PureComponent {
// static contextTypes = {
// list: PropTypes.instanceOf(Immutable.List).isRequired
// };
constructor (props) {
super(props)
this.state = {
disableHeader: false,
headerHeight: 30,
height: 270,
hideIndexRow: false,
overscanRowCount: 10,
rowHeight: 40,
rowCount: 1000,
scrollToIndex: undefined,
sortBy: 'index',
sortDirection: SortDirection.ASC,
useDynamicRowHeight: false
}
this._getRowHeight = this._getRowHeight.bind(this)
this._headerRenderer = this._headerRenderer.bind(this)
this._noRowsRenderer = this._noRowsRenderer.bind(this)
this._onRowCountChange = this._onRowCountChange.bind(this)
this._onScrollToRowChange = this._onScrollToRowChange.bind(this)
this._rowClassName = this._rowClassName.bind(this)
this._sort = this._sort.bind(this)
}
render () {
const {
disableHeader,
headerHeight,
height,
hideIndexRow,
overscanRowCount,
rowHeight,
rowCount,
scrollToIndex,
sortBy,
sortDirection,
useDynamicRowHeight
} = this.state
console.log('render of tableexample');
console.log(this.props);
const list = this.props.filelist;
const sortedList = this._isSortEnabled()
? list
.sortBy(item => item[sortBy])
.update(list =>
sortDirection === SortDirection.DESC
? list.reverse()
: list
)
: list
const rowGetter = ({ index }) => this._getDatum(sortedList, index)
return (
<ContentBox>
<div className="table table-striped">
<AutoSizer disableHeight>
{({ width }) => (
<Table
ref='Table'
disableHeader={disableHeader}
headerClassName={styles.headerColumn}
headerHeight={headerHeight}
height={height}
noRowsRenderer={this._noRowsRenderer}
overscanRowCount={overscanRowCount}
rowClassName={this._rowClassName}
rowHeight={useDynamicRowHeight ? this._getRowHeight : rowHeight}
rowGetter={rowGetter}
rowCount={rowCount}
scrollToIndex={scrollToIndex}
sort={this._sort}
sortBy={sortBy}
sortDirection={sortDirection}
width={width}
>
{!hideIndexRow &&
<Column
label='Index'
cellDataGetter={
({ columnData, dataKey, rowData }) => rowData.index
}
dataKey='index'
disableSort={!this._isSortEnabled()}
width={60}
/>
}
<Column
dataKey='name'
disableSort={!this._isSortEnabled()}
headerRenderer={this._headerRenderer}
width={90}
/>
<Column
width={210}
disableSort
label='The description label is really long so that it will be truncated'
dataKey='random'
className={styles.exampleColumn}
cellRenderer={
({ cellData, columnData, dataKey, rowData, rowIndex }) => cellData
}
flexGrow={1}
/>
</Table>
)}
</AutoSizer>
</div>
</ContentBox>
)
}
_getDatum (list, index) {
// Getting error here : TypeError: list.get is not a function[Learn More]
return list.get(index % list.size)
}
_getRowHeight ({ index }) {
const list = this.props.filelist;
return this._getDatum(list, index).size
}
_headerRenderer ({
columnData,
dataKey,
disableSort,
label,
sortBy,
sortDirection
}) {
return (
<div>
Full Name
{sortBy === dataKey &&
<SortIndicator sortDirection={sortDirection} />
}
</div>
)
}
_isSortEnabled () {
const list= this.props.filelist;
const { rowCount } = this.state
return rowCount <= list.size
}
_noRowsRenderer () {
return (
<div className={styles.noRows}>
No rows
</div>
)
}
_onRowCountChange (event) {
const rowCount = parseInt(event.target.value, 10) || 0
this.setState({ rowCount })
}
_onScrollToRowChange (event) {
const { rowCount } = this.state
let scrollToIndex = Math.min(rowCount - 1, parseInt(event.target.value, 10))
if (isNaN(scrollToIndex)) {
scrollToIndex = undefined
}
this.setState({ scrollToIndex })
}
_rowClassName ({ index }) {
if (index < 0) {
return styles.headerRow
} else {
return index % 2 === 0 ? styles.evenRow : styles.oddRow
}
}
_sort ({ sortBy, sortDirection }) {
this.setState({ sortBy, sortDirection })
}
_updateUseDynamicRowHeight (value) {
this.setState({
useDynamicRowHeight: value
})
}
}
I am getting error inside -
_getDatum (list, index) {
// Getting error here : TypeError: list.get is not a function[Learn More]
return list.get(index % list.size)
}
I am not using immutable list, instead using my own object. If I do
console.log(this.props.filelist) // Object { filelist: Array[12] }
0:Object
absPath:"/home/testmaximumcharactersforfolders123"
created:1490586030000
filename:"testmaximumcharactersforfolders123"
hasChildren:true
isHidden:false
isReadable:true
isWritable:false
modified:1490586030000
owner:"root"
size:4096
type:"FILE_DIR"
I have one more question, as you can see my object structure above what should be my datakey ? As per my understanding using datakey we are referring key name in our object . so should it be datakey="filename" if I want to show filename data in the column ? And is it ok if my object contains other key value pair which I am not going to show in the table ?
Please help...
Screenshot of overlapping :

Resources