install
meteor add cesarve:react-auto-table
Usage
1 2//on server && client 3import createAutoTable from 'meteor/cesarve:react-auto-table' 4import {userSchema as schema} from './Users' 5const Collection = Meteor.users 6const columns = [ 7 { 8 Header: 'Email', 9 accessor: 'emails.0.address' 10 }, 11 { 12 Header: 'First name', 13 accessor: 'profile.firstName' 14 }, 15 { 16 Header: 'Family name', 17 accessor: 'profile.familyName' 18 }, 19] 20 21export default createAutoTable({Collection, schema, columns})
Props
| Property | Type | Required/default | Where | Explanation |
|---|---|---|---|---|
| Collection | MongoCollection | required | Both | Where the data comes from |
| columns | Array | required | Both | List of columns to show. see columns prop above |
| schema | SimpleSchema | undefined | Both | Schema. This is used to automatically create filters based on field type |
| query | Object | {} | Both | Mongo query for filter the data |
| publish | Function | ()=>true | Server | Function for determine if it is allowed or not publish the data on server side. see publish prop above |
| defaultTypeFilters | Object | seetype filter | Both | Defaults cell filterMethod and filter. see defaultTypeFilters prop above |
| filterKeyUpDelay | Number | 400 | Client | Number of milliseconds for fetch the data after keyup on filters |
Columns prop
for complete options see react-table.
There are two special properties
- filterMethod
- filter
if you pass schema prop both will be filled by AutoTable according to defaultTypeFilters or if not both will filled with:
1filterMethod = (filter, row) => ({[filter.id]: filter.value}), 2filter = ({filter, onChange}) => <input type="text" onChange={event => onChange(event.target.value)} value={filter.value}/> 3
defaultTypeFilters prop
Based on simple schema there are only ten kind of field types:
- string
- number
- boolean
- date
- object
- stringArray (array of string [ string ])
- numberArray
- booleanArray
- dateArray
- objectArray
Yu can pass individual filterMethod and filter for each columns and/or you can pass defaultFilter to createAutoTAble function and it assign this properties according to the kind of field.
The default typeFilters is as follow, you need to pass a same shape object
1 2export const typeFilters = { 3 string: { 4 method: (filter, row) => ({[filter.id]: {$regex: filter.value, $options: 'gi'}}), 5 filter: ({filter, onChange}) => <input type="text" onChange={event => onChange(event.target.value)} value={filter.value}/>, 6 }, 7 number: { 8 method: defaultFilter.method, 9 filter: ({filter, onChange}) => <input type="numeric" onChange={event => onChange(event.target.value)} value={filter.value}/>, 10 }, 11 boolean: { 12 method: (filter, row) => ({[filter.id]: filter.value}), 13 filter: ({filter, onChange}) => <select onChange={event => onChange(event.target.value)} value={filter.value}> 14 <option value={true}>Select</option> 15 <option value={true}>Yes</option> 16 <option value={false}>No</option> 17 </select>, 18 }, 19 date: { 20 method: (filter, row) => { 21 const $gte = new Date(filter.value).setHours(0, 0, 0, 0) 22 const $lte = new Date(filter.value).setHours(24, 0, 0, 0) 23 return {[filter.id]: {$gte, $lte}} 24 }, 25 filter: ({filter, onChange}) => <input type="date" onChange={event => onChange(event.target.value)} value={filter.value}/>, 26 }, 27 object:{ 28 method: (filter, row) => ({[filter.id]: filter.value}), 29 filter: ({filter, onChange}) => <input type="text" onChange={event => onChange(event.target.value)} value={filter.value}/>, 30 }, 31 stringArray: { 32 method: (filter, row) => ({[filter.id]: filter.value}), 33 filter: ({filter, onChange}) => <input type="text" onChange={event => onChange(event.target.value)} value={filter.value}/>, 34 }, 35 numberArray: { 36 method: (filter, row) => ({[filter.id]: filter.value}), 37 filter: ({filter, onChange}) => <input type="text" onChange={event => onChange(event.target.value)} value={filter.value}/>, 38 }, 39 booleanArray: { 40 method: (filter, row) => ({[filter.id]: filter.value}), 41 filter: ({filter, onChange}) => <input type="text" onChange={event => onChange(event.target.value)} value={filter.value}/>, 42 }, 43 dateArray: { 44 method: (filter, row) => ({[filter.id]: filter.value}), 45 filter: ({filter, onChange}) => <input type="text" onChange={event => onChange(event.target.value)} value={filter.value}/>, 46 }, 47 objectArray: { 48 method: (filter, row) => ({[filter.id]: filter.value}), 49 filter: ({filter, onChange}) => <input type="text" onChange={event => onChange(event.target.value)} value={filter.value}/>, 50 }, 51} 52 53
publish prop
This function will receive as unique param a object with {Collection, columns, schema, query} properties and it will have as a context the same context than a publish meteor function (normally you only will need this.userId).
Finally this function need to return:
- true for automatic publication based on columns prop
- false for denied publication
- Any thing else for a custom publication, probably you will need to use this.added('collection_name',_id,{customObject}); this.ready();
Examples:
True or false example
1publish=({Collection, columns, schema, query})=> Roles.userIsInRole(this.userId,'admin')
Custom publish example
1publish=({Collection, columns, schema, query})=> { 2 const handle = Collection.find(query).observeChanges({ 3 added: (id,doc) => { 4 doc.joinField=OtherCollection.find({_id: doc.otherCollectionId}).fetch() /*is just a example, don't abuse of this*/ 5 this.added(Collection._name, id, doc); 6 }, 7 changed: (id) => { 8 /**handle changed**/ 9 }, 10 removed: (id) => { 11 /**handle removed**/ 12 } 13 }); 14 15 this.ready(); 16 this.onStop(() => handle.stop()); 17 /* 18 note: 19 I'm returning undefined in this function, 20 if true is returned automatic publication will be run as well 21 If false is returned, previous publication will be executed but not the automatic 22 */ 23}
publish