Hi,
I am trying to move slowly from Blaze to React. I want to have a reactive table in the page, with sorting and search. Looks like there’s already a solid one implemented as React component. However, I don’t know how to add this to my project, I know, quite a noobie…
Any advice?
Hey,
Yeah - I got this to work. In essence -
Follow instructions on the git page, GitHub - AllenFang/react-bootstrap-table: A Bootstrap table built with React.js to install.
- Do the install in your project:
meteor npm install react-bootstrap-table --save
- You will also need to add:
meteor npm install --save meteor-node-stubs
- You don’t need to build it, just do the ECMAScript 6 import in your component.
- Add in the CSS file. Just copy into your client/spreadsheets directory.
Example below: There is a bunch of other stuff i was p[laying with, specifically an accordion, but the getUsers2() is what you want.
// imports/ui/components/globaladmin/users-list.js
import React, { Component, PropTypes } from 'react';
import { createContainer } from 'meteor/react-meteor-data';
// Publications
import { Users } from '../../../api/globaladmin/users.js';
// React-Bootstrap
import { Accordion, Panel } from 'react-bootstrap';
// React-Bootstreap-Table
import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table';
// Sub Components
import User from './user.js';
class UsersList extends Component {
getUsers() {
return this.props.users.map((user) =>
<User key = {user._id} user = {user} />
);
}
getUsers2() {
const users = [];
const quantity = this.props.count;
for (let i = 0; i < quantity; i++) {
users.push({
id: this.props.users[i]._id,
name: this.props.users[i].profile.name.first
+ this.props.users[i].profile.name.last,
});
}
return (
<BootstrapTable data={ users }>
<TableHeaderColumn dataField="id" isKey={ true }>Product ID</TableHeaderColumn>
<TableHeaderColumn dataField="name">Product Name</TableHeaderColumn>
</BootstrapTable>
);
}
render() {
return (
<div className="global-admin">
<Accordion>
<Panel header="Collapsible Group Item #1" eventKey="1">
{this.getUsers()}
</Panel>
<Panel header="Collapsible Group Item #2" eventKey="2">
{this.getUsers2()}
</Panel>
<Panel header="Collapsible Group Item #3" eventKey="3">
<p>Even more stuff</p>
</Panel>
</Accordion>
</div>
);
}
}
UsersList.propTypes = {
users: PropTypes.array.isRequired,
count: PropTypes.number.isRequired,
};
export default createContainer(() => {
Meteor.subscribe('users-list');
return {
users: Users.find({}).fetch(),
count: Users.find().count(),
};
}, UsersList);
Looks like:
I’m using Meteor Chef’s base as the harness for this. I’ll try to put together a gist about how to use all these nicely in a bit. Table’s in React seem like far more pain and boilerplate than they should be. I did not bother changing the productname and product id, that was from the example i was using.
Tat
Hi ,
I have been able to get this working . But “New Row” modal does not seem to be working .
- The modal code is present in the html
- if I change the display options of the modal it shows on the screen
So I believe the issue could be because of data-toggle property not working within the meteor setup.Any ideas ?
Hi @smitkant ,
I got it to work using below. I ended up not actually using the component, as I’m trying to learn react. But below is what I did -
import React from 'react';
// Container
import { createContainer } from 'meteor/react-meteor-data';
// React-Bootstrap-Table
import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table';
function addRole(row) {
Meteor.call('roles.insert', row.toString());
}
function removeRole(row) {
Meteor.call('roles.remove', row.toString());
}
const options = {
afterInsertRow: addRole,
afterDeleteRow: removeRole,
};
const selectRowProp = {
mode: 'radio',
};
class Working extends React.Component {
getRoles() {
const roles = [];
const quantity = this.props.count;
for (let i = 0; i < quantity; i ++) {
roles.push({
number: i,
id: this.props.roles[i]._id,
name: this.props.roles[i].name,
});
}
return roles;
}
render() {
return (
<div>
<h4>Role List</h4>
<BootstrapTable
data={ this.getRoles() }
insertRow={ true }
deleteRow={ true }
selectRow={ selectRowProp }
options={ options }
>
<TableHeaderColumn dataField="number">Role #</TableHeaderColumn>
<TableHeaderColumn dataField="name" isKey={ true }>Role Name</TableHeaderColumn>
</BootstrapTable>
</div>
);
}
}
Working.propTypes = {
// Some props here
roles: React.PropTypes.array.isRequired,
count: React.PropTypes.number.isRequired,
};
export default createContainer(() => {
Meteor.subscribe('roles-list');
return {
roles: Meteor.roles.find({}).fetch(),
count: Meteor.roles.find().count(),
};
}, Working);
The options triggers the below -
const options = {
afterInsertRow: addRole,
afterDeleteRow: removeRole,
};
This calls the relevant functions. The roles.insert and roles.remove are on the server side. I’m using the roles package here for authentication/authorization. It was just a convenient collection to play around with while I was testing this.
function addRole(row) {
Meteor.call('roles.insert', row.toString());
}
function removeRole(row) {
Meteor.call('roles.remove', row.toString());
}
Thanks so much.
Tat
Thx a ton Tat. Will try this out .
Hi Tat,
import React, { Component } from 'react';
import {BootstrapTable,TableHeaderColumn} from 'react-bootstrap-table';
// App component - represents the whole app
export default class App extends Component {
render(){
var data = [
{id : 1, name : "Tom"},
{id : 2, name : "Dick"},
{id : 3, name : "Harry"},
];
var selectRowProp = {
mode: "radio"
};
return(
<BootstrapTable
data={data}
selectRow={selectRowProp}
insertRow={true}
>
<TableHeaderColumn dataField="id" isKey={true}>Id</TableHeaderColumn>
<TableHeaderColumn dataField="name" >Name</TableHeaderColumn>
</BootstrapTable>
);
}
}
have reduced the code to this . but still can’t get the modal to open on clicking “New Row” .
HTML file looks like this
<head>
<title>Test table</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="react-bootstrap-table-all.min.css" >
</head>
<body>
<div id="app"></div>
</body>
Any ideas ? BTW i am including the CSS file by creating a soft link from inside the node_modules folder
Smit
I simply manually copied the css file into my stylesheets folder. I’m not sure it works if you use the <link....>
thing. Also added bootstrap directly from npm…
Also, to be honest, the entire thing was very fiddly. It was easier to just build a table directly from react-bootstrap.
Tat
Hi Tat,
Thanks for the reply . Silly me had included bootstrap js file incorrectly . Its sorted now . Thanks again
Smit
How to handle properly pagination in publications on the server side ?