<commit_before>About
-----

Build reactive forms:

* *in minutes*.
* *for production use*.
* *with reusable custom components*.
* *that work the way they should*.

Validation is handled using [SimpleSchemas](https://github.com/aldeed/meteor-simple-schema)--however, these are not required.

This package provides you with two **template factories** that take simple templates that you create and turn them into robust form components. Components can be used alone, but their real power comes from being used together.

Install
-------

`meteor add templates:forms`

This package works on the client-side only.

Usage
-----

### Getting Started

**1. Provide a schema and an action function using a parent template's helpers**.

```javascript
Template['testForm'].helpers({
  schema: function () {
    return new SimpleSchema({
      testField: {
        type: String,
        max: 3,
        instructions: "Enter a value!"
      }
    });
  },
  action: function () {
    return function (els, callbacks) {
      console.log("[forms] Action running!");
      console.log("[forms] Form data!", this);
      console.log("[forms] Form elements!", els);
      console.log("[forms] Callbacks!", callbacks);
      callbacks.success();
    };
  }
});
```

The **action function** runs when the form is submitted. It takes two params, as shown above:
* `els`
  * This contains any elements in the form block with class `.reactive-element`.
  * You'll likely serialize this and save it to the database.
  * You can also use this to clear each element's value after the form has successfully been submitted.
* `callbacks`
  * This contains two methods to trigger the form's state.
  * Running `callbacks.success()` --> Sets `success`.
  * Running `callbacks.failed()`  --> Sets `failed`.
  * The form's `{{loading}}` state (see below) will run from the time you submit to the time you call one of these.

Also, all validated form values are available with no extra work from `this`:

```javascript
// Inside the action function...
console.log(this); // Returns {testField: "xxx"}
```

Data from elements passed into the action function is **guaranteed to be valid**, considering:
* You provided an adequate schema.
* You used ReactiveForms elements.
* You specified the correct schema field for each element (see `basicInput` in the next example).

Hopefully, this satisfies your needs.

**2. Add the ReactiveForms form block and elements to the parent template**.

```handlebars
<!-- Wrapped input with form-wide schema -->
<template name="testForm">
  {{#basicForm schema=schema action=action}}
    {{> basicInput field='testField'}}
  {{/basicForm}}
</template>
```

**3. Register the form block and elements with ReactiveForms**.

This is where you can specify how the form gets submitted, and how the element gets validated.

```javascript
ReactiveForms.createForm({
  template: 'basicForm',
  submitType: 'normal'
});

ReactiveForms.createElement({
  template: 'basicInput',
  validationEvent: 'keyup',
  validationValue: function (el, clean, template) {
    return clean(el.value);
  }
});
```

The `basicForm` and `basicInput` templates are **included** with this package.

See `templates:forms.html`.

### API

ReactiveForms has only two API endpoints.

Add any custom template that satisfies the basic requirements (outlined below), and you're
ready to go!

#### ReactiveForms.createElement

Create a ReactiveForms element from a compatible template.<commit_msg>specify about registering form blocks and elements<commit_after>About
-----

Build reactive forms:

* *in minutes*.
* *for production use*.
* *with reusable custom components*.
* *that work the way they should*.

Validation is handled using [SimpleSchemas](https://github.com/aldeed/meteor-simple-schema)--however, these are not required.

This package provides you with two **template factories** that take simple templates that you create and turn them into robust form components. Components can be used alone, but their real power comes from being used together.

Install
-------

`meteor add templates:forms`

This package works on the client-side only.

Usage
-----

### Getting Started

**1. Provide a schema and an action function using a parent template's helpers**.

```javascript
Template['testForm'].helpers({
  schema: function () {
    return new SimpleSchema({
      testField: {
        type: String,
        max: 3,
        instructions: "Enter a value!"
      }
    });
  },
  action: function () {
    return function (els, callbacks) {
      console.log("[forms] Action running!");
      console.log("[forms] Form data!", this);
      console.log("[forms] Form elements!", els);
      console.log("[forms] Callbacks!", callbacks);
      callbacks.success();
    };
  }
});
```

The **action function** runs when the form is submitted. It takes two params, as shown above:
* `els`
  * This contains any elements in the form block with class `.reactive-element`.
  * You'll likely serialize this and save it to the database.
  * You can also use this to clear each element's value after the form has successfully been submitted.
* `callbacks`
  * This contains two methods to trigger the form's state.
  * Running `callbacks.success()` --> Sets `success`.
  * Running `callbacks.failed()`  --> Sets `failed`.
  * The form's `{{loading}}` state (see below) will run from the time you submit to the time you call one of these.

Also, all validated form values are available with no extra work from `this`:

```javascript
// Inside the action function...
console.log(this); // Returns {testField: "xxx"}
```

Data from elements passed into the action function is **guaranteed to be valid**, considering:
* You provided an adequate schema.
* You used ReactiveForms elements.
* You specified the correct schema field for each element (see `basicInput` in the next example).

Hopefully, this satisfies your needs.

**2. Add the ReactiveForms form block and elements to the parent template**.

```handlebars
<!-- Wrapped input with form-wide schema -->
<template name="testForm">
  {{#basicForm schema=schema action=action}}
    {{> basicInput field='testField'}}
  {{/basicForm}}
</template>
```

**3. Register the form block and elements with ReactiveForms**.

This is where you can specify how the form gets submitted, and how the element gets validated.

```javascript
ReactiveForms.createForm({
  template: 'basicForm',
  submitType: 'normal'
});

ReactiveForms.createElement({
  template: 'basicInput',
  validationEvent: 'keyup',
  validationValue: function (el, clean, template) {
    return clean(el.value);
  }
});
```

The `basicForm` and `basicInput` templates are **included** with this package, however you still need to **register** them.

See `templates:forms.html` to see the code.

You only need to register a given form block or element template once--each time it's rendered, it will have a unique context. For elements, they'll always be connected to the instance of the form block that contains them.

### API

ReactiveForms has only two API endpoints.

Add any custom template that satisfies the basic requirements (outlined below), and you're
ready to go!

#### ReactiveForms.createElement

Create a ReactiveForms element from a compatible template.
{'fraction_non_alphanumeric': 0.11302787744962738, 'fraction_numerical': 0.0011040574109853713, 'mean_word_length': 3.9603011635865846, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 15, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1385775', 'n_tokens_mistral': 1971, 'n_tokens_neox': 1917, 'n_words': 858}