├── .versions ├── README.md ├── lib ├── EditDocument.jsx ├── NewDocument.jsx ├── export.js ├── smart-forms.jsx └── utils.js └── package.js /.versions: -------------------------------------------------------------------------------- 1 | aldeed:collection2@2.8.0 2 | aldeed:collection2-core@1.0.0 3 | aldeed:schema-deny@1.0.1 4 | aldeed:schema-index@1.0.1 5 | aldeed:simple-schema@1.5.3 6 | allow-deny@1.0.2-rc.2 7 | babel-compiler@6.5.1-rc.2 8 | babel-runtime@0.1.6-rc.2 9 | base64@1.0.6-rc.2 10 | binary-heap@1.0.6-rc.2 11 | blaze@2.1.5-rc.2 12 | blaze-tools@1.0.6-rc.2 13 | boilerplate-generator@1.0.6-rc.2 14 | callback-hook@1.0.6-rc.2 15 | check@1.1.2-rc.2 16 | ddp@1.2.3-rc.2 17 | ddp-client@1.2.3-rc.2 18 | ddp-common@1.2.3-rc.2 19 | ddp-server@1.2.4-rc.2 20 | deps@1.0.10-rc.2 21 | diff-sequence@1.0.3-rc.2 22 | ecmascript@0.4.1-rc.2 23 | ecmascript-runtime@0.2.8-rc.2 24 | ejson@1.0.9-rc.2 25 | geojson-utils@1.0.6-rc.2 26 | html-tools@1.0.7-rc.2 27 | htmljs@1.0.7-rc.2 28 | id-map@1.0.5-rc.2 29 | jquery@1.11.6-rc.2 30 | logging@1.0.10-rc.2 31 | mdg:validation-error@0.2.0 32 | meteor@1.1.12-rc.2 33 | minimongo@1.0.12-rc.2 34 | modules@0.5.1-rc.2 35 | modules-runtime@0.6.1-rc.2 36 | mongo@1.1.5-rc.2 37 | mongo-id@1.0.2-rc.2 38 | npm-mongo@1.4.41-rc.2 39 | observe-sequence@1.0.9-rc.2 40 | ordered-dict@1.0.5-rc.2 41 | promise@0.6.4-rc.2 42 | raix:eventemitter@0.1.3 43 | random@1.0.7-rc.2 44 | reactive-var@1.0.7-rc.2 45 | retry@1.0.5-rc.2 46 | routepolicy@1.0.8-rc.2 47 | spacebars@1.0.9-rc.2 48 | spacebars-compiler@1.0.9-rc.2 49 | tmeasday:check-npm-versions@0.1.1 50 | tracker@1.0.11-rc.2 51 | ui@1.0.9-rc.2 52 | underscore@1.0.6-rc.2 53 | utilities:react-form-containers@0.1.6 54 | utilities:smart-methods@0.1.2 55 | webapp@1.2.6-rc.2 56 | webapp-hashing@1.0.7-rc.2 57 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Forms 2 | 3 | This package provides two components (`NewDocument` and `EditDocument`) that work with the schema extension defined in the [smart-methods](https://github.com/meteor-utilities/smart-methods) package to let you easily generate new document and edit document forms. 4 | 5 | ### Install 6 | 7 | `meteor add utilities:react-form-containers` 8 | 9 | ### `NewDocument` 10 | 11 | This component takes the following properties: 12 | 13 | - `collection`: the collection in which to insert the new document. 14 | - `currentUser`: the current user. 15 | - `errorCallback`: a function to call on error. 16 | - `successCallback`: a function to call on success. 17 | - `methodName`: the name of the method to submit the form to. 18 | - `labelFunction`: a function that will be called on each field's name to get the label (for example, an internationalization function). 19 | 20 | ### `EditDocument` 21 | 22 | This component takes the same properties as `NewDocument`, plus: 23 | 24 | - `document`: the document being edited. -------------------------------------------------------------------------------- /lib/EditDocument.jsx: -------------------------------------------------------------------------------- 1 | import React, { PropTypes, Component } from 'react'; 2 | import Formsy from 'formsy-react'; 3 | import { Button } from 'react-bootstrap'; 4 | 5 | import SmartForms from "./smart-forms.jsx"; 6 | import Utils from './utils.js'; 7 | 8 | const EditDocument = React.createClass({ 9 | 10 | propTypes: { 11 | document: React.PropTypes.object.isRequired, 12 | collection: React.PropTypes.object.isRequired, 13 | currentUser: React.PropTypes.object, 14 | successCallback: React.PropTypes.func, 15 | errorCallback: React.PropTypes.func, 16 | methodName: React.PropTypes.string, 17 | labelFunction: React.PropTypes.func 18 | }, 19 | 20 | submitForm(data) { 21 | 22 | console.log(data) 23 | 24 | const document = this.props.document; 25 | const modifier = {$set: _.compactObject(Utils.flatten(data))}; 26 | const collection = this.props.collection; 27 | const methodName = this.props.methodName ? this.props.methodName : collection._name+'.edit'; 28 | 29 | console.log(modifier) 30 | 31 | Meteor.call(methodName, document._id, modifier, (error, document) => { 32 | if (error) { 33 | console.log(error) 34 | if (this.props.errorCallback) { 35 | this.props.errorCallback(document); 36 | } 37 | } else { 38 | if (this.props.successCallback) { 39 | this.props.successCallback(document); 40 | } 41 | } 42 | }); 43 | }, 44 | 45 | render() { 46 | 47 | const document = this.props.document; 48 | const collection = this.props.collection; 49 | const fields = collection.getInsertableFields(this.props.currentUser); 50 | 51 | const style = { 52 | maxWidth: "800px", 53 | width: "100%" 54 | } 55 | 56 | return ( 57 |
58 | 59 | {fields.map(fieldName =>
{SmartForms.getComponent(fieldName, collection.simpleSchema()._schema[fieldName], this.props.labelFunction, document)}
)} 60 | 61 |
62 |
63 | ) 64 | } 65 | }); 66 | 67 | module.exports = EditDocument; 68 | export default EditDocument; -------------------------------------------------------------------------------- /lib/NewDocument.jsx: -------------------------------------------------------------------------------- 1 | import React, { PropTypes, Component } from 'react'; 2 | import Formsy from 'formsy-react'; 3 | import { Button } from 'react-bootstrap'; 4 | 5 | import SmartForms from "./smart-forms.jsx"; 6 | import Utils from './utils.js'; 7 | 8 | const NewDocument = React.createClass({ 9 | 10 | propTypes: { 11 | collection: React.PropTypes.object.isRequired, 12 | currentUser: React.PropTypes.object, 13 | errorCallback: React.PropTypes.func, 14 | successCallback: React.PropTypes.func, 15 | methodName: React.PropTypes.string, 16 | labelFunction: React.PropTypes.func 17 | }, 18 | 19 | submitForm(data) { 20 | 21 | // remove any empty properties 22 | const document = _.compactObject(Utils.flatten(data)); 23 | const collection = this.props.collection; 24 | const methodName = this.props.methodName ? this.props.methodName : collection._name+'.create'; 25 | 26 | Meteor.call(methodName, document, (error, document) => { 27 | if (error) { 28 | console.log(error) 29 | if (this.props.errorCallback) { 30 | this.props.errorCallback(document); 31 | } 32 | } else { 33 | if (this.props.successCallback) { 34 | this.props.successCallback(document); 35 | } 36 | } 37 | }); 38 | }, 39 | 40 | render() { 41 | 42 | const collection = this.props.collection; 43 | const fields = collection.getInsertableFields(this.props.currentUser); 44 | 45 | const style = { 46 | maxWidth: "800px", 47 | width: "100%" 48 | } 49 | 50 | return ( 51 |
52 | 53 | {fields.map(fieldName =>
{SmartForms.getComponent(fieldName, collection.simpleSchema()._schema[fieldName], this.props.labelFunction)}
)} 54 | 55 |
56 |
57 | ) 58 | } 59 | }); 60 | 61 | module.exports = NewDocument; 62 | export default NewDocument; -------------------------------------------------------------------------------- /lib/export.js: -------------------------------------------------------------------------------- 1 | import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions'; 2 | checkNpmVersions({ 3 | "react": "^0.14.6", 4 | "formsy-react": "^0.17.0", 5 | "formsy-react-components": "^0.6.6", 6 | "react-bootstrap": "^0.28.3" 7 | // 'rebass': '^0.2.4', 8 | }); 9 | 10 | import NewDocument from "./NewDocument.jsx"; 11 | import EditDocument from "./EditDocument.jsx"; 12 | 13 | export default {NewDocument, EditDocument}; -------------------------------------------------------------------------------- /lib/smart-forms.jsx: -------------------------------------------------------------------------------- 1 | import React, { PropTypes, Component } from 'react'; 2 | import Formsy from 'formsy-react'; 3 | import FRC from 'formsy-react-components'; 4 | 5 | import Utils from './utils.js'; 6 | 7 | const Checkbox = FRC.Checkbox; 8 | const CheckboxGroup = FRC.CheckboxGroup; 9 | const Input = FRC.Input; 10 | const RadioGroup = FRC.RadioGroup; 11 | const Select = FRC.Select; 12 | const Textarea = FRC.Textarea; 13 | 14 | const SmartForms = {}; 15 | 16 | SimpleSchema.extendOptions({ 17 | insertableIf: Match.Optional(Function), 18 | editableIf: Match.Optional(Function) 19 | }); 20 | 21 | SmartForms.getComponent = (fieldName, field, labelFunction, document) => { 22 | 23 | let options = []; 24 | if (field.autoform && field.autoform.options) { 25 | options = typeof field.autoform.options === "function" ? field.autoform.options() : field.autoform.options; 26 | } 27 | 28 | const value = document && Utils.deepValue(document, fieldName) ? Utils.deepValue(document, fieldName) : ""; 29 | const label = typeof labelFunction === "function" ? labelFunction(fieldName) : fieldName; 30 | 31 | switch (field.control) { 32 | 33 | case "text": 34 | return ; 35 | case "textarea": 36 | return