Guide for implementing and understanding the form generator web component library.
-
Version: 0.0.14
-
Authors: Ramiro Estrella Adrianna Wiącek
-
Created: 3 July, 2024
-
Update: 3 July, 2024
Follow the steps below to setup the form generator in your website:
- Place the following scripts preferably just before the closing
bodytag in the HTML<script type="module" src="https://unpkg.com/@restrella/form-generator@0.0.14/dist/form-generator/form-generator.esm.js"></script><script nomodule src="https://unpkg.com/@restrella/form-generator@0.0.14/dist/form-generator/form-generator.js"></script>
- Insert the
re-form-generatortag where you want the component to be displayed - You are good to go for adding your form schema now!
The form generator follows a JSON schema structure to add fields and configuration to the form. Here is the sample for your reference:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Form Generator</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<script
type="module"
src="https://unpkg.com/@restrella/form-generator@0.0.14/dist/form-generator/form-generator.esm.js"
></script>
<script
nomodule
src="https://unpkg.com/@restrella/form-generator@0.0.14/dist/form-generator/form-generator.js"
></script>
</head>
<body>
<re-form-generator
schema='[
{
"type": "input",
"id": "name",
"inputType": "text",
"inputName": "name",
"visible": true,
"label": "Name",
"model": "applicantName",
"readonly": false,
"disabled": false,
"placeholder": "John",
"validationType": "string",
"validations": [
{
"name": "required",
"params": [
"First name is a required field"
]
}
],
"layout": {
"row": "row1",
"cols": 6,
"group": "applicant",
"groupTitle": "Job application form"
}
},
{
"type": "input",
"id": "lastName",
"inputType": "text",
"inputName": "lastName",
"visible": true,
"label": "Last name",
"model": "applicantLastName",
"readonly": false,
"disabled": false,
"placeholder": "Doe",
"validationType": "string",
"validations": [
{
"name": "required",
"params": [
"Last name is a required field"
]
}
],
"layout": {
"row": "row1",
"cols": 6,
"group": "applicant"
}
},
{
"type": "input",
"id": "email",
"inputType": "email",
"inputName": "email",
"visible": true,
"label": "Email",
"model": "applicantEmail",
"readonly": false,
"disabled": false,
"placeholder": "john.doe@email.com",
"validationType": "string",
"validations": [
{
"name": "required",
"params": [
"Email is a required field"
]
},
{
"name": "email",
"params": [
"The email is not in the right format"
]
}
],
"layout": {
"group": "applicant"
}
},
{
"type": "select",
"id": "position",
"inputName": "position",
"visible": true,
"label": "What position are you applying for?",
"model": "apllicationPosition",
"readonly": false,
"disabled": false,
"placeholder": "Please select a position...",
"defaultValue": "",
"values": [
{
"value": 1,
"display": "Chief Executive Officer (CEO)",
"group": "Vacant positions"
},
{
"value": 2,
"display": "Chief Technology Officer (CTO)",
"group": "Vacant positions"
}
],
"validationType": "number",
"validations": [
{
"name": "required"
}
],
"layout": {
"row": "row2",
"group": "applicant",
"cols": 6
}
},
{
"type": "input",
"id": "availableDate",
"inputType": "date",
"inputName": "availableDate",
"visible": true,
"label": "Available date",
"model": "availableDate",
"readonly": false,
"disabled": false,
"validationType": "date",
"validations": [
{
"name": "required",
"params": ["Available date is required"]
},
{
"name": "max",
"params": ["2024-02-20", "You should be available before the the 20th of February"]
}
],
"layout": {
"group": "applicant",
"row": "row2",
"cols": 6
}
},
{
"type": "input",
"id": "referenceName",
"inputType": "text",
"inputName": "referenceName",
"placeholder": "Martin",
"visible": true,
"label": "First name",
"model": "referenceName",
"readonly": false,
"disabled": false,
"validationType": "string",
"validations": [
{
"name": "required"
}
],
"layout": {
"group": "reference",
"groupTitle": "Personal references",
"row": "row3",
"cols": 6
}
},
{
"type": "input",
"id": "referenceLastName",
"inputType": "text",
"inputName": "referenceLastName",
"placeholder": "Martin",
"visible": true,
"label": "Last name",
"model": "referenceLastName",
"readonly": false,
"disabled": false,
"validationType": "string",
"validations": [
{
"name": "required"
}
],
"layout": {
"group": "reference",
"row": "row3",
"cols": 6
}
}
]'
action='{
"httpMethod": "POST",
"endpoint": "ENDPOINT",
"bearerToken": "TOKEN",
"formData": "true",
"submitButtonText": "Apply now"
}'
>
</re-form-generator>
</body>
</html>
The form action is defined in a JSON schema passed through the action attribute of the form generator component.
The properties that can be defined in this object are the following:
- String
recaptchaSiteKey- In case your backend endpoint is protected using reCAPTCHA. - String
httpMethod- HTTP method of the endpoint- default: POST
- String
bearerToken- Bearer token to be used in the endpoint (if endpoint requires authorization) - Boolean
formData- The request body should be made using form-data- default: false
- String
endpoint- Endpoint where the request should be sent - String
webhoookEndpoint- Endpoint where the form events should be sent. List of events:- submit.failed
- String
formErrorMessage- Message that should be shown when the validation fails (supports HTML) - String
submitButtonText- Text the submit button should display (supports HTML) - String
successMessage- Text the displayed in success alert after form submition - String
errorMessage- Text the displayed in success alert after form submition in case of errors
An example of how this would look like:
`{ "recaptchaSiteKey": "MY_SITE_KEY", "bearerToken": "MY_BEARER_TOKEN", "formData": true, "endpoint": "MY_API_ENDPOINT", "webhoookEndpoint": "MY_WEBHOOK_ENDPOINT", "formErrorMessage": "Please fix the errors in the form before submiting", "submitButtonText": "Send form" }`
The fields are send to the api endpoint specified in the config based on the model property inside the field in the schema.
Let's say you have a simple form with fields contaning the models firstName and lastName, the form generator will generate a request body similar to the following one:
`{ "name": "FIELD_VALUE", "lastName": "FIELD_VALUE" }`
However, this will not always be the format the API will expect. The form generator offers a way to define a custom field mapping by passing an array. Following the previous example, let's say that now we want to put the name and lastName inside a person object.
This can be achieved using the following object structure:
`{ "name": ["person.name"], "lastName": ["person.lastName"] }`
It is important to mention that you can map the same field to multiple objects/object property. Here is an example:
`{ "name": ["person.name", "applicant.name"], "lastName": ["person.lastName", "person.familyName"] }`
The schema attribute is basically the core of the component. In this, you can specify all the fields, layout, and validations that your form should contain.
Further in the doumentation we will conver the different type of fields and validations you can use in the form, for now let's just see an example of how a field looks like in the schema:
`{ "type": "input", "id": "name", "inputType": "text", "inputName": "name", "visible": true, "label": "Name", "model": "applicantName", "readonly": false, "disabled": false, "placeholder": "John", "validationType": "string", "validations": [ { "name": "required", "params": [ "First name is a required field" ] } ] }`
These properties in the schema can vary based on the type and as mentioned before are going to be detailed individually. These are some of the most common properties that can be applied to the fields:
- String
type- Input field type. Accepted values:- input
- textarea
- toggle
- select
- checkboxGroup
- radioGroup
- multiSelect
- countrySelect
- file
- String
id- id selector of the field - Boolean
visible- Wether the field should be visible or not - String
label- Field label (supports HTML) - String
model- Object property name to be send to the API - Boolean
readonly- Wether the field is read only or not - Boolean
disabled- Wether the field is disabled or not - String
placeholder- Field placeholder - String
validationType- Yup validation type - Array
validations- Validations rule to apply based on Yup validation type (This is explained in Validations section)
The layout configuration is specified inside the layout property of the field in the form schema. Here is an example:
`{ // Other field properties "layout": { "row": "row1", // Row where it should be displayed, "cols": 6, // Number of columns to display (from 1 to 12), "group": "applicant", // If the field is part of a group (Optional) "groupTitle": "Applicant details" // Title of the group (Optional) } }`
Examples about how to implement some commonly used validations from Yup in the JSON schema. These validations must be implemented in the schema using a combination of String validationType and Array validations properties.
Examples about string validationType from Yup
Validation
Implementation
string.required(message?: string | function): Schema
`{ "validationType": "string", "validations": [ { "name": "required", "params": [ "This is a required field" ] } ] }`
string.nullable(message?: string | function): Schema
`{ "validationType": "string", "validations": [ { "name": "nullable", "params": [ ] } ] }`
string.length(limit: number | Ref, message?: string | function): Schema
`{ "validationType": "string", "validations": [ { "name": "length", "params": [ 15, "The string should be exactly ${length} characters" ] } ] }`
string.min(limit: number | Ref, message?: string | function): Schema
`{ "validationType": "string", "validations": [ { "name": "min", "params": [ 10, "The string should contain minimum ${min} characters" ] } ] }`
string.max(limit: number | Ref, message?: string | function): Schema
`{ "validationType": "string", "validations": [ { "name": "max", "params": [ 20, "The string should contain maximum ${max} characters" ] } ] }`
string.matches(regex: RegExp, message?: string | function): Schema
`{ "validationType": "string", "validations": [ { "name": "matches", "params": [ "^[a-zA-Z0-9]*$", // Regex pattern "The string should match the required pattern" ] } ] }`
string.matches(regex: RegExp, options: { message: string, excludeEmptyString: bool }): Schema
`{ "validationType": "string", "validations": [ { "name": "matches", "params": [ "^[a-zA-Z0-9]*$", // Regex pattern { "message": "The string should match the required pattern", "excludeEmptyString": true } ] } ] }`
string.email(message?: string | function): Schema
`{ "validationType": "string", "validations": [ { "name": "email", "params": [ "The string should be a valid email address" ] } ] }`
string.url(message?: string | function): Schema
`{ "validationType": "string", "validations": [ { "name": "url", "params": [ "The string should be a valid URL" ] } ] }`
string.uuid(message?: string | function): Schema
`{ "validationType": "string", "validations": [ { "name": "uuid", "params": [ "The string should be a valid UUID" ] } ] }`
string.datetime(options?: {message?: string | function, allowOffset?: boolean, precision?: number})
`{ "validationType": "string", "validations": [ { "name": "datetime", "params": [ { "message": "The string should be a valid datetime", "allowOffset": true, "precision": 3 } ] } ] }`
string.datetime(message?: string | function)
`{ "validationType": "string", "validations": [ { "name": "datetime", "params": [ "The string should be a valid datetime" ] } ] }`
string.ensure(): Schema
`{ "validationType": "string", "validations": [ { "name": "ensure", "params": [] } ] }`
string.trim(message?: string | function): Schema
`{ "validationType": "string", "validations": [ { "name": "trim", "params": [ "The string should not have leading or trailing whitespace" ] } ] }`
string.lowercase(message?: string | function): Schema
`{ "validationType": "string", "validations": [ { "name": "lowercase", "params": [ "The string should be in lowercase" ] } ] }`
string.uppercase(message?: string | function): Schema
`{ "validationType": "string", "validations": [ { "name": "uppercase", "params": [ "The string should be in uppercase" ] } ] }`
Examples about number validationType from Yup
Validation
Implementation
number.min(limit: number | Ref, message?: string | function): Schema
`{ "validationType": "number", "validations": [ { "name": "min", "params": [ 5, "The number should be at least ${min}" ] } ] }`
number.max(limit: number | Ref, message?: string | function): Schema
`{ "validationType": "number", "validations": [ { "name": "max", "params": [ 100, "The number should be at most ${max}" ] } ] }`
number.lessThan(max: number | Ref, message?: string | function): Schema
`{ "validationType": "number", "validations": [ { "name": "lessThan", "params": [ 50, "The number should be less than ${less}" ] } ] }`
number.moreThan(min: number | Ref, message?: string | function): Schema
`{ "validationType": "number", "validations": [ { "name": "moreThan", "params": [ 10, "The number should be more than ${more}" ] } ] }`
number.nullable(message?: string | function): Schema
`{ "validationType": "number", "validations": [ { "name": "nullable", "params": [] } ] }`
number.positive(message?: string | function): Schema
`{ "validationType": "number", "validations": [ { "name": "positive", "params": [ "The number should be positive" ] } ] }`
number.negative(message?: string | function): Schema
`{ "validationType": "number", "validations": [ { "name": "negative", "params": [ "The number should be negative" ] } ] }`
number.integer(message?: string | function): Schema
`{ "validationType": "number", "validations": [ { "name": "integer", "params": [ "The number should be an integer" ] } ] }`
number.truncate(): Schema
`{ "validationType": "number", "validations": [ { "name": "truncate", "params": [] } ] }`
number.round(type: 'floor' | 'ceil' | 'trunc' | 'round' = 'round'): Schema
`{ "validationType": "number", "validations": [ { "name": "round", "params": [ "round" ] } ] }`
Examples about date validationType from Yup
Validation
Implementation
date.min(limit: Date | string | Ref, message?: string | function): Schema
`{ "validationType": "date", "validations": [ { "name": "min", "params": [ "2023-01-01", // Date limit "The date should be later than ${min}" ] } ] }`
date.max(limit: Date | string | Ref, message?: string | function): Schema
`{ "validationType": "date", "validations": [ { "name": "max", "params": [ "2024-01-01", // Date limit "The date should be earlier than ${max}" ] } ] }`
Examples about array validationType from Yup
Validation
Implementation
array.json(): this
`{ "validationType": "array", "validations": [ { "name": "json", "params": [] } ] }`
array.length(length: number | Ref, message?: string | function): this
`{ "validationType": "array", "validations": [ { "name": "length", "params": [ 5, "The array should contain exactly ${length} items" ] } ] }`
array.min(limit: number | Ref, message?: string | function): this
`{ "validationType": "array", "validations": [ { "name": "min", "params": [ 2, "The array should contain at least ${min} items" ] } ] }`
array.max(limit: number | Ref, message?: string | function): this
`{ "validationType": "array", "validations": [ { "name": "max", "params": [ 10, "The array should contain at most ${max} items" ] } ] }`
array.ensure(): this
`{ "validationType": "array", "validations": [ { "name": "ensure", "params": [] } ] }`
array.compact(rejector: (value) => boolean): Schema
`{ "validationType": "array", "validations": [ { "name": "compact", "params": [ "function(value) { return value === null; }" ] } ] }`
Examples about mixed validationType from Yup
Validation
Implementation
mixed.required(message?: string | function): Schema
`{ "validationType": "mixed", "validations": [ { "name": "required", "params": [ "This field is required" ] } ] }`
mixed.oneOf(arrayOfValues: Array, message?: string | function): Schema
`{ "validationType": "mixed", "validations": [ { "name": "oneOf", "params": [ [1, 2, 3], // Example array of valid values "The value must be one of ${values}" ] } ] }`
mixed.notOneOf(arrayOfValues: Array, message?: string | function): Schema
`{ "validationType": "mixed", "validations": [ { "name": "notOneOf", "params": [ [1, 2, 3], // Example array of invalid values "The value must not be one of ${values}" ] } ] }`
mixed.equals(arrayOfValues: Array, message?: string | function): Schema
`{ "validationType": "mixed", "validations": [ { "name": "equals", "params": [ [1, 2, 3], // Example array of equal values "The value must be equal to one of ${values}" ] } ] }`
mixed.notEquals(arrayOfValues: Array, message?: string | function): Schema
`{ "validationType": "mixed", "validations": [ { "name": "notEquals", "params": [ [1, 2, 3], // Example array of not equal values "The value must not be equal to one of ${values}" ] } ] }`
mixed.default(value: any): Schema
`{ "validationType": "mixed", "validations": [ { "name": "default", "params": [ "default value" ] } ] }`
mixed.nullable(isNullable?: boolean): Schema
`{ "validationType": "mixed", "validations": [ { "name": "nullable", "params": [ true // Allows the value to be null ] } ] }`
Form schema allows following components to be generated:
- Input
- Checkbox group
- Country select
- File drag and drop
- Multiselect
- Radio group
- Select
- Textarea
- Toggle
Input field allow following inputType values in the form schema:
If you want to specify any attirbutte that given input type supports natively you can do it in the schema using attributtes property. For example, if you want an inputType week to have the attibutes min and max, you can do it as follow:
{
// Other field properties
"inputType": "week",
"attributes": {
"min": "2024-W1",
"max": "2024-W10"
}
}
<re-form-generator
schema='[{
"type": "input",
"id": "checkbox-field",
"inputType": "checkbox",
"inputName": "checkbox-name",
"visible": "true",
"label": "Checkbox field",
"model": "checkboxField"
}]'>
</re-form-generator>
<re-form-generator
schema='[{
"type": "input",
"id": "color-field",
"inputType": "color",
"inputName": "color-name",
"visible": "true",
"label": "Color field",
"model": "colorField"
"defaultValue": "#FFC0CB"
}]'>
</re-form-generator>
<re-form-generator
schema='[{
"type": "input",
"id": "date-field",
"inputType": "date",
"inputName": "date-name",
"visible": "true",
"label": "Date field",
"model": "dateField"
}]'>
</re-form-generator>
<re-form-generator
schema='[{
"type": "input",
"id": "datetime-local-field",
"inputType": "datetime-local",
"inputName": "datetime-local-name",
"visible": "true",
"label": "Datetime-local field",
"model": "datetime-localField"
}]'>
</re-form-generator>
<re-form-generator
schema='[{
"type": "input",
"id": "email-field",
"inputType": "email",
"inputName": "email-name",
"visible": "true",
"label": "Email field",
"model": "emailField",
"placeholder": "example@example.com"
}]'>
</re-form-generator>
<re-form-generator
schema='[{
"type": "input",
"id": "month-field",
"inputType": "month",
"inputName": "month-name",
"visible": "true",
"label": "Month field",
"model": "monthField"
}]'>
</re-form-generator>
<re-form-generator
schema='[{
"type": "input",
"id": "number-field",
"inputType": "number",
"inputName": "number-name",
"visible": "true",
"label": "<h1>I also support HTML</h1>",
"model": "numberField",
"defaultValue": 69
}]'>
</re-form-generator>
<re-form-generator
schema='[{
"type": "input",
"id": "password-field",
"inputType": "password",
"inputName": "password-name",
"visible": "true",
"label": "Password field",
"model": "passwordField"
}]'>
</re-form-generator>
<re-form-generator
schema='[{
"type": "input",
"id": "range-field",
"inputType": "range",
"inputName": "range-name",
"visible": "true",
"label": "Range field",
"model": "rangeField",
"attributes": {
"min": 0,
"max": 100,
"step": 10
},
"defaultValue": 50
}]'>
</re-form-generator>
<re-form-generator
schema='[{
"type": "input",
"id": "phone-field",
"inputType": "tel",
"inputName": "phone-name",
"visible": "true",
"label": "Phone field",
"model": "phoneField",
"attributes": {
"pattern":"[0-9]{3}-[0-9]{3}-[0-9]{4}"
}
}]'>
</re-form-generator>
<re-form-generator
schema='[{
"type": "input",
"id": "text-field",
"inputType": "text",
"inputName": "text-name",
"visible": "true",
"label": "Text field",
"model": "textField",
"defaultValue": "This is a disabled and readonly field",
"readonly": true,
"disabled": true
}]'>
</re-form-generator>
<re-form-generator
schema='[{
"type": "input",
"id": "time-field",
"inputType": "time",
"inputName": "time-name",
"visible": "true",
"label": "Time field",
"model": "timeField"
}]'>
</re-form-generator>
<re-form-generator
schema='[{
"type": "input",
"id": "url-field",
"inputType": "url",
"inputName": "url-name",
"visible": "true",
"label": "Url field",
"model": "urlField"
}]'>
</re-form-generator>
<re-form-generator
schema='[{
"type": "input",
"id": "week-field",
"inputType": "week",
"inputName": "week-name",
"visible": "true",
"label": "Week field",
"model": "weekField"
}]'>
</re-form-generator>
Checkbox group is an input field that allows multiple items selection from pre-defined selection options.
Available radio buttons can be defined in the items property.
When it comes to the default values, they can defined with the checked property in the attributes array. For instance:
{
// Other field properties
"items": [
{
"label": "Checkbox option 1",
"value": "check-option-1",
"attributes": {
"checked": true
}
},
{
"label": "Checkbox option 2",
"value": "check-option-2",
"attributes": {
"checked": true
}
},
{
"label": "Checkbox option 3",
"value": "check-option-3"
}
]
}
<re-form-generator
schema='[{
"type": "checkboxGroup",
"inputType": "object",
"id": "checkbox-group",
"inputName": "checkbox-group",
"visible": true,
"label": "Checkbox Group",
"model": "checkboxOptions",
"items": [
{
"label": "Checkbox option 1",
"value": "check-option-1",
"attributes": {
"checked": true
}
},
{
"label": "Checkbox option 2",
"value": "check-option-2",
"attributes": {
"checked": true
}
},
{
"label": "Checkbox option 3",
"value": "check-option-3"
}
]
}]'>
</re-form-generator>
Country select field allow selecting country or dial code. Countries are searchable by their names and dial codes. The modelValueKey property defines which value is selected: name, dialCode or code. The inputDisplayKey property is resposible for the value that is displayed after country selection. To specify defaultValue use lowercase country ISO code, for example, "defaultValue": "dk".
<re-form-generator
schema='[{
"type": "countrySelect",
"id": "country",
"inputName": "country",
"visible": true,
"label": "Country",
"model": "country",
"modelValueKey": "code",
"placeholder": "Select country",
"layout": {
"row": "row1",
"cols": 6
}
}]'>
</re-form-generator>
<re-form-generator
schema='[{
"type": "countrySelect",
"id": "dial_code",
"inputName": "dial_code",
"visible": true,
"label": "Dial code",
"model": "dial_code",
"defaultValue": "dk",
"modelValueKey": "dialCode",
"inputDisplayKey": "dialCode",
"showDialCode": true,
"placeholder": "Select dial code",
"layout": {
"row": "row1",
"cols": 4
}
}]'>
</re-form-generator>
File drag and dropdown input field let the user choose one or more files from their device storage. On default single file selection is allowed. To enable multiple file selection or to control allowed file types, specify the attributes property. For instance:
{
// Other field properties
"attributes": {
"multiple": true,
"accept": "image/*,.pdf"
}
}
Text displayed in the dropdown zone can be changed by defining textTitle, subTitle and placeholder properties.
{
{
// Other field properties
"textTitle": "Custom title",
"subTitle": "Custom subtitle",
"placeholder": "Placeholder"
}
}
<re-form-generator
schema='[{
"type": "file",
"inputType": "file",
"label": "Documents",
"id": "documents",
"inputName": "documents",
"visible": "true",
"model": "documents"
}]'>
</re-form-generator>
<re-form-generator
schema='[{
"type": "file",
"inputType": "file",
"label": "Documents",
"id": "documents",
"inputName": "documents",
"visible": "true",
"model": "documents",
"textTitle": "Custom title",
"subTitle": "Custom subtitle",
"placeholder": "Placeholder",
"attributes": {
"multiple": true,
"accept": "image/*,.pdf"
}
}]'>
</re-form-generator>
Multiselect is an input field that allows multiple items to be selected. Available selection options should be defined in the values property. For instance:
{
// Other field properties
"values": [
{
"value": 1,
"display": "Option 1",
"group": "options"
},
{
"value": 2,
"display": "Option 2",
"group": "options"
},
{
"value": 3,
"display": "Option 3",
"group": "options"
}
]
}
When it comes to the default values, they are controlled through defaultOptions, specifing indices of values that should be pre-selected. For example:
{
// Other field properties
"defaultOptions": [0, 1]
}
<re-form-generator
schema='[{
"type": "multiSelect",
"id": "multiselect",
"inputName": "options",
"inputType": "number",
"visible": true,
"label": "Multiselect",
"model": "options",
"placeholder": "Select options",
"values": [
{
"value": 1,
"display": "Option 1",
"group": "options"
},
{
"value": 2,
"display": "Option 2",
"group": "options"
},
{
"value": 3,
"display": "Option 3",
"group": "options"
}
]
}]'>
</re-form-generator>
Radio group is an input field that allows single value selection from pre-defined radio buttons. Selecting any radio button automatically deselects any other currently-selected radio button.
Available radio buttons can be defined in the items property.
When it comes to the default value, it is defined with the checked property in the attributes array. For instance:
{
// Other field properties
"items": [
{
"label": "Radio 1",
"value": "radio-1"
},
{
"label": "Radio 2",
"value": "radio-2",
"attributes": {
"checked": true
}
},
{
"label": "Radio 3",
"value": "radio-3"
}
]
}
<re-form-generator
schema='[{
"type": "radioGroup",
"inputType": "radio",
"id": "radio-group",
"inputName": "radio-group",
"visible": true,
"label": "Radio Group",
"model": "radioOption",
"items": [
{
"label": "Radio 1",
"value": "radio-1"
},
{
"label": "Radio 2",
"value": "radio-2",
"attributes": {
"checked": true
}
},
{
"label": "Radio 3",
"value": "radio-3"
}
]
}]'>
</re-form-generator>
Select is an input field that allows an item to be selected out of pre-defined options. Available selection options should be defined in the values property. Each value object should be described by following attributes: value, display and group. For instance:
{
// Other field properties
"values": [
{
"value": "one",
"display": "Option 1",
"group": "options"
},
{
"value": "two",
"display": "Option 2",
"group": "options"
},
{
"value": "three",
"display": "Option 3",
"group": "options"
}
]
}
When it comes to the default value, it is controlled through defaultValue, specifing of value property of the option that should be pre-selected. For example:
{
// Other field properties
"defaultValue": "one"
}
<re-form-generator
schema='[{
"type": "select",
"id": "select",
"inputName": "options",
"visible": true,
"label": "Select",
"model": "selectOption",
"readonly": false,
"disabled": false,
"placeholder": "Please select an option...",
"defaultValue": "two",
"values": [
{
"value": "one",
"display": "Option 1",
"group": "Options"
},
{
"value": "two",
"display": "Option 2",
"group": "Options"
},
{
"value": "three",
"display": "Option 3",
"group": "Options"
}
]
}]'>
</re-form-generator>
Textarea is an input field that allows for multi-line text.
Textarea attributes like maxlength or rows can be deffined in the attributes property in a following way:
`{ // Other field properties "attributes": { "maxlength": 20, "rows": 2 } }`
<re-form-generator
schema='[{
"type": "textarea",
"id": "long-text",
"inputName": "long-text",
"visible": true,
"label": "Textarea",
"model": "longText",
"readonly": false,
"disabled": false,
"placeholder": "Please feed me with some text...",
"attributes": {
"maxlength": 20,
"rows": 2
}
}]'>
</re-form-generator>
The toggle input is used to choose one of two values.
The inputType and validationType should be defined as boolean.
{
// Other field properties
"inputType": "boolean",
"validationType": "boolean"
}
<re-form-generator
schema='[{
"type": "toggle",
"id": "toggle-input",
"inputType": "boolean",
"inputName": "is-on",
"visible": true,
"label": "Do you want subscribe?",
"model": "isOn",
"validationType": "boolean",
"defaultValue": true,
"attributes": {
"value": true
}
}]'>
</re-form-generator>
Name
Description
Code Example
submitted
Event emitted when the form is submitted. When form action is not defined, event will emit all form values, otherwise, if action is defined, the response of the request will be passed as an argument of the callback.
<script>
const formGenerator = document.querySelector('re-form-generator');
formGenerator.addEventListener('submitted', event => {
console.log(event.detail);
});
</script>
validationError
In the submit process when there are errors this event is emitted.
<script>
const formGenerator = document.querySelector('re-form-generator');
formGenerator.addEventListener('validationError', event => {
console.log(event.detail);
});
</script>
valueChanged
Event is emitted every time when form input data changes.
<script>
const formGenerator = document.querySelector('re-form-generator');
formGenerator.addEventListener('valueChanged', event => {
console.log(event.detail);
});
</script>
Name
Description
Code Example
updateValue
Updates the value of the model.
<script>
const formGenerator = document.querySelector('re-form-generator');
formGenerator.addEventListener('valueChanged', event => {
const field = event.detail;
const { birthday } = field;
if (birthday) {
const parts = birthday.split('-');
const [year, month, date] = parts;
formGenerator.updateValue('year', year);
formGenerator.updateValue('month', month);
formGenerator.updateValue('date', date);
}
});
</script>
submit
It will submit the form with its values and will trigger the submitted event.
<script>
const formGenerator = document.querySelector('re-form-generator');
formGenerator.submit();
</script>
validate
Validates the form. In case of errors, the validationError event will be emitted.
<script>
const formGenerator = document.querySelector('re-form-generator');
formGenerator.validate();
</script>
You can overwrite default input fields style. For example:
`.input__label { font-size: 20px !important; color: blue; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; } .submit-container__button { background-color: blue !important; }`
.input__description {
color: #6c757d;
font-size: 13px;
margin: 0;
}
.re-form-generator {
width: calc(100% - 40px);
border: 1px solid #000 3b;
padding: 20px;
border-radius: 20px;
background: #fff;
/* Rounded sliders */
}
.re-form-generator .select-input {
position: relative;
appearance: none;
-webkit-appearance: none;
width: 100%;
font-size: 14px;
height: 44px;
padding: 0.675em 6em 0.675em 1em;
background-color: #fff;
border: 1px solid #caced1;
border-radius: 0.25rem;
color: #000;
cursor: pointer;
}
.re-form-generator .select-input::after, .re-form-generator .select-input::before {
content: "";
position: absolute;
right: 1rem;
pointer-events: none;
}
.re-form-generator .select-input::before {
border-left: 0.3rem solid transparent;
border-right: 0.3rem solid transparent;
border-bottom: 0.3rem solid black;
top: 40%;
}
.re-form-generator .select-input::after {
border-left: 0.3rem solid transparent;
border-right: 0.3rem solid transparent;
border-top: 0.3rem solid black;
top: 55%;
}
.re-form-generator .group-title {
font-size: 24px;
padding-bottom: 6px;
margin-bottom: 20px;
border-bottom: 1px solid #cbd5e1;
}
.re-form-generator textarea {
resize: none;
height: 90px;
font-size: 14px;
line-height: 17px;
color: #252733;
background: #fafafa;
padding: 12px;
border: 1px solid #e3e8eb;
border-radius: 5px;
width: 100%;
font-size: 14px;
color: #252733;
box-sizing: border-box;
font-family: inherit;
}
.re-form-generator .input-text, .re-form-generator .input-email, .re-form-generator .input-date, .re-form-generator .input-number, .re-form-generator .select-input {
background: #fafafa;
padding: 12px;
border: 1px solid #e3e8eb;
border-radius: 5px;
width: 100%;
font-size: 14px;
color: #252733;
box-sizing: border-box;
font-family: inherit;
height: 43px;
}
.re-form-generator .input-text.input-checkbox, .re-form-generator .input-email.input-checkbox, .re-form-generator .input-date.input-checkbox, .re-form-generator .input-number.input-checkbox, .re-form-generator .select-input.input-checkbox {
height: 18px;
width: 18px;
background-color: #eee;
margin: 0;
}
.re-form-generator .row-container {
display: flex;
gap: 10px;
flex-grow: 12;
}
@media (max-width: 768px) {
.re-form-generator .row-container {
display: block;
}
}
.re-form-generator .row-container .col-1 {
width: calc((100% / 12) * 1);
}
.re-form-generator .row-container .col-2 {
width: calc((100% / 12) * 2);
}
.re-form-generator .row-container .col-3 {
width: calc((100% / 12) * 3);
}
.re-form-generator .row-container .col-4 {
width: calc((100% / 12) * 4);
}
.re-form-generator .row-container .col-5 {
width: calc((100% / 12) * 5);
}
.re-form-generator .row-container .col-6 {
width: calc((100% / 12) * 6);
}
.re-form-generator .row-container .col-7 {
width: calc((100% / 12) * 7);
}
.re-form-generator .row-container .col-8 {
width: calc((100% / 12) * 8);
}
.re-form-generator .row-container .col-9 {
width: calc((100% / 12) * 9);
}
.re-form-generator .row-container .col-10 {
width: calc((100% / 12) * 10);
}
.re-form-generator .row-container .col-11 {
width: calc((100% / 12) * 11);
}
.re-form-generator .row-container .col-12 {
width: calc((100% / 12) * 12);
}
@media (max-width: 768px) {
.re-form-generator .row-container .col-1 {
width: 100%;
}
.re-form-generator .row-container .col-2 {
width: 100%;
}
.re-form-generator .row-container .col-3 {
width: 100%;
}
.re-form-generator .row-container .col-4 {
width: 100%;
}
.re-form-generator .row-container .col-5 {
width: 100%;
}
.re-form-generator .row-container .col-6 {
width: 100%;
}
.re-form-generator .row-container .col-7 {
width: 100%;
}
.re-form-generator .row-container .col-8 {
width: 100%;
}
.re-form-generator .row-container .col-9 {
width: 100%;
}
.re-form-generator .row-container .col-10 {
width: 100%;
}
.re-form-generator .row-container .col-11 {
width: 100%;
}
.re-form-generator .row-container .col-12 {
width: 100%;
}
}
.re-form-generator .input__label {
font-weight: 700;
font-size: 14px;
line-height: 20px;
margin-bottom: 12px;
display: inline-block;
}
.re-form-generator .error-message {
font-size: 12px;
color: #ff6868;
}
.re-form-generator .switch {
position: relative;
display: inline-block;
width: 45px;
height: 25px;
}
.re-form-generator .switch input {
opacity: 0;
width: 0;
height: 0;
}
.re-form-generator .slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #83888f;
transition: 0.4s;
transition: 0.4s;
}
.re-form-generator .slider:before {
position: absolute;
content: "";
height: 21px;
width: 21px;
left: 2px;
bottom: 2px;
background-color: white;
transition: 0.4s;
transition: 0.4s;
}
.re-form-generator input:checked + .slider {
background-color: #2196f3;
}
.re-form-generator input:checked + .slider:before {
transform: translateX(20px);
}
.re-form-generator input:focus + .slider {
box-shadow: 0 0 1px #2196f3;
}
.re-form-generator .slider.round {
border-radius: 34px;
}
.re-form-generator .slider.round:before {
border-radius: 50%;
}
.re-form-generator .input-group {
position: relative;
display: flex;
flex-direction: column;
padding: 0 0 16px 0;
font-weight: 700;
font-size: 14px;
line-height: 20px;
}
.re-form-generator .input-group.hasErrors input, .re-form-generator .input-group.hasErrors .multi-select, .re-form-generator .input-group.hasErrors .select-input {
border: 1.5px solid #ff6868;
border-radius: 5px;
}
.re-form-generator .input-group.hasErrors .file-field-container {
border: 1.5px solid #ff6868;
border-radius: 5px;
}
.re-form-generator .input-group.input-checkbox-container {
display: flex;
flex-direction: row-reverse;
align-items: center;
justify-content: start;
gap: 0.5rem;
}
.re-form-generator .input-group.input-checkbox-container .input__label {
margin-bottom: 0px;
margin-left: 6px;
font-weight: normal;
}
.re-form-generator .input-group.input-checkbox-container .error-message {
flex-basis: 100%;
position: absolute;
bottom: 0px;
}
.re-form-generator .input-group.input-checkbox-container.hasErrors {
margin-bottom: 16px;
}
.re-form-generator .input-group.input-checkboxGroup-container .checkboxGroup .label {
margin-bottom: 0px;
margin-left: 6px;
font-weight: normal;
}
.re-form-generator .input-group.two-columns {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.re-form-generator .submit-container {
display: flex;
margin-top: 16px;
}
.re-form-generator .submit-container__button {
padding: 10px 20px;
font-size: 16px;
border: none;
border-radius: 5px;
background-color: #2196f3;
color: #fff;
cursor: pointer;
transition: background-color 0.3s ease;
width: 100%;
}
.re-form-generator .submit-container__button:hover {
background-color: #1565c0;
}
.re-form-generator .radioGroup {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.re-form-generator .radioGroup-element {
display: flex;
flex-direction: row;
gap: 0.5rem;
align-items: center;
}
.re-form-generator .radioGroup-element .label {
font-weight: normal;
}
.re-form-generator .radioGroup .input-radio {
padding: 2px;
margin: 0;
}
.re-form-generator .hidden {
display: none;
}
.re-form-generator .form-error-message {
display: flex;
justify-content: center;
align-items: center;
}
.re-form-generator .form-error-message__message {
color: #ff6868;
font-size: 12px;
font-weight: 700;
}
`re-file-input-field .file-field-container { width: 100%; display: flex; } re-file-input-field .file-field-container .file-dropzone { width: 100%; height: 16rem; border: 1px dashed #e3e8eb; border-radius: 5px; background-color: #fafafa; cursor: pointer; display: flex; flex-direction: column; align-items: center; justify-content: center; transition: background-color 0.3s, border-color 0.3s; } re-file-input-field .file-field-container .file-dropzone.hover { background-color: #e5e7eb; border-color: #9ca3af; } re-file-input-field .file-field-container .file-dropzone.hover .dropzone-icon, re-file-input-field .file-field-container .file-dropzone.hover .dropzone-text, re-file-input-field .file-field-container .file-dropzone.hover .dropzone-subtext { color: #252733; } re-file-input-field .file-field-container .file-dropzone:hover { background-color: #f9fafb; } re-file-input-field .file-field-container .file-dropzone:hover .dropzone-icon { color: #9ca3af; } re-file-input-field .file-field-container .file-dropzone:hover .dropzone-text, re-file-input-field .file-field-container .file-dropzone:hover .dropzone-subtext { color: #6b7280; } re-file-input-field .file-field-container .file-dropzone.dark { background-color: #374151; border-color: #4b5563; } re-file-input-field .file-field-container .file-dropzone.dark:hover { background-color: #4b5563; border-color: #6b7280; } re-file-input-field .file-field-container .file-dropzone.dark .dropzone-icon, re-file-input-field .file-field-container .file-dropzone.dark .dropzone-text, re-file-input-field .file-field-container .file-dropzone.dark .dropzone-subtext { color: #9ca3af; } re-file-input-field .file-field-container .file-dropzone .dropzone-content { display: flex; flex-direction: column; align-items: center; justify-content: center; padding-top: 1.25rem; padding-bottom: 1.5rem; font-weight: normal; } re-file-input-field .file-field-container .file-dropzone .dropzone-icon { width: 2rem; height: 2rem; margin-bottom: 1rem; color: #6b7280; transition: color 0.3s; } re-file-input-field .file-field-container .file-dropzone .dropzone-text { margin-bottom: 0.5rem; color: #6b7280; transition: color 0.3s; display: flex; gap: 8px; flex-direction: column; align-items: center; justify-content: center; } re-file-input-field .file-field-container .file-dropzone .dropzone-text .file-element { display: flex; gap: 8px; color: #252733; } re-file-input-field .file-field-container .file-dropzone .font-bold { font-weight: bold; } re-file-input-field .file-field-container .file-dropzone .dropzone-subtext { font-size: 0.8rem; color: #6b7280; transition: color 0.3s; } re-file-input-field .file-field-container .file-dropzone .remove-file { width: 20px; height: 20px; border-radius: 50%; background-color: #ff6868; color: white; text-align: center; line-height: 20px; font-size: 14px; font-weight: bold; } re-file-input-field .file-field-container .file-dropzone .file-name { font-weight: bold; max-width: 250px; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; }`
re-multi-select .multi-select {
position: relative;
width: 100%;
background: #fafafa;
font-weight: normal;
}
re-multi-select .multi-select__header {
padding: 10px;
border: 1px solid #e3e8eb;
cursor: pointer;
display: flex;
justify-content: space-between;
border-radius: 5px;
}
re-multi-select .multi-select__header.disabled {
pointer-events: none;
background-color: #ddd;
}
re-multi-select .multi-select__header .selected_options {
display: flex;
justify-content: row;
flex-wrap: wrap;
gap: 0.5rem;
}
re-multi-select .multi-select__header .selected_options__option {
background-color: #2196f3;
border-radius: 5px;
color: #fff;
padding: 0rem 0.5rem;
font-size: 11px;
font-weight: 400;
display: flex;
justify-content: space-between;
align-items: center;
gap: 0.5rem;
}
re-multi-select .multi-select__header .selected_options__option-close {
padding: 0 0.25rem;
}
re-multi-select .multi-select__options {
position: absolute;
width: calc(100% - 2px);
border: 1px solid #e3e8eb;
border-top: none;
max-height: 150px;
overflow-y: auto;
background: #fff;
z-index: 1;
margin: 0;
padding: 0;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
}
re-multi-select .multi-select__option {
padding: 10px;
cursor: pointer;
}
re-multi-select .multi-select__option.selected {
background-color: #f0f0f0;
}
re-multi-select .multi-select__option:not(.selected):hover {
background-color: #2196f3;
color: #fff;
}
re-multi-select .multi-select__option:last-of-type {
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
}
re-multi-select .multi-select .arrow-up::before {
content: '▲';
}
re-multi-select .multi-select .arrow-down::before {
content: '▼';
}
re-multi-select .multi-select .arrow {
font-size: 0.63rem;
padding: 0 0.25rem;
}
`re-form-generator re-country-select .country-select-input-wrapper { position: relative; width: 100%; height: 43px; } re-form-generator re-country-select .country-select-input-wrapper .dropdown-container { position: absolute; width: 100%; max-height: 300px; background: #fff; } re-form-generator re-country-select .country-select-input-wrapper .dropdown-container::-webkit-scrollbar { display: none; } re-form-generator re-country-select .country-select-input-wrapper .dropdown-container .selected-country-wrapper { position: relative; font-size: 14px; font-weight: normal; width: 100%; height: 100%; pointer-events: none; display: block; } re-form-generator re-country-select .country-select-input-wrapper .dropdown-container .selected-country-wrapper .selected-flag { transform: translateY(-50%) scale(0.8); width: 24px; position: absolute; left: 10px; top: 20px; display: block; } re-form-generator re-country-select .country-select-input-wrapper .dropdown-container .selected-country-wrapper .selected-country-value { position: absolute; top: 11px; left: 40px; overflow: hidden; text-overflow: ellipsis; width: -webkit-fill-available; text-wrap: nowrap; margin-right: 5px; display: block; } re-form-generator re-country-select .country-select-input-wrapper .dropdown-container .selected-country-wrapper.hidden { display: none; } re-form-generator re-country-select .country-select-input-wrapper .country-search { width: 100%; box-sizing: border-box; border: 1px solid #e3e8eb; padding: 10px; text-indent: 26px; border-radius: 5px; height: 43px; font-family: unset; text-indent: 26px; background: #fafafa; } re-form-generator re-country-select .country-select-input-wrapper .country-search input::placeholder { font-family: unset; } re-form-generator re-country-select .country-select-input-wrapper .country-search.no-indent { text-indent: 0px; } re-form-generator re-country-select .country-select-input-wrapper input::placeholder { font-family: 'Times-Roman'; } re-form-generator re-country-select .country-select-input-wrapper .dropdown { position: absolute; top: 40px; width: 100%; border: 1px solid #e3e8eb; background-color: white; overflow-y: auto; display: none; } re-form-generator re-country-select .country-select-input-wrapper .dropdown-item { padding: 10px; cursor: pointer; border: 0.5px solid #e3e8eb; border-top: 0px; background: #fff; font-weight: normal; } re-form-generator re-country-select .country-select-input-wrapper .dropdown-item:last-of-type { border-bottom: 0px; } re-form-generator re-country-select .country-select-input-wrapper .dropdown-item:hover { background: #f0f0f0; } re-form-generator re-country-select .country-select-input-wrapper .flag { width: 20px; height: 15px; margin-right: 10px; } re-form-generator re-country-select .country-select-input-wrapper .country-select-dropdown-wrapper { overflow-y: scroll; max-height: 200px; border-bottom: 1px solid #e3e8eb; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; } re-form-generator re-country-select .country-select-input-wrapper .country-select-dropdown-wrapper::-webkit-scrollbar { display: none; }`
See what's new added, changed, fixed, improved or updated in the latest versions.
Copyright © 2020 iDocs. All Rights Reserved.
Design & Develop by HarnishDesign.