npm package: @sixdeex/jaf
Description: Just Another Form: a webcomponent to build forms using json schema
Author: Riccardo Pasquini
Latest version: 1.0.6

# Just Another Form

## Description

Render a simple form starting from an embedded or referenced schema.
The form supports client side internationalization and client, and server, side errors.

See

* examples/index.html
* examples/login.html
* examples/style.html

for examples and 

* docs/jaf-definition.schema.json

for the overall schema.

## Usage

It is possible to import the webcomponent using 

```bash
npm i --save @sixdeex/jaf
```
```javascript
import { JafForm } from '@sixdeex/jaf'
```

which make the element <jaf-form> available.

Using CDN (not really, TODO, but I would like to replace the gitlab wiki file):

```html

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <title>Hello Jaf component</title>
  <script src="https://gitlab.com/morphy76/jaf/-/wikis/uploads/f91ecbd7ea6d0517590751db3c3ea3d8/jaf.js"></script>
</head>

<body>
  <div class="form">
    <jaf-form id="loginForm" title="Sign In" src="/form-definition.json"></jaf-form>
  </div>
</body>

</html>
```

## Definition schema

### Form schema

See docs/form.schema.json

### Validation schema

See docs/validate.schema.json

### Initial values schema

Part of docs/jaf-definition.schema.json

### Errors schema

See docs/errors.schema.json

### Internationalization schema

See docs/labels.schema.json

## How validation works

Fields with validation rules provide client side validation; the rules are:

* required, the value cannot be null or undefined, blank strings are allowed;
* not_blank, like required but not allowing blank values;
* is_digit, the field value must be made of digits;
* min, like is_digit but the value must be greater than a given minimum;
* max, like is_digit but the value must be lesser than a given maximum;
* is_date, the field value is a date;
* regex, the field value must match a given regular expression;
* is_email, like regex with a preconfigured regular expression to check emails.

Validation happens when the definition _validate_ element is provided; oherwise, rules in the definition _schema_ element are just for rendering purposes.

```json
{
  "schema": {
    "field1": {
      "type": "text",
      "required": true # used for rendering rules of the field
    }
  },
  "validate": {
    "field1": {
      "not_blank": "Field one is mandatory" # used for client side validation
    }
  }
}
```

## How internationalization works

Translations are provided in the definition _labels_ element, if the translation is not found, the key is printed as is.

Translation keys can be provided for every textual content.


```json
{
  "schema": {
    "field1": {
      "type": "text",
      "title": "Field one", # printed as is because no key is matched in the labels
      "required": true
    }
  },
  "validate": {
    "field1": {
      "not_blank": "field.one.mandatory" # a key is matched, hence this value is translated
    }
  },
  "labels": {
    "default": "en",
    "translations": {
      "en": {
        "field.one.mandatory": "Field one is mandatory"
      },
      "en": {
        "field.one.mandatory": "Field one è obbligatorio"
      }
    }
  }
}
```

## Events

### on-submit

Catch the custom event `on-submit` which holds the form values in the `detail` attribute, e.g.:

```javascript
document.getElementById('myJafForm').addEventListener('on-submit', onSubmitEvent => console.log(onSubmitEvent.detail));
```

## API

### addErrors

Inject a JSON object defined by the error schema in order to provide server side state about fields and errors; e.g.:

```javascript
document.getElementById('loginForm').addErrors({
  form_messages: 'Login failed',
  values: onSubmitEvent.detail,
  messages: {
    username: 'Not found'
  }
});
```

## Theming

Theming is acieved defining CSS variables in the document using the Jaf Form.

### Form CSS variables

<pre>--jaf-font-family</pre>
> default `Sans-Serif`
<pre>--jaf-form-direction</pre>
> default `column`
<pre>--jaf-form-wrap</pre>
> default `nowrap`
<pre>--jaf-form-grow</pre>
> default `1`
<pre>--jaf-form-shrink</pre>
> default `0`
<pre>--jaf-form-justify-items</pre>
> default `flex-start`
<pre>--jaf-form-align-items</pre>
> default `stretch`
<pre>--jaf-form-border</pre>
> default `none`
<pre>--jaf-form-margin</pre>
> default `0px`
<pre>--jaf-form-padding</pre>
> default `0px`
<pre>--jaf-title-font-family</pre>
> default `--jaf-font-family`
<pre>--jaf-title-font-size</pre>
> default `1em`
<pre>--jaf-title-align</pre>
> default `center`
<pre>--jaf-title-font-weight</pre>
> default `bold`
<pre>--jaf-button-margin</pre>
> default `10px`
<pre>--jaf-button-margin-left</pre>
> default `--jaf-button-margin`
<pre>--jaf-button-margin-right</pre>
> default `--jaf-button-margin`
<pre>--jaf-button-margin-top</pre>
> default `--jaf-button-margin`

### Form component variables

<pre>--jaf-group-margin-bottom</pre>
> default `5px`
<pre>--jaf-label-font-family</pre>
> default `--jaf-font-family`
<pre>--jaf-label-font-size</pre>
> default `.75em`
<pre>--jaf-control-font-family</pre>
> default `--jaf-font-family`
<pre>--jaf-control-font-size</pre>
> default `1em`
<pre>--jaf-control-margin-top</pre>
> default `1px`
<pre>--jaf-control-margin-right</pre>
> default `1px`
<pre>--jaf-control-margin-bottom</pre>
> default `0px`
<pre>--jaf-control-margin-left</pre>
> default `0px`

### Form controls

<pre>--jaf-button-font-size</pre>
> default `.75em`
<pre>--jaf-control-border</pre>
> default `1px solid darkgray`
<pre>--jaf-control-border-radius</pre>
> default `0px`
<pre>--jaf-control-border-top-left-radius</pre>
> default `--jaf-control-border-radius`
<pre>--jaf-control-border-top-right-radius</pre>
> default `--jaf-control-border-radius`
<pre>--jaf-control-border-bottom-left-radius</pre>
> default `--jaf-control-border-radius`
<pre>--jaf-control-border-bottom-right-radius</pre>
> default `--jaf-control-border-radius`

### Errors

<pre>--jaf-error-background-color</pre>
> default `yellow`
<pre>--jaf-error-main-color</pre>
> default `black`
<pre>--jaf-error-notification-color</pre>
> default `red`