1.1.9-brain • Published 6 years ago

gmst-forms v1.1.9-brain

Weekly downloads
-
License
ISC
Repository
-
Last release
6 years ago

GMST Forms

Overview

GMST Forms (<gmst-form>) is a WebComponent library built using the tools provided by the gmwc toolkit. The library contains components that without configuration, can create a working form, and can be extended to add any custom functionality needed. By default all forms will be accessibility compliant.

Building a form starts with including a gmst-form element on the page and nesting form fields like gmst-form-input with some attributes underneath. All form fields have functionality to translate labels, error messages and placeholders (soon). Some form fields also include a way to perform multiple field level validations at a time.

In the future, functionality will be added to allow for forms to be built purely off of a configuration object or a simple markup language based on the components themselves.

Components

Form (gmst-form)

<gmst-form>
    <div slot="form">
        ...
    </div>
    <div slot="after-submission">
        ...
    </div>
</gmst-form>

The form component is a wrapper component for a form built using the library. The component provides a few different ways to handle form submission and blocks submissions altogether if there are any validation errors.

There are two useable slots in the gmst-form component. form is used to place all form elements into, and after-submission is an area to place content that will be displayed after a submission is successful. Usually the after-submission slot will be used for a thank you page/message.

Ways to Handle Submissions (WIP)

  • Form submissions can be done using the default form submission. (This will be an attribute that is passed through)
  • Write a window.handleFormSubmit function that recieves form data and submits it in some way.
  • Extend the GMSTForm component and overwrite the default handleSubmit() method.

Form Element (GMSTFormElement)

GMSTFormElement is the "base component class", meaning all of the form field elements are extended from it. GMSTFormElement provides a lot of the base functionality incluing validations, hide/show, rendering and more.

Each element that is extended off of GMSTFormElement will start similarly. Below is the gmst-form-input component, which is a good place to start from.

// Import GMSTFormElement from wherever it is located
import { GMSTFormElement } from '../gmst-form-element/gmst-form-element';

export class GMSTFormInput extends GMSTFormElement {
    constructor(self) {
        self = super(self);
        // Components extended off of GMSTFormElement begin with a configuration.
        self.configuration = {
            // These three key/values are needed for the element to render properly.
            // `fieldType` is the HTML Element type of the field (e.g. input, select)
            fieldType: 'input',
            // `labelElementType` is the HTML Element type of the label (e.g. label, legend)
            labelElementType: 'label',
            // The template name is the HTML template used for the custom element in camelcase.
            templateName: 'gmstFormInput', // The actual file name is `gmst-form-input.html`
            // When validation is necessary for a form field validation happens on the event specified
            // in `validateOnEvent` and validation errors are cleared when the configured `clearValidationOnEvent` is fired.
            clearValidationOnEvent: 'input',
            validateOnEvent: 'blur'
        };

        return self;
    }
}

Checkbox (gmst-form-checkbox)

<gmst-form-checkbox
    name="optIn"
    element-id="optInEmail"
    label="optIn"
    value="optIn"
    business-rules='[{
                "effect": "unCheckField",
                "event": "click",
               "fieldIds": ["fieldID"]
            }]'>
</gmst-form-checkbox>

The checkbox component creates an HTML structure with an i18n label and a checkbox. (Validation soon). Added Business Rule will uncheck Field with given ID

Input (gmst-form-input)

<gmst-form-input
    type="text"
    name="firstName"
    element-id="firstName"
    label="firstName"
    placeholder="i18nLabel"
    validations="required,otherValidation">
</gmst-form-input>

The input component creates an HTML structure with an i18n label, an input and space for validation messages to be displayed. The field is validated each time the input element fires an onblur event and displays an error message when necessary.

Google Address Autocomplete (gmst-form-google-address)

    <gmst-form-google-address
        autocomplete-elements='{
            "street_number": "address",
            "route": "address",
            "locality": "city",
            "administrative_area_level_1": "province",
            "postal_code": "postalCode"
        }'
        type="text"
        name="salesLead.address.address"
        element-id="address"
        label="address"
        validations="required">

gmst-form-google-address is a component extended from gmst-form-input to provide Google address autocomplete functionality to a form.

Specific to gmst-form-google-address is the autocomplete-elements attribute that is used to fill in address information into other form elements. The value for this attribute is a JSON formatted Javascript object where each key is a portion of an address provided by Google and the value is the element-id of a form element to fill the information into. If multiple keys share an element-id the information is appended.

Radio (gmst-form-radio)

<gmst-form-radio
    options='[{"value": "email", "label": "email"}, {"value": "phone", "label": "phone"}]' name="preferredContact"
    title="preferredContact">
</gmst-form-radio>

The radio component creates an HTML structure for a radio button fieldset with a label. Options are passed in as a JSON structured array, each radio button contains an i18n label.

Select (gmst-form-select)

<gmst-form-select
    options='[{"value": "Request for Information", "label": "ownershipExperience"}, {"value": "Service", "label": "serviceExperience", "selected": true}]'
    element-id="questionType"
    name="questionType"
    label="questionType">
</gmst-form-select>

The select component creates an HTML structure for a select with a label. The select options are passed in as a JSON structured array, where each select has an i18n label, one option can be preselelected.

Additional functionality can be found in the section on field attributes.

Text Area (gmst-form-text-area)

<gmst-form-text-area
    element-id="comments"
    label="comments"
    placeholder="i18nLabel">
</gmst-form-text-area>

The select component creates an HTML structure for a textarea with a label.

Component Attributes

The following component attributes are used on all components (except gmst-form) unless specified otherwise.

element-id

The element-id attribute is used to add a unique id to a form field (e.g. select, input). A for attribute is also added to that form element's corresponding label.

element-id is also used to select the form custom elements as well. This can be necessary when adding functionality that requires a references to other custom elements.

label

The label attribute is used to add a label to a form field. The value is the key to the string you want in the current I18n collection of labels.

name

The name attribute is used to provide a name to a form field, this is used during submission.

options

The options attribute is used on components that have multiple items to choose from. options is currently only used with gmst-form-radio and gmst-form-select. The value of options is a JSON array of objects, each individual option has a few different values to use.

In gmst-form-radio, each object is an individual radio button.

In gmst-form-select, each object is an individual select option.

Options for options

Each object should contain a value and a label.

Optionally an option can be preselected by providing "selected": true

Specific to gmst-form-select

Currently there are a few features specific to gmst-form-select.

hideFields/showFields - A JSON array of fields (a component's `element-id) to be hidden/shown on select.

addFieldValidations/removeFieldValidations - A JSON array of objects used to add and remove field validations on select. Each object contains an elementId and an array of validations.

validations

The validations attribute is used to set validations for a form element. If a field is hidden all validations will be disabled.

The value expected is a comma separated list of validations. This can include validations provided in this library or extended validations.

value

The value attribute is used to add a preset value can be passed into a few different form elements. This is particularly useful for hidden gmst-form-inputs.

Extending Base Functionality

export class CustomGMFormInput extends GMFormInput {
    ...
    extendedFunctionality() {
        ...
    }
    ...
}

Each component includes an extendedFunctionality() method that is ran at the end of a components render() method.

A few components include methods like addInputEventListener() where the default validation logic is added, these can be overwritten as well.

Validation

// required - returns 'Required' when value is empty
// testValue - returns 'Must be "Test"' when the value is not 'Test'

let value = '';
let validationResult = validate(['required', 'testValue'], value);
// -> 'Required'

let value = 'T';
let validationResult = validate(['required', 'testValue'], value);
// -> 'Must be "Test"'

let value = 'Test';
let validationResult = validate(['required', 'testValue'], value);
// -> undefined

Included in the library is a simple way of doing form validations for single form field. A comma separated list of validations are passed in as an attribute on custom elements like gmst-form-input and ran after a specific event is triggered.

Extending Validations

Each validation follows the same structure, return an error message when there is an error, otherwise return undefined.

Below is an example of extending validation functionality.

import { validate, allValidations } from 'gmst-forms'

const newValidation = (value) => value === 'New' ? undefined : 'Must be "New"';

allValidations.newValidation = newValidation;

validate(['newValidation'], 'New'); // returns undefined;

Utilities

There are a few utilities provided by the library that can be used to extend the functionality of the form.

  • getFormData(element) - Given an element will return the nearest form element's data. The output provided is the same as jQuery's serializeArray().
  • ...

Translations

There are a few places where components allow for translations using the gmwc-i18n library:

  • Form field - Each form field has a label attribute where a translation key is provided.
  • When a form field has an options attribute there is a label key in each object where a translation key is provided.
  • Validation Errors - Each validation rule will return a translation key or a string.

Future Features and Ideas

Optional HTML Options

Currently on components that have multiple field options, like gmst-form-select only accept an array of objects in JSON format. In the future it might be a good idea to make writing JSON optional and stick to HTML markup. To do this each option will be a child element of the component.

Example

<gmst-form-select ...>
    <gmst-form-option
    value="Example Option"
    label="exampleLabel">
    </gmst-form-option>
</gmst-form-select>

Configuraton Based Form

Currently Global Forms is able to build out a fully functioning form based off of a large configuration object. This library can be extended to match current Global Forms functionality and even improve it. To do this a configuration tool will be created that allows for creation of complex forms that can be imported by the gmst-form component.

Given a configuration object gmst-form will render a form based on the configuration without any additional steps.

Form Markup

As an alternative to generating a configuration object, since these are custom elements, it is possible that a form can be built purely from some HTML markup passed onto a page. Form configurations can be hosted externally and can be pulled onto the page using DataProvider (or other tools) and rendered using all of the elements provided by the library.

Examples

Contact Form

This is the form included in index.html.

<gm-form>
    <div slot="form" class="gm-form">
        <gmst-form-select 
            options='[{"value": "Request for Information", "label": "ownershipExperience"}, {"value": "Service", "label": "serviceExperience", "selected": true}]' 
            element-id="questionType" 
            name="questionType"
            label="questionType"></gmst-form-select>
        <gmst-form-input type="text" name="firstName" element-id="firstName" label="firstName"></gmst-form-input>
        <gmst-form-input type="text" name="lastName" element-id="lastName" label="lastName" validations="required,testValue"></gmst-form-input>
        <gmst-form-input type="text" name="postalCode" element-id="postalCode" label="postalCode"></gmst-form-input>
        <!-- <gmst-postalcode class="container-fluid"></gmst-postalcode> -->
        <gmst-form-input type="email" name="emailAddress" element-id="emailAddress" label="emailAddress"></gmst-form-input>
        <gmst-form-input type="tel" name="phoneNumber" element-id="phoneNumber" label="phoneNumber"></gmst-form-input>
        <gmst-form-input type="text" name="vin" element-id="vin" label="vin"></gmst-form-input>
        <gmst-form-input type="text" name="model" element-id="model" label="model"></gmst-form-input>
        <gmst-form-input type="text" name="comments" element-id="comments" label="comments"></gmst-form-input>
        <gmst-form-radio options='[{"value": "email", "label": "email"}, {"value": "phone", "label": "phone"}]' name="preferredContact" title="preferredContact"></gmst-form-radio>
        <gmst-form-text-area element-id="comments" label="comments"></gmst-form-text-area>
        <gmst-form-checkbox name="optIn" id="optInEmail" label="optIn" value="optIn"></gmst-form-checkbox>
        <button type="submit">Submit</button>
    </div>
</gm-form>

Contact Us Form