├── .gitignore
├── .versions
├── MeteorGriddle.jsx
├── README.md
└── package.js
/.gitignore:
--------------------------------------------------------------------------------
1 | .npm
--------------------------------------------------------------------------------
/.versions:
--------------------------------------------------------------------------------
1 | allow-deny@1.0.4
2 | babel-compiler@6.6.4
3 | babel-runtime@0.1.8
4 | base64@1.0.8
5 | binary-heap@1.0.8
6 | blaze@2.1.7
7 | blaze-tools@1.0.8
8 | boilerplate-generator@1.0.8
9 | callback-hook@1.0.8
10 | check@1.2.1
11 | ddp@1.2.5
12 | ddp-client@1.2.7
13 | ddp-common@1.2.5
14 | ddp-server@1.2.6
15 | deps@1.0.12
16 | diff-sequence@1.0.5
17 | ecmascript@0.4.3
18 | ecmascript-runtime@0.2.10
19 | ejson@1.0.11
20 | geojson-utils@1.0.8
21 | html-tools@1.0.9
22 | htmljs@1.0.9
23 | id-map@1.0.7
24 | jquery@1.11.8
25 | jsx@0.2.4
26 | logging@1.0.12
27 | meteor@1.1.14
28 | minimongo@1.0.16
29 | modules@0.6.1
30 | modules-runtime@0.6.3
31 | mongo@1.1.7
32 | mongo-id@1.0.4
33 | npm-mongo@1.4.43
34 | observe-sequence@1.0.11
35 | ordered-dict@1.0.7
36 | promise@0.6.7
37 | random@1.0.9
38 | react-meteor-data@0.2.9
39 | reactive-var@1.0.9
40 | retry@1.0.7
41 | routepolicy@1.0.10
42 | spacebars@1.0.11
43 | spacebars-compiler@1.0.11
44 | tmeasday:check-npm-versions@0.2.0
45 | tmeasday:publish-counts@0.7.3
46 | tracker@1.0.13
47 | ui@1.0.11
48 | underscore@1.0.8
49 | utilities:meteor-griddle@1.2.1
50 | webapp@1.2.8
51 | webapp-hashing@1.0.9
52 |
--------------------------------------------------------------------------------
/MeteorGriddle.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions';
3 | import { _ } from 'meteor/underscore';
4 | import Griddle from 'griddle-react';
5 |
6 | checkNpmVersions({
7 | 'griddle-react': '0.5.x',
8 | 'react-addons-pure-render-mixin': '15.x',
9 | }, 'utilities:meteor-griddle');
10 |
11 | MeteorGriddle = React.createClass({
12 |
13 | propTypes: {
14 | publication: React.PropTypes.string, // the publication that will provide the data
15 | collection: React.PropTypes.object, // the collection to display
16 | matchingResultsCount: React.PropTypes.string, // the name of the matching results counter
17 | filteredFields: React.PropTypes.array, // an array of fields to search through when filtering
18 | subsManager: React.PropTypes.object,
19 | // plus regular Griddle props
20 | },
21 |
22 | mixins: [ReactMeteorData],
23 |
24 | getDefaultProps() {
25 | return {
26 | useExternal: false,
27 | externalFilterDebounceWait: 300,
28 | externalResultsPerPage: 10,
29 | };
30 | },
31 |
32 | getInitialState() {
33 |
34 | return {
35 | currentPage: 0,
36 | maxPages: 0,
37 | externalResultsPerPage: this.props.externalResultsPerPage,
38 | externalSortColumn: this.props.externalSortColumn,
39 | externalSortAscending: this.props.externalSortAscending,
40 | query: {},
41 | };
42 |
43 | },
44 |
45 | componentWillMount() {
46 | this.applyQuery = _.debounce((query) => {
47 | this.setState({ query });
48 | }, this.props.externalFilterDebounceWait);
49 | },
50 |
51 | getMeteorData() {
52 |
53 | // Get a count of the number of items matching the current filter.
54 | // If no filter is set it will return the total number of items in the
55 | // collection.
56 | var matchingResults = Counts.get(this.props.matchingResultsCount);
57 |
58 | const options = {};
59 | let skip;
60 | if (this.props.useExternal) {
61 | options.limit = this.state.externalResultsPerPage;
62 | if (!_.isEmpty(this.state.query) && !!matchingResults) {
63 | // if necessary, limit the cursor to number of matching results to avoid
64 | // displaying results from other publications
65 | options.limit = _.min([options.limit, matchingResults]);
66 | }
67 | options.sort = {
68 | [this.state.externalSortColumn]:
69 | (this.state.externalSortAscending ? 1 : -1)
70 | };
71 | skip = this.state.currentPage * this.state.externalResultsPerPage;
72 | }
73 |
74 | let pubHandle;
75 |
76 | if (this.props.subsManager) {
77 | pubHandle = this.props.subsManager.subscribe(
78 | this.props.publication,
79 | this.state.query,
80 | _.extend({skip: skip}, options)
81 | );
82 | } else {
83 | pubHandle = Meteor.subscribe(
84 | this.props.publication,
85 | this.state.query,
86 | _.extend({skip: skip}, options)
87 | );
88 | }
89 |
90 | const results =
91 | this.props.collection.find(this.state.query, options).fetch();
92 |
93 | return {
94 | loading: !pubHandle.ready(),
95 | results: results,
96 | matchingResults: matchingResults
97 | }
98 | },
99 |
100 | resetQuery() {
101 | this.setState({
102 | query: {},
103 | });
104 | },
105 |
106 | //what page is currently viewed
107 | setPage(index) {
108 | this.setState({currentPage: index});
109 | },
110 |
111 | //this changes whether data is sorted in ascending or descending order
112 | changeSort(sort, sortAscending) {
113 | this.setState({externalSortColumn: sort, externalSortAscending: sortAscending});
114 | },
115 |
116 | setFilter(filter) {
117 | if (filter) {
118 | const filteredFields = this.props.filteredFields || this.props.columns;
119 | const orArray = filteredFields.map((field) => {
120 | const filterItem = {};
121 | filterItem[field] = {$regex: filter, $options: 'i'};
122 | return filterItem;
123 | });
124 | this.applyQuery({ $or: orArray });
125 | } else {
126 | this.resetQuery();
127 | }
128 | },
129 |
130 | //this method handles determining the page size
131 | setPageSize(size) {
132 | this.setState({ externalResultsPerPage: size });
133 | },
134 |
135 | render() {
136 |
137 | // figure out how many pages we have based on the number of total results
138 | // matching the cursor
139 | var maxPages =
140 | Math.ceil(this.data.matchingResults/this.state.externalResultsPerPage);
141 |
142 | // The Griddle externalIsLoading property is managed internally to line
143 | // up with the subscription ready state, so we're removing this property
144 | // if it's passed in.
145 | const allProps = this.props;
146 | delete allProps.externalIsLoading;
147 |
148 | return (
149 |