mirror of
https://github.com/vale981/Vulcan
synced 2025-03-06 01:51:40 -05:00
clean up forms package and update readme
This commit is contained in:
parent
a367ed426d
commit
641bc46e13
3 changed files with 42 additions and 246 deletions
|
@ -8,38 +8,70 @@ This package provides a `NovaForm` component that works with the schema extensio
|
|||
|
||||
### Props
|
||||
|
||||
#### collection `object.isRequired`
|
||||
#### `collection`
|
||||
|
||||
The collection in which to edit or insert a document.
|
||||
|
||||
#### document `object`
|
||||
#### `document`
|
||||
|
||||
If present, the document to edit. If not present, the form will be a “new document” form.
|
||||
|
||||
#### currentUser `object`
|
||||
#### `currentUser`
|
||||
|
||||
The current user.
|
||||
|
||||
#### submitCallback() `func`
|
||||
#### `submitCallback()`
|
||||
|
||||
A callback called on form submission.
|
||||
|
||||
#### successCallback(document) `func`
|
||||
#### `successCallback(document)`
|
||||
|
||||
A callback called on method success.
|
||||
|
||||
#### errorCallback(document, error) `func`
|
||||
#### `errorCallback(document, error)`
|
||||
|
||||
A callback called on method failure.
|
||||
|
||||
#### methodName `string`
|
||||
#### `methodName`
|
||||
|
||||
The name of the Meteor method to call.
|
||||
|
||||
#### labelFunction `func`
|
||||
#### `labelFunction`
|
||||
|
||||
A function to call on field names to get the label.
|
||||
|
||||
#### prefilledProps `object`
|
||||
#### `prefilledProps`
|
||||
|
||||
A set of props to prefill for new documents.
|
||||
A set of props to prefill for new documents.
|
||||
|
||||
### Collection Schema
|
||||
|
||||
This package generates forms based on the following special schema properties (see also the [Smart Methods](https://github.com/meteor-utilities/smart-methods) package:
|
||||
|
||||
#### `insertableIf(user)`
|
||||
|
||||
A function called on the `user` performing the operation, should return `true` or `false`. When generating a form for inserting new documents, the form will contain all the fields that return `true` for the current user.
|
||||
|
||||
#### `editableIf(user, document)`
|
||||
|
||||
Called on the `user` performing the operation, and the `document` being operated on, and should return `true` or `false`. When generating a form for editing existing documents, the form will contain all the fields that return `true` for the current user.
|
||||
|
||||
#### `control`
|
||||
|
||||
Either a text string (one of `text`, `textarea`, `checkbox`, `checkboxgroup`, `radiogroup`, or `select`) or a React component.
|
||||
|
||||
#### `position`
|
||||
|
||||
A number corresponding to the position of the property's field inside the form.
|
||||
|
||||
### Context
|
||||
|
||||
The main `NovaForm` components makes the following objects available as context to all its children:
|
||||
|
||||
#### `currentValues`
|
||||
|
||||
An object containing all the current values of the form.
|
||||
|
||||
#### `throwError({content, type})`
|
||||
|
||||
A callback function that can be used to throw an error.
|
|
@ -1,122 +0,0 @@
|
|||
import React, { PropTypes, Component } from 'react';
|
||||
import Formsy from 'formsy-react';
|
||||
import { Button } from 'react-bootstrap';
|
||||
|
||||
import FormComponent from "./FormComponent.jsx";
|
||||
import Utils from './utils.js';
|
||||
|
||||
class EditDocument extends Component{
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.submitForm = this.submitForm.bind(this);
|
||||
this.state = {
|
||||
disabled: false
|
||||
};
|
||||
}
|
||||
|
||||
getFields() {
|
||||
const collection = this.props.collection;
|
||||
const fields = collection.getEditableFields(this.props.currentUser);
|
||||
return fields;
|
||||
}
|
||||
|
||||
submitForm(data) {
|
||||
|
||||
this.setState({disabled: true});
|
||||
|
||||
// if there's a submit callback, run it
|
||||
if (this.props.submitCallback) {
|
||||
this.props.submitCallback();
|
||||
}
|
||||
|
||||
const fields = this.getFields();
|
||||
const document = this.props.document;
|
||||
// put all keys with data on $set
|
||||
const set = _.compactObject(Utils.flatten(data));
|
||||
// put all keys without data on $unset
|
||||
const unsetKeys = _.difference(fields, _.keys(set));
|
||||
const unset = _.object(unsetKeys, unsetKeys.map(()=>true));
|
||||
const modifier = {$set: set, $unset: unset};
|
||||
const collection = this.props.collection;
|
||||
|
||||
Meteor.call(this.props.methodName, document._id, modifier, (error, document) => {
|
||||
|
||||
this.setState({disabled: false});
|
||||
|
||||
if (error) {
|
||||
console.log(error)
|
||||
this.setState({
|
||||
errors: [{
|
||||
content: error.message,
|
||||
type: "error"
|
||||
}]
|
||||
});
|
||||
if (this.props.errorCallback) {
|
||||
this.props.errorCallback(document, error);
|
||||
}
|
||||
} else {
|
||||
this.setState({errors: []});
|
||||
if (this.props.successCallback) {
|
||||
this.props.successCallback(document);
|
||||
}
|
||||
if (this.context.closeCallback) {
|
||||
this.context.closeCallback();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
renderErrors() {
|
||||
Flash = Telescope.components.Flash;
|
||||
return <div className="form-errors">{this.state.errors.map(message => <Flash message={message}/>)}</div>
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const document = this.props.document;
|
||||
const collection = this.props.collection;
|
||||
const fields = this.getFields();
|
||||
|
||||
const style = {
|
||||
maxWidth: "800px",
|
||||
width: "100%"
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="edit-document" style={style}>
|
||||
<Formsy.Form onSubmit={this.submitForm} disabled={this.state.disabled}>
|
||||
{this.renderErrors()}
|
||||
{fields.map(fieldName => <FormComponent
|
||||
key={fieldName}
|
||||
className={"input-"+fieldName}
|
||||
fieldName={fieldName}
|
||||
field={collection.simpleSchema()._schema[fieldName]}
|
||||
labelFunction={this.props.labelFunction}
|
||||
document={document}
|
||||
/>)}
|
||||
<Button type="submit" bsStyle="primary">Submit</Button>
|
||||
</Formsy.Form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
EditDocument.propTypes = {
|
||||
document: React.PropTypes.object.isRequired,
|
||||
collection: React.PropTypes.object.isRequired,
|
||||
currentUser: React.PropTypes.object,
|
||||
successCallback: React.PropTypes.func,
|
||||
errorCallback: React.PropTypes.func,
|
||||
methodName: React.PropTypes.string,
|
||||
labelFunction: React.PropTypes.func
|
||||
}
|
||||
|
||||
EditDocument.contextTypes = {
|
||||
closeCallback: React.PropTypes.func
|
||||
}
|
||||
|
||||
module.exports = EditDocument;
|
||||
export default EditDocument;
|
|
@ -1,114 +0,0 @@
|
|||
import React, { PropTypes, Component } from 'react';
|
||||
import Formsy from 'formsy-react';
|
||||
import { Button } from 'react-bootstrap';
|
||||
|
||||
import FormComponent from "./FormComponent.jsx";
|
||||
import Utils from './utils.js';
|
||||
|
||||
class NewDocument extends Component {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.submitForm = this.submitForm.bind(this);
|
||||
this.state = {
|
||||
disabled: false,
|
||||
errors: []
|
||||
};
|
||||
}
|
||||
|
||||
submitForm(data) {
|
||||
|
||||
this.setState({disabled: true});
|
||||
|
||||
// if there's a submit callback, run it
|
||||
if (this.props.submitCallback) {
|
||||
this.props.submitCallback();
|
||||
}
|
||||
|
||||
// remove any empty properties
|
||||
let document = _.compactObject(Utils.flatten(data));
|
||||
const collection = this.props.collection;
|
||||
|
||||
// add prefilled properties
|
||||
if (this.props.prefilledProps) {
|
||||
document = Object.assign(document, this.props.prefilledProps);
|
||||
}
|
||||
|
||||
Meteor.call(this.props.methodName, document, (error, document) => {
|
||||
|
||||
this.setState({disabled: false});
|
||||
|
||||
if (error) {
|
||||
console.log(error)
|
||||
this.setState({
|
||||
errors: [{
|
||||
content: error.message,
|
||||
type: "error"
|
||||
}]
|
||||
});
|
||||
if (this.props.errorCallback) {
|
||||
this.props.errorCallback(document, error);
|
||||
}
|
||||
} else {
|
||||
this.setState({errors: []});
|
||||
this.refs.newDocumentForm.reset();
|
||||
if (this.props.successCallback) {
|
||||
this.props.successCallback(document);
|
||||
}
|
||||
if (this.context.closeCallback) {
|
||||
this.context.closeCallback();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
renderErrors() {
|
||||
Flash = Telescope.components.Flash;
|
||||
return <div className="form-errors">{this.state.errors.map(message => <Flash message={message}/>)}</div>
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const collection = this.props.collection;
|
||||
const fields = collection.getInsertableFields(this.props.currentUser);
|
||||
|
||||
const style = {
|
||||
maxWidth: "800px",
|
||||
width: "100%"
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="new-document" style={style}>
|
||||
<Formsy.Form onSubmit={this.submitForm} disabled={this.state.disabled} ref="newDocumentForm">
|
||||
{this.renderErrors()}
|
||||
{fields.map(fieldName => <FormComponent
|
||||
key={fieldName}
|
||||
className={"input-"+fieldName}
|
||||
fieldName={fieldName}
|
||||
field={collection.simpleSchema()._schema[fieldName]}
|
||||
labelFunction={this.props.labelFunction}
|
||||
/>)}
|
||||
<Button type="submit" bsStyle="primary">Submit</Button>
|
||||
</Formsy.Form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
NewDocument.propTypes = {
|
||||
collection: React.PropTypes.object.isRequired,
|
||||
currentUser: React.PropTypes.object,
|
||||
errorCallback: React.PropTypes.func,
|
||||
successCallback: React.PropTypes.func,
|
||||
methodName: React.PropTypes.string,
|
||||
labelFunction: React.PropTypes.func,
|
||||
prefilledProps: React.PropTypes.object
|
||||
}
|
||||
|
||||
NewDocument.contextTypes = {
|
||||
closeCallback: React.PropTypes.func
|
||||
}
|
||||
|
||||
module.exports = NewDocument;
|
||||
export default NewDocument;
|
Loading…
Add table
Reference in a new issue