# meteor-autoform2 **Repository Path**: xiaolinlu/meteor-autoform2 ## Basic Information - **Project Name**: meteor-autoform2 - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: devel - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-06-10 - **Last Updated**: 2024-06-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README AutoForm ========================= AutoForm is a Meteor package that adds UI components and helpers to easily create basic forms with automatic insert and update events, and automatic reactive validation. Versions 6+ of this package require that you separately install the [simpl-schema](https://github.com/aldeed/node-simple-schema) NPM package. Prior versions require and automatically install the [simple-schema](https://github.com/aldeed/meteor-simple-schema) Meteor package. You can optionally use it with the [collection2](https://github.com/aldeed/meteor-collection2) package, which you have to add to your app yourself.  [](https://www.repostatus.org/#active) [](https://standardjs.com)   ## NOTE: AutoForm 7.0 AutoForm 7.0 is now available and decouples from the default themes. **You will have to install themes manually!** Be sure to check out the [change log](./CHANGELOG.md#700) for full details, first. Note that if you use add-on packages that haven't been updated yet, you will not yet be able to update to version 6. **Add-on Package Authors**: Please test your package against AutoForm 7.0, and then release a major version update in which you change your `api.use` to `api.use('aldeed:autoform@7.0.0');`. We do NOT recommend using something like `api.use('aldeed:autoform@6.0.0 || 7.0.0');` to try to support multiple major versions of AutoForm because there is currently a known Meteor issue where trying to support too many dependency paths leads to running out of memory when trying to resolve dependencies. ## Table of Contents **Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* - [Installation](#installation) - [Migration from 6.x](#migration-from-6x) - [Import using static imports](#import-using-static-imports) - [Import using dynamic imports](#import-using-dynamic-imports) - [Community Add-On Packages](#community-add-on-packages) - [Custom Input Types](#custom-input-types) - [Themes](#themes) - [Admin Panels](#admin-panels) - [Content Management Systems](#content-management-systems) - [Components](#components) - [Other](#other) - [Demo](#demo) - [Example](#example) - [A Basic Insert Form](#a-basic-insert-form) - [A Basic Update Form](#a-basic-update-form) - [A Custom Insert Form](#a-custom-insert-form) - [Another Custom Insert Form](#another-custom-insert-form) - [Component and Helper Reference](#component-and-helper-reference) - [autoForm](#autoform) - [quickForm](#quickform) - [afFieldInput](#affieldinput) - [afFieldMessage](#affieldmessage) - [afFieldIsInvalid](#affieldisinvalid) - [afFormGroup](#afformgroup) - [afQuickField](#afquickfield) - [afQuickField Examples](#afquickfield-examples) - [afFieldValue](#affieldvalue) - [afFieldValueIs and afFieldValueContains](#affieldvalueis-and-affieldvaluecontains) - [afFieldNames](#affieldnames) - [afQuickFields](#afquickfields) - [Objects and Arrays](#objects-and-arrays) - [afObjectField](#afobjectfield) - [afArrayField](#afarrayfield) - [afEachArrayItem](#afeacharrayitem) - [afArrayFieldIsFirstVisible and afArrayFieldIsLastVisible](#afarrayfieldisfirstvisible-and-afarrayfieldislastvisible) - [Form Types](#form-types) - [insert](#insert) - [update](#update) - [update-pushArray](#update-pusharray) - [method](#method) - [method-update](#method-update) - [normal](#normal) - [disabled](#disabled) - [readonly](#readonly) - [Public API](#public-api) - [Non-Collection Forms](#non-collection-forms) - [An Example Contact Form](#an-example-contact-form) - [Fine Tuning Validation](#fine-tuning-validation) - [Manual Validation](#manual-validation) - [Resetting Validation](#resetting-validation) - [The Form Document](#the-form-document) - [Getting Current Field Values](#getting-current-field-values) - [Callbacks/Hooks](#callbackshooks) - [formToDoc, formToModifier, and docToForm](#formtodoc-formtomodifier-and-doctoform) - [Putting Field Attribute Defaults in the Schema](#putting-field-attribute-defaults-in-the-schema) - [Complex Schemas](#complex-schemas) - [Dates](#dates) - [type=date](#typedate) - [type=datetime](#typedatetime) - [type=datetime-local](#typedatetime-local) - [Theme Templates](#theme-templates) - [Using a Different Template](#using-a-different-template) - [Creating a Custom Template](#creating-a-custom-template) - [Grouping Fields](#grouping-fields) - [Sticky Validation Errors](#sticky-validation-errors) - [Defining Custom Input Types](#defining-custom-input-types) - [Common Questions](#common-questions) - [Should the value of `schema` and `collection` have quotation marks around it?](#should-the-value-of-schema-and-collection-have-quotation-marks-around-it) - [Which components should I use?](#which-components-should-i-use) - [Can I reuse the same `quickForm` or `autoForm` for both inserts and updates?](#can-i-reuse-the-same-quickform-or-autoform-for-both-inserts-and-updates) - [How can I show an asterisk after the label for required fields?](#how-can-i-show-an-asterisk-after-the-label-for-required-fields) - [What are the various ways I can specify options for a select, radio group, or checkbox group?](#what-are-the-various-ways-i-can-specify-options-for-a-select-radio-group-or-checkbox-group) - [Use allowed values array from the schema as both the label and the value](#use-allowed-values-array-from-the-schema-as-both-the-label-and-the-value) - [Set options in the schema](#set-options-in-the-schema) - [Calculate options in the schema](#calculate-options-in-the-schema) - [Use a helper](#use-a-helper) - [Can I put HTML in my error messages?](#can-i-put-html-in-my-error-messages) - [Examples](#examples) - [Troubleshooting](#troubleshooting) - [Contributing](#contributing) - [Testing](#testing) - [Credits](#credits) - [License](#license) ## Installation In a Meteor app directory, enter: ``` $ meteor add aldeed:autoform ``` Also install SimpleSchema NPM package separately (AutoForm 6+): ``` $ npm i --save simpl-schema ``` And then also extend SimpleSchema to allow the `autoform` option in your schemas, if you plan to use it: ``` import SimpleSchema from 'simpl-schema'; SimpleSchema.extendOptions(['autoform']); ``` By default there is no theme included, so you will have to install a theme, too. The following themes are available and tested to work with v7: - [autoform-plain](https://github.com/Meteor-Community-Packages/meteor-autoform-themes/tree/main/plain) - [autoform-bootstrap3](https://github.com/Meteor-Community-Packages/meteor-autoform-themes/tree/main/bootstrap3) - [autoform-bootstrap4](https://github.com/Meteor-Community-Packages/meteor-autoform-themes/tree/main/bootstrap4) - [autoform-bootstrap5](https://github.com/Meteor-Community-Packages/meteor-autoform-themes/tree/main/bootstrap5) Please also consider, that `twbs:bootstrap` is depending on an outdated (and potential insecure!) Bootstrap version. Better: Use the latest Bootstrap 3.x or 4.x from NPM in favour. ### Migration from 6.x If you update to 7.0.0 you will likely encounter errors from your extension packages like ```bash While selecting package versions: error: Conflict: Constraint aldeed:autoform@6.3.0 is not satisfied by aldeed:autoform 7.0.0. Constraints on package "aldeed:autoform": * aldeed:autoform@=7.0.0 <- top level * aldeed:autoform@6.3.0 <- someone:packagename x.y.z ``` You can easily circumvent this issue by editing the package entry in `.meteor/packages` from `aldeed:autoform` to `aldeed:autoform@7.0.0!` (note the exclamation mark). This is because many extensions will not have the `7.0.0` reference in their `package.js` file, yet. However, this major version is intended to not break compatibility with extensions, that worked with `6.x`. If you encounter any runtime issues with extensions, please open an issue. ### Import using static imports If you come from a previous version and want to "keep things as they were" then this is the option you should choose. AutoForm now comes only with the core functionality added to the initial package code. In order to make the Templates available, too, you only need to put the following line into your top-level client startup code (for example *`imports/startup/client/autoform.js`*): ```javascript import 'meteor/aldeed:autoform/static' ``` That's it. The Templates are now available. ### Import using dynamic imports This package supports `dynamic-import`, which helps to reduce initial bundle size of the package from ~110 KB to ~60 KB (estimated via `bundle-visualizer`). The following example shows how to import the packages dynamically: ```javascript import 'meteor/aldeed:autoform/dynamic' AutoForm.load() .then(() => { // ... on init success code, for example set a ReactiveVar to true )) .catch(e => { // ... on error code }) ``` You can even combine this with one of the themes (if they support dynamic imports) like in the following example: ```javascript import { AutoFormThemeBootstrap4 } from 'meteor/communitypackages:autoform-bootstrap4/dynamic' import 'meteor/aldeed:autoform/dynamic' async function init () { await AutoForm.load() await AutoFormThemeBootstrap4.load() // theme is imported, you can now make the form available // you could use a reactive var that resolves to true here // or any other mechanism you like to use to reactively activate the form AutoForm.setDefaultTemplate('bootstrap4') } (function () { init() .catch(e => console.error('[autoForm]: init failed - ', e)) .then(() => console.info('[autoForm]: initialized')) })() ``` Note, that you can't use the `#autoForm` or `>quickForm` Templates before the import has not completed. You can however use a `ReactiveVar` in your Temlate to "wait" with rendering the form: ```javascript import { ReactiveVar } from 'meteor/reactive-var' import { initAutoForm } from 'meteor/aldeed:autoform/dynamic' const autoFormLoaded = new ReactiveVar() initAutoForm() .then(() => autoFormLoaded.set(true)) .catch(e => { // ... on error code }) // ... other Template code Template.myCoolForm.helpers({ loadComplete() { return autoFormLoaded.get() } }) ``` ### Community Add-On Packages *Submit a pull request to add your package to this list!* #### Custom Input Types Dates and times: * [aldeed:autoform-bs-datepicker](https://github.com/Meteor-Community-Packages/meteor-autoform-bs-datepicker) * [aldeed:autoform-bs-datetimepicker](https://github.com/Meteor-Community-Packages/meteor-autoform-bs-datetimepicker) * [miguelalarcos:afwrap-xdatetime](https://atmospherejs.com/miguelalarcos/afwrap-xdatetime) * [notorii:autoform-datetimepicker](https://atmospherejs.com/notorii/autoform-datetimepicker) * [lukemadera:autoform-pikaday](https://atmospherejs.com/lukemadera/autoform-pikaday) * [antalakas:autoform-bs-daterangepicker](https://atmospherejs.com/antalakas/autoform-bs-daterangepicker) * [drewy:autoform-datetimepicker](https://atmospherejs.com/drewy/autoform-datetimepicker) * [bookmd:autoform-time-from-now](https://atmospherejs.com/bookmd/autoform-time-from-now) * [jkutianski:autoform-datemask](https://atmospherejs.com/jkutianski/autoform-datemask) Selects: * [aldeed:autoform-select2](https://github.com/Meteor-Community-Packages/meteor-autoform-select2) * [aldeed:autoform-bs-button-group-input](https://github.com/Meteor-Community-Packages/meteor-autoform-bs-button-group-input) * [comerc:autoform-selectize](https://atmospherejs.com/comerc/autoform-selectize) * [vazco:universe-autoform-select](https://atmospherejs.com/vazco/universe-autoform-select) * [lukemadera:autoform-autocomplete](https://atmospherejs.com/lukemadera/autoform-autocomplete) * [rikonor:autoform-image-gallery](https://github.com/rikonor/meteor-autoform-image-gallery) * [newnectar:meteor-autoform-select-country-flags](https://atmospherejs.com/newnectar/meteor-autoform-select-country-flags) WYSIWYGs: * [mpowaga:autoform-summernote](https://atmospherejs.com/mpowaga/autoform-summernote) * [donchess:autoform-froala](https://atmospherejs.com/donchess/autoform-froala) * [vimes1984:autoform-textangular](https://atmospherejs.com/vimes1984/autoform-textangular) Markdowns: * [q42:autoform-markdown](https://atmospherejs.com/q42/autoform-markdown) Autocompletes: * [comerc:autoform-placecomplete](https://atmospherejs.com/comerc/autoform-placecomplete) * [miguelalarcos:afwrap-xautocomplete](https://atmospherejs.com/miguelalarcos/afwrap-xautocomplete) * [comerc:autoform-typeahead](https://atmospherejs.com/comerc/autoform-typeahead) * [lukemadera:autoform-googleplace](https://atmospherejs.com/lukemadera/autoform-googleplace) * [lukemadera:autoform-autocomplete](https://atmospherejs.com/lukemadera/autoform-autocomplete) Files: * [cfs:autoform](https://atmospherejs.com/cfs/autoform) * [yogiben:autoform-file](https://atmospherejs.com/yogiben/autoform-file) * [naxio:autoform-file](https://atmospherejs.com/naxio/autoform-file) * [elevatedevdesign:autoform-slingshot](https://github.com/ElevateDev/meteor-autoform-slingshot) * [ostrio:autoform-files](https://github.com/VeliovGroup/meteor-autoform-file) * [universe:files-blaze-ui](https://github.com/vazco/universe-files-blaze-ui) Maps: * [yogiben:autoform-map](https://atmospherejs.com/yogiben/autoform-map) Ranges/Sliders: * [muqube:autoform-nouislider](https://github.com/muqube/meteor-autoform-nouislider) Payments * [elevatedevdesign:autoform-jquery-payments](https://github.com/ElevateDev/meteor-autoform-jquery-payments) Other: * [comerc:autoform-contenteditable2](https://atmospherejs.com/comerc/autoform-contenteditable2) * [hausor:autoform-bs-minicolors](https://atmospherejs.com/hausor/autoform-bs-minicolors) * [valedaemon:autoform-materialize-tags](https://atmospherejs.com/valedaemon/autoform-materialize-tags) #### Themes * [meteoric:autoform-ionic](https://github.com/meteoric/autoform-ionic) * [fabienb4:autoform-semantic-ui](https://atmospherejs.com/fabienb4/autoform-semantic-ui) * [mozfet:autoform-materialize](https://atmospherejs.com/mozfet/autoform-materialize) * [mozfet:autoform-modals-materialize](https://atmospherejs.com/mozfet/autoform-modals-materialize) * [poetic:react-autoform-material-ui](https://atmospherejs.com/poetic/react-autoform-material-ui) #### Admin Panels * [yogiben:admin](https://atmospherejs.com/yogiben/admin) * [kaoskeya:admin](https://atmospherejs.com/kaoskeya/admin) * [vimes1984:foundation-angular-admin](https://atmospherejs.com/vimes1984/foundation-angular-admin) * [tooit:content-types](https://github.com/tooit/meteor-content-types) #### Content Management Systems * [orionjs:core](https://atmospherejs.com/orionjs) #### Components * [comerc:autoform-bs-more](https://atmospherejs.com/comerc/autoform-bs-more) * [forwarder:autoform-wizard](https://atmospherejs.com/forwarder/autoform-wizard) * [planifica:wizard](https://atmospherejs.com/planifica/wizard) * [yogiben:autoform-modals](https://atmospherejs.com/yogiben/autoform-modals) #### Other * [comerc:autoform-fixtures](https://github.com/comerc/meteor-autoform-fixtures/) * [tooit:content-types](https://atmospherejs.com/tooit/content-types) * [tooit:content-types-bootstrap3](https://atmospherejs.com/tooit/content-types-bootstrap3) ## Demo [Live](http://autoform.meteorapp.com) [Source](https://github.com/aldeed/autoform-demo) ## Example Let's say you have the following Mongo.Collection instance, with schema support provided by the collection2 package. (Adding `autoform` to your app does not add `collection2` by default so you need to run `meteor add aldeed:collection2@3.0.0` for this example to work.) ```js Books = new Mongo.Collection("books"); Books.attachSchema(new SimpleSchema({ title: { type: String, label: "Title", max: 200 }, author: { type: String, label: "Author" }, copies: { type: Number, label: "Number of copies", min: 0 }, lastCheckedOut: { type: Date, label: "Last date this book was checked out", optional: true }, summary: { type: String, label: "Brief summary", optional: true, max: 1000 } }, { tracker: Tracker })); ``` *Be sure to define proper insert security for untrusted code if you've removed the `insecure` package. Call allow/deny or use [ongoworks:security](https://atmospherejs.com/ongoworks/security).* ### A Basic Insert Form ```html {{> quickForm collection="Books" id="insertBookForm" type="insert"}} ``` That's it! This gives you: * An autogenerated form that uses the appropriate classes, depending on your theme. * Appropriate HTML5 fields for all keys in the "Books" collection schema. * A submit button that gathers the entered values and inserts them into the "Books" collection. * Form validation based on the schema attached to the "Books" collection. By default the form is validated when the user submits. If anything is invalid, the form is continually re-validated on keyup (throttled) as the user fixes the issues. * Default validation error messages that appear under the fields, and can be customized and translated. ### A Basic Update Form An update form is similar to an insert form, except you need to provide the document with the original values to be updated: ```html {{> quickForm collection="Books" doc=this id="updateBookForm" type="update"}} ``` This example uses `doc=this`, assuming that you use something like iron:router's `data` function to set the template's data context to the book document. This is a common way to do it, but you could also use a helper function that returns the document. *Be sure to define proper update security for untrusted code if you've removed the `insecure` package. Call allow/deny or use [ongoworks:security](https://atmospherejs.com/ongoworks/security).* ### A Custom Insert Form If you want to customize autogenerated forms for *all* forms, you can easily do so by writing your own templates. Refer to the templates section. However, sometimes a certain form has a complex schema or unique UI requirements, in which case you can use `autoForm` rather than `quickForm`, allowing you to define fields individually. Here's an example: ```html {{#autoForm collection="Books" id="insertBookForm" type="insert"}} {{/autoForm}} ``` In this example, we added `rows=6` to the "summary" field, which will cause it to be rendered as a `textarea` instead of a normal text input field. ### Another Custom Insert Form In the previous example of a custom insert form, we saw how `afQuickField` can be used to render a field with simple customizations. Now let's say we need to fully customize one of the fields. To do this, you can use the following more specific templates and helpers: * afFieldIsInvalid * afFieldInput * afFieldMessage Here's an example: ```html {{#autoForm collection="Books" id="insertBookForm" type="insert"}} {{/autoForm}} ``` We added a `cost` field to our form and customized it to display as an input group with add-ons. ## Component and Helper Reference NOTE: The `afDeleteButton` component that used to be part of autoform is now available as [a separate package](https://github.com/aldeed/meteor-delete-button). ### autoForm Use this component as a block instead of `