Vulcan/packages/nova-forms
2016-06-22 10:16:07 +02:00
..
lib added order support for custom fields 2016-06-22 10:16:07 +02:00
package.js make nova:forms accept schemas as well as collections 2016-06-13 16:05:46 +09:00
README.md make submitData callback do something (see #1355) 2016-06-17 13:05:17 +09:00

Nova Forms

This package provides a NovaForm component that works with the schema extension defined in the smart-methods package to let you easily generate new document and edit document forms.

Install

meteor add nova:forms

(note: package is not published yet)

Features

This package can generate new document and edit document forms from a SimpleSchema schema. Features include:

  • Error handling.
  • Bootstrap-compatible.
  • Cross-component communciation (prefill a field based on another).
  • Callbacks on form submission, success, and failure.
  • Support for basic form controls (input, textarea, radio, etc.).
  • Support for custom form controls.
  • Submission to Meteor methods.

NPM Dependencies

react react-intl formsy-react react-bootstrap formsy-react-components

You also need to load Bootstrap's CSS separately.

Usage

Example schema:


import BodyFormControl from './components/BodyFormControl.jsx';

const isLoggedIn = (user) => !!user;
const isOwner = (user, document) => user._id === document.userId;
const isAdmin = (user) => user.isAdmin;

const PostsSchema = new SimpleSchema({
  postedAt: {
    type: Date,
    optional: true
    // no insertableIf or editableIf means this field won't appear in forms
  },
  title: {
    type: String,
    optional: false,
    max: 500,
    insertableIf: isLoggedIn,
    editableIf: isOwner,
    control: "text",
    order: 1
  },
  body: {
    type: String,
    optional: true,
    max: 3000,
    insertableIf: isLoggedIn,
    editableIf: isOwner,
    control: BodyFormControl,
    order: 2
  },
  sticky: {
    type: Boolean,
    optional: true,
    defaultValue: false,
    insertableIf: isAdmin,
    editableIf: isAdmin,
    control: "checkbox",
    order: 3
  },
}

New document form:

<NovaForm 
  collection={Posts}
  currentUser={currentUser},
  methodName="posts.new"
/>

Edit document form:

<NovaForm 
  collection={Posts}
  currentUser={currentUser},
  methodName="posts.edit",
  document={post},
  labelFunction={capitalize}
  successCallback={closeModal}
/>

Props

collection

The collection in which to edit or insert a document.

schema

If you prefer, you can also specify a schema instead of a collection.

document

If present, the document to edit. If not present, the form will be a “new document” form.

currentUser

The current user.

submitCallback(data)

A callback called on form submission on the form data. Should return the data object as well.

successCallback(document)

A callback called on method success.

errorCallback(document, error)

A callback called on method failure.

cancelCallback()

If provided, will show a "cancel" link next to the form's submit button.

methodName

The name of the Meteor method to call.

labelFunction

A function to call on field names to get the label.

prefilledProps

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 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.

order

A number corresponding to the position of the property's field inside the form.

group

An optional object containing the group/section/fieldset in which to include the form element. Groups have name, label, and order properties.

For example:

postedAt: {
  type: Date,
  optional: true,
  insertableIf: Users.is.admin,
  editableIf: Users.is.admin,
  publish: true,
  control: "datetime",
  group: {
    name: "admin",
    label: "Admin Options",
    order: 2
  }
},

Note that fields with no groups are always rendered first in the form.

Context

The main NovaForm components makes the following objects available as context to all its children:

autofilledValues

An object containing optional autofilled properties.

addToAutofilledValues({name: value})

A function that takes a property, and adds it to the autofilledValues object.

throwError({content, type})

A callback function that can be used to throw an error.

Handling Values

The component handles three different layers of input values:

  • The value stored in the database (when editing a document).
  • The value being currently inputted in the form element.
  • An “autofilled” value, typically provided by an other form element (i.e. autofilling the post title from its URL).

The highest-priority value is the user input. If there is no user input, we default to the database value provided by the props. And if that one is empty too, we then look for autofilled values.

i18n

This package uses React Intl to automatically translate all labels. In order to do so it expects an intl object ot be passed as part of its context. For example, in a parent component:

getChildContext() {
  const intlProvider = new IntlProvider({locale: myLocale}, myMessages);
  const {intl} = intlProvider.getChildContext();
  return {
    intl: intl
  };
}