# Form generator

It's a web component for creating forms from a JSON file based on the JSON schema.
The output format is also a JSON file.


## Getting Started

* Install with ```npm i ns-schema-form``` 

	and add it to your framework ([StencilJs Doc](https://stenciljs.com/docs/overview)) 

	or set ```<script src="PATH/TO/YOUR/SCRIPT/ns-schema-form.js></script>``` into your index.html

* Install reneco-fonts with bower
```bower install git@github.com:NaturalSolutions/RenecoFonts.git```

* Call 
	```<ns-schema-form></ns-schema-form>``` to use this component

* Set your params

## Configure params

JSON params must be like that:
```
{"form": {
	"items": [
		{ INSERT YOUR ITEMS HERE
        }],
        "i18next": { 
          	"lng": "fr",
          	"resources": {
            	"fr": {
              		"labels": {
                		INSERT YOUR LABELS TRANSLATION HERE
                	}
            	},
            	"validationErrors": {
	                INSERT YOUR VALIDATION ERRORS HERE
              	}
            }
        },
        "model": {
          ADD YOUR MODEL HERE
        },
        "validation": {
          ADD VALIDATION FIELDS HERE
        }
    },
    "framework": "INSERT FRAMEWORK POSSIBLE CHOICES",
    "config":{
    	INSERT CONFIGURATION HERE
    } 
}
```

You can choose ionic framework for display field:
```"framework": "ionic"```
write at the same level of "form". By default, there is no framework but you can choose class of each field (see __Options list by type field__ below).

Some config options are available:

*	```"domain": "http://YOUR_DOMAIN/"``` to choose the domain of your request (Ex: localhost)
*	```"thesaurus-icon": "YOUR CLASS ICON"``` or ```"position-icon": "YOUR CLASS ICON"``` to change displayed icon.

## Options list by type field

Each type must have 2 required arguments:

* "key" : string (name of the field)
* "type" : string (type of the field)

"classNames" field is not supported by Ionic
There are different required and optional arguments according to type field:


**Columns**

|                  Required                 | Optional |
|:-----------------------------------------:|:--------:|
| "type": "cols"                            | "classNames": string (add class to field)         |
| "key": string ("name\_of\_cols")          |          |
| 											|          |
| "cols" : table of objects                 |          |

**Text**

|              Required             |                     Optional                    |
|:---------------------------------:|:-----------------------------------------------:|
| "type": "text"                    | "nolabel": boolean (true if no label displayed) |
| "key": string ("name\_of\_field") | "placeholder": string                           |
|                                   | "disabled": boolean                             |
|                                   | "classNames": string (add class to field)       |

**Email**

|              Required             |                     Optional                    |
|:---------------------------------:|:-----------------------------------------------:|
| "type": "email"                   | "nolabel": boolean (true if no label displayed) |
| "key": string ("name\_of\_field") | "placeholder": string                           |
|                                   | "disabled": boolean                             |
|                                   | "classNames": string (add class to field)       |

**Number**

|              Required             |                     Optional                    |
|:---------------------------------:|:-----------------------------------------------:|
| "type": "number"                  | "nolabel": boolean (true if no label displayed) |
| "key": string ("name\_of\_field") | "placeholder": string                           |
|                                   | "max": integer (maximum value)                  |
|                                   | "min": integer (minimum value)                  |
|                                   | "classNames": string (add class to field)       |

**Date**

|              Required             |                     Optional                    |
|:---------------------------------:|:-----------------------------------------------:|
| "type": "date"                    | "nolabel": boolean (true if no label displayed) |
| "key": string ("name\_of\_field") | "placeholder": string                           |
|                                   | "display-format": string (Ex: "DD/MM/YYYY")     |
|                                   | "classNames": string (add class to field)       |

**Textarea**

|              Required             |                     Optional                    |
|:---------------------------------:|:-----------------------------------------------:|
| "type": "textarea"                | "nolabel": boolean (true if no label displayed) |
| "key": string ("name\_of\_field") | "placeholder": string                           |
|                                   | "autogrow": boolean -- for ionic framework                             |
|                                   | "cols": integer (number of columns) -- for ionic framework          |
|                                   | "rows": integer (number of rows) -- for ionic framework               |
|                                   | "classNames": string (add class to field)       |

**Checkbox**

|              Required             |                        Optional                       |
|:---------------------------------:|:-----------------------------------------------------:|
| "type": "checkbox"                | "nolabel": boolean (true if no label displayed)       |
| "key": string ("name\_of\_field") |                                    |
|                                   | "color": string (primary,secondary,danger,light,dark -- for ionic framework) |
|                                   | "disabled": boolean                                   |
|                                   | "indeterminate": boolean -- for ionic framework                             |
|                                   | "classNames": string (add class to field)       |

**Dropdown**

|              Required             |                                      Optional                                     |
|:---------------------------------:|:---------------------------------------------------------------------------------:|
| "type": "dropdown"                | "operators": table (list of select-options. Can be string, objects, integer, ...) |
| "key": string ("name\_of\_field") | "nolabel": boolean (true if no label displayed)                                   |
|                                   | "interface": string (action-sheet, alert, popover)                                |
|                                   | "multiple": boolean                                                               |
|                                   | "placeholder": string                                                             |
|                                   | "disabled": boolean                                                               |
|                                   | "classNames": string (add class to field)       |

**Thesaurus field**

|              Required             |                     Optional                     |
|:---------------------------------:|:------------------------------------------------:|
| "type": "thesaurus"               | "startNodeId" : integer (node to start the tree) |
| "key": string ("name\_of\_field") | "lng" : string (choice are "en" or "fr")         |
|                                   | "deprecated": boolean                            |

**Position field**

|              Required             |                     Optional                     |
|:---------------------------------:|:------------------------------------------------:|
| "type": "position"                | "startNodeId" : integer (node to start the tree) |
| "key": string ("name\_of\_field") | "lng" : string (choice are "en" or "fr")         |
|                                   | "deprecated": boolean                            |

##Example

```json
{"form": {
	"items": [{
		"key": "colonne generale",
		"type": "cols",
		"classNames": "d-flex",
		"cols": [{
			"key": "colonne de gauche",
			"classNames": "col-12",
			"type": "cols",
			"cols": [{
				"key": "dropdown",
				"type": "dropdown",
				"options": {
					"operators": ["a", "b", "c", "d", "e"]
				}
			},{
				"key": "email",
				"type": "email"
			},{
				"key": "checkbox",
				"type": "checkbox"
			},{
				"key": "thesaurus",
				"type": "thesaurus",
				"options": {
					"startNodeId": 167920
				}
			},{
				"key": "sous colonne de gauche",
				"type": "cols",
				"cols": [{
					"classNames": "col-7",
					"key": "id",
					"type": "dropdown",
					"options": {
						"operators": [{"value":"=", "label":"operators.="}, {"value":"<>", "label":"operators.<>"}]
					}
				},{
					"classNames": "col-5",
					"key": "id_text",
					"type": "text",
					"nolabel": true
				}]
			}]
		}]
		}, 
		{
			"key": "OK",
			"type": "submit"
		}
	]
},
	"i18next": {
		"lng": "fr",
		"resources": {
			"fr": {
				"labels": {
					"dropdown": "Menu déroulant",
					"translations_items": {
						"lang": "Langue",
						"title": "Title"
					}
				},
				"operators": {
					"=": "Eq",
					"<>": "Different"
				},
				"validationErrors": {
					"minLength": "Veuillez saisir au moins {{count}} caractères.",
					"maxLength": "Ne dois pas dépasser {{count}} caractères.",
					"email": "Veuillez saisir un email valide.",
					"required": "Ce champ est requis"
				}
			}
		}
	},
	"model": {
		"translations": [
			{
				"lang": "fr",
				"title": "bonjour"
			}, {
				"lang": "en",
				"title": "hello"
			}
		]
	},
	"validation": {
		"type": "object",
		"required": ["thesaurus"],
		"properties": {
			"thesaurus":{
				"type": "string",
				"thesaurusValidator": 167920
			},
			"email": {
				"type" : "string",
				"if": {
					"minLength": 1
				},
				"then": {
					"format": "email"
				},
				"else": {
					"minLength": 0
				}
			},
			"translations": {
				"type": "array",
				"items": {
					"type": "object",
					"properties": {
						"lang": {
							"type": "string",
							"minLength": 2,
							"maxLength": 2
						}
					}
				}
			}
		}
	},
	"config":{
		"domain": "localhost/"
	}
}
```

## Filter component
The filter component will generate a filter form given an input config. 

### Component instanciation
The component is instanciated as follows 
```html
<ns-schema-filter
	domain = "the domain to use (for position and thesaurus)"
	config = "your config"
/>
<ns-schema-filter>
```
where config is a **json** of the form 

```json
{
	"fieldName" : {
		"type" : "<type>",
		"additionalProp" : "additional prop for the given type"
	},
	"anotherField" : {
		"type" : "<type>",
		"additionalProp" : "additional prop for the given type"
	},
	"..." : {}
}
```
* **fieldName** : the name of your field
* **type** : the type of the field. Available types are 
  * number
  * string
  * date
  * dateInterval
  * booleanOptions (List of possible values for a field)
  * thesaurus
  * position

* **additionalProp** : can be the following depending on the type
  * thesaurus :
    * startNodeID
    * deprecated
    * lng
	* position :
    * startNodeID
    * deprecated
		* lng
			
### Example

```html
<ns-schema-filter
	domain='http://localhost/' 
	config='{
		"stringField": {
			"type" : "string"
		},
		"numberField" : {
			"type" : "number"
		},
		"thesaurusField": {
			"type" : "thesaurus",
			"startNodeID": 167920,
			"lng" : "en"
		},
		"dateField" : {
			"type" : "date"
		},
		"dateIntervalField" : {
			"type" : "dateInterval"
		},
		"positionField" : {
			"type" : "position",
			"startNodeID" : 1,
			"lng" : "en"
		},
		"optionsField": {
			"type" : "booleanOptions",
			"options" : ["option1", "option2","option3", "option4","option5", "option6","option7", "option8"]
		}
	}'>
</ns-schema-filter>
```

