npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

coherent-gameface-form-control

v3.1.0

Published

A component for Coherent Labs Gameface.

Downloads

16

Readme

The gameface-form-control is part of the Gameface custom components suite. As most of the components in this suite, it uses slots to allow dynamic content.

Installation

npm i coherent-gameface-form-control

Usage with UMD:

<script src="./node_modules/coherent-gameface-form-control/dist/form-control.production.min.js"></script>

This is all! Load the file in Gameface to see the gameface-form-control.

<gameface-form-control></gameface-form-control>

Usage with JavaScript:

If you wish to import the GamefaceFormControl using JavaScript you can replace the script tag with import statements like this:

import { GamefaceFormControl } from 'coherent-gameface-form-control';

or simply

import 'coherent-gameface-form-control';

Note that this approach requires a module bundler like Webpack or Rollup to resolve the modules from the node_modules folder.

Form control attributes

| Attribute | Required | Values | Default value | Usage | | --------- | -------- | ------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | method | Yes | GET, POST | GET | Used to specify the HTTP method that will be used to send data when the form is submitted. If the attribute is not added or with no valid value the form won't be published. | | action | No | Any valid URL | ./ | Used to specify where the form will send the data. If the attribute is not added the data will be sent to the current page URL. |

Examples

  • <gameface-form-control method="GET" action="http://localhost:12345/login"></gameface-form-control> - Submitting this form will create a GET request with the form data and send it to the server that is available on http://localhost:12345/login.
  • <gameface-form-control method="POST"></gameface-form-control> - Submitting this form will create a POST request with the form data and send it to the current page location.
  • <gameface-form-control></gameface-form-control> - Submitting this form will produce a warning and the request will be aborted.

Form control events

Inline event handlers

| Event | Value | Usage | | ---------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | | onload | Function | Will call the function that is added from the attribute's value when the form request has been completed, whether with success or not. | | onsubmit | Function | Will call the function that is added from the attribute's value when the form is submitted and right before the request is made to the server. |

Examples

Let us have the following functions:

function onRequestEnd(event) {
    console.log("Request response: ", event.detail.target.response)
}

function preventSubmit(event) {
    event.preventDefault();
}
  • <gameface-form-control onload="onRequestEnd(event)" method="GET" action="http://localhost:12345/login"></gameface-form-control> - onRequestEnd will log the response from the request.
  • <gameface-form-control onsubmit="preventSubmit(event)" method="GET" action="http://localhost:12345/login"></gameface-form-control> - preventSubmit will prevent form from making request to the server when the form is submitted.

Event handlers

| Event | Usage | | --------- | ------------------------------------------------------------------------------------------------ | | loadend | Will be triggered when the form request has completed, whether with success or not. | | submit | Will be triggered when the form is submitted and right before the request is made to the server. |

Examples

Let us have the following form - <gameface-form-control id="form" method="GET" action="http://localhost:12345/login"></gameface-form-control>.

  • Log the response from the request.
const form = document.getElementById('form');
form.addEventListener('loadend', (event)=>{
    console.log("Request response: ",event.detail.target.response)
});
  • Prevent form from submitting.
const form = document.getElementById('form');
form.addEventListener('submit', (event) => {
    event.preventDefault();
});

Form control elements

Input

Text inputs

<input> element is supported from the gameface form control just when it is holding text values input with type text, password, email, etc.

The name attribute will be used to specify the form-data key and the value will be used to specify the form data value of the input.

Submit input

So far Gameface does not support input elements with the type submit although they can be defined in the DOM.

The form control will treat these elements like submit buttons and when they are clicked the form will be submitted.

Other inputs

Any other input elements with type range, color, date, etc. are not supported.

Example

<gameface-form-control method="GET" action="http://localhost:12345/login">
    <span>User name:</span>
    <input type="text" name="user" value="name"/>
    <span>Password:</span>
    <input type="password" name="password" value="pass"/>
    <input type="text" name="emptyInput"/>
    <input type="submit" name="submitButton" value="It is input not a button"/>
</gameface-form-control>

Clicking on the input with type submit will make a GET request to http://localhost:12345/login?user=name&password=pass&submitButton=It+is+input+not+a+button.

Notes

  • The data from <input type="submit"/> will be included in the request if this input is clicked.
  • The name attribute is required if you want your input to be included in the form data on submitting!

Select

Native <select> element is not supported by Gameface. However, there is a polyfill that transforms <select> into a working dropdown in the Gameface. That dropdown element - <custom-select> is supported by the form control component.

The polyfill is located inside the Gameface package - Samples/uiresources/Dropdown.

Example

<gameface-form-control method="GET" action="http://localhost:12345/">
    <span>Select city</span>
    <select name="city">
        <option id="Chongqing" name="Chongqing" value="Chongqing">Chongqing</option>
        <option id="Shanghai" name="Shanghai" value="Shanghai">Shanghai</option>
        <option id="Beijing" name="Beijing" value="Beijing">Beijing</option>
        <option id="Lagos" name="Lagos" value="Lagos">Lagos</option>
    </select>
</gameface-form-control>
<script src="Samples/uiresources/Dropdown/custom-select.js">

Textarea

<textarea> element is supported from the gameface form control.

The name attribute is required if you want the value to be included in the form data on submit.

The name attribute will be used to specify the form-data key and the value will be used to specify the form data value of the input.

Example

<gameface-form-control method="POST" action="http://localhost:12345/register">
    <span>User info:</span>
    <textarea name="info">Default value</textarea>
    <span>Additional info:</span>
    <textarea name="moreInfo"></textarea>
    <button type="submit">Submit form</button>
</gameface-form-control>

Clicking on the button will make a POST request to http://localhost:12345/register with the body {"info":"Default value"}. moreInfo won't be included in the request body if its value is empty.

Button

<button> element is supported from the gameface form control.

To make a button that submits the form you need to add the type="submit" attribute to the button.

If a button has name and value attributes their values will be included in the form data on submit if this button is clicked.

Example

<gameface-form-control method="GET" action="http://localhost:12345/buttons">
    <button id="button-with-data" name="button" value="data" type="submit">Submit form</button>
    <button id="button-with-no-data" type="submit">Submit form</button>
</gameface-form-control>
  • Clicking on the button with id button-with-data will make a GET request to http://localhost:12345/buttons?button=data.
  • Clicking on the button with id button-with-no-data will make a GET request to http://localhost:12345/buttons.

Gameface checkbox

<gameface-checkbox> is a gameface component that represents a checkbox and it is supported by the gameface form control.

The name attribute is required if you want the checkbox to be included in the form data when submitted.

The value attribute is not required but if it is empty and the checkbox is checked then the value will be - on by default.

If the checkbox is checked then its name and value will be included in the form data on submit and vice versa if not.

Example

<gameface-form-control action="http://localhost:3000/interests" method="GET">
    <gameface-checkbox name="user-interests" value="music">
        <component-slot data-name="checkbox-background">
            <div class="guic-checkbox-background"></div>
        </component-slot>
        <component-slot data-name="checkbox-label">
            <span class="guic-checkbox-label">Music</span>
        </component-slot>
    </gameface-checkbox>
    <gameface-checkbox name="user-interests" value="coding">
        <component-slot data-name="checkbox-background">
            <div class="guic-checkbox-background"></div>
        </component-slot>
        <component-slot data-name="checkbox-label">
            <span class="guic-checkbox-label">Coding</span>
        </component-slot>
    </gameface-checkbox>
    <gameface-checkbox name="user-interests">
        <component-slot data-name="checkbox-background">
            <div class="guic-checkbox-background"></div>
        </component-slot>
        <component-slot data-name="checkbox-label">
            <span class="guic-checkbox-label">Nothing</span>
        </component-slot>
    </gameface-checkbox>
    <button type="submit">Submit</button>
</gameface-form-control>

Clicking on the submit button will make a GET request to http://localhost:3000/interests?user-interests=music&user-interests=coding&user-interests=on.

Unchecking the Nothing and Coding checkboxes and then submitting the form will make a GET request to http://localhost:3000/interests?user-interests=music.

Gameface radio group/button

<gameface-radio-group> is a gameface component that represents a group with radio buttons that lets the user choose one from all and it is supported by the gameface form control.

The name attribute is required if you want the radio group to be included in the form data when submitted.

The value attribute is not required for the radio-button element but if it is empty and the radio button is checked then the value will be - on by default.

Example

<gameface-form-control action="http://localhost:3000/options" method="POST">
    <span>Normal:</span>
    <gameface-radio-group name="option1">
        <radio-button checked value="1">1</radio-button>
        <radio-button value="2">2</radio-button>
        <radio-button value="3">3</radio-button>
    </gameface-radio-group>
    <span>No value:</span>
    <gameface-radio-group name="option2">
        <radio-button value="1">1</radio-button>
        <radio-button checked>2</radio-button>
        <radio-button value="3">3</radio-button>
    </gameface-radio-group>
    <button type="submit">Submit</button>
</gameface-form-control>

Clicking on the submit button will make a POST request to http://localhost:3000/options with body {"option1":1,"option2":"on"}.

Gameface switch

<gameface-switch> is a gameface component that represents a switch toggle button that lets the uses enable/disable the option and it is supported by the gameface form control.

The name attribute is required if you want the switch to be included in the form data when submitted.

The value attribute is not required for the switch element but if it is empty and the switch is enabled then the value will be - on by default.

Example

<gameface-form-control action="http://localhost:3000/options" method="POST">
    <span class="guic-checkbox-label">Normal</span>
    <gameface-switch name="option1" value="checked" type="text-inside">
        <component-slot data-name="switch-unchecked">No</component-slot>
        <component-slot data-name="switch-checked">Yes</component-slot>
    </gameface-switch>
    <span>No value:</span>
    <gameface-switch name="option2" type="text-inside">
        <component-slot data-name="switch-unchecked">No</component-slot>
        <component-slot data-name="switch-checked">Yes</component-slot>
    </gameface-switch>
    <button type="submit">Submit</button>
</gameface-form-control>

Enable both switch buttons.

Clicking on the submit button will make a POST request to http://localhost:3000/options with body {"option1":1,"option2":"on"}.

Gameface dropdown

<gameface-dropdown> is a gameface component that represents the native select menu and it is supported by the gameface form control.

The name attribute is required if you want the dropdown to be included in the form data when submitted.

The value attribute is not required for the dropdown option element but if it is empty and the options are selected then the value will be the text content of the option by default.

Example

<gameface-form-control action="http://localhost:3000/options" method="POST">
    <span class="guic-checkbox-label">Normal</span>
    <gameface-dropdown name="option1" class="gameface-dropdown-component" id="dropdown-default">
        <dropdown-option value="1" slot="option">One</dropdown-option>
        <dropdown-option value="2" slot="option">Two</dropdown-option>
    </gameface-dropdown>
    <span class="guic-checkbox-label">No values</span>
    <gameface-dropdown name="option2" class="gameface-dropdown-component" id="dropdown-default">
        <dropdown-option slot="option">One</dropdown-option>
        <dropdown-option slot="option">Two</dropdown-option>
    </gameface-dropdown>
    <button type="submit">Submit</button>
</gameface-form-control>

Clicking on the submit button will make a POST request to http://localhost:3000/options with body {"option1":1,"option2":"One"}.

Text Field

<gameface-text-field> is a component that allows you to use a text input of different types - text, email, password, number, etc. It supports validation. For example, if you create a text field with the type:

  • email - the built-in validation will check if the value has a @ symbol and it will show an error if does not.
  • url - the built-in validation will check a pattern as an attribute to the text field and its value should match this pattern. For example if the url should match certain domain name - <gameface-text-field type="url" pattern="mydomain.*">.
  • password - the built-in validation will check length through the minlength and maxlength attributes.
  • number - the built-in validation will check min and max attributes.
  • text, password, search - the built-in validation will check length through the minlength and maxlength attributes.

Example

<gameface-form-control style="position: absolute;top: 200px;">
    <gameface-text-field id="text" name="text" label="User name:" type="text" value="thisisvalid" minlength="5" maxlength="20"></gameface-text-field>
    <gameface-text-field id="url" name="url" pattern="https://.*" label="Website:" value="https://localhost:9090" type="url"></gameface-text-field>
    <gameface-text-field id="email" name="email" label="Email:" type="email" value="[email protected]"></gameface-text-field>
    <gameface-text-field id="number" name="number" label="Age:" type="number" min="15" max="200" step="10" value="30"></gameface-text-field>
    <button class="form-element" id="submit" type="submit">Login</button>
</gameface-form-control>

Validation

The form control supports validation. These are the attributes that you can use:

| Name | Purpose | Supported Elements | | --------- | ------------------------------------------------------------------------------------------------ | ----------------------------------------------- | | required | Used to indicate that a value is required. Will show an error if the element doesn't have value. | Input, Textarea, Checkbox, Switch, Radio Button | | minlength | Used to indicate the minimum length of a text field. | Input | | maxlength | Used to indicate the minimum length of a text field. | Input | | min | Used to indicate the minimum value of a number input | Input | | max | Used to indicate the maximum value of a number input | Input | | pattern | Used to specify a url pattern. | TextField[type="url"] | | required | Used to specify that the element must have value. | All form supported elements |

Custom validation

The form control component supports custom validation as well. Its purpose is to customize the default methods for validation, error messages, or where to show them. The default methods for validating form are stored in a map where each method has a default message defined for it. These methods are checking if a form element meets the requirements to be valid that are defined by the attributes above. Here is a table describing each method name, its error, and its relevant form element attribute.

| Default validator method name | Error message | Corresponding attribute | Additional info | | ---------------------- | ---------------------------------------------------------------------------------------- | ----------------------- | -------------------------------------------------------------------------------------------- | | notAForm | This element is not part of a form. | N/A | This validator validates if the element is part of the form control. | | nameMissing | The element does not have a name attribute and will not be submitted | N/A | This validator validates if a form element has valid name attribute set. | | tooLong | The value is too long. Maximum length is ${element.getAttribute('maxlength')}. | maxlength | | tooShort | The value is too short. Minimal length is ${element.getAttribute('minlength')}. | minlength | | rangeOverflow | The value is too big. Maximum is ${element.getAttribute('max')}. | max | | rangeUnderflow | The value is too small. Minimum is ${element.getAttribute('min')}. | min | | valueMissing | The value is required. | required | | badURL | Please enter a valid URL. It should match the following pattern: /${element.pattern}/. | N/A | This validator validates <gameface-text-field> component's value when its type is url. | | badEmail | Please enter a valid email. It should contain a @ symbol. | N/A | This validator validates <gameface-text-field> component's value when its type is email. |

As you can see some validators have error messages that include some properties from the validated element. That is because each validator dynamically constructs the error messages using the currently validated form element.

Custom form validation methods

<gameface-form-control> component has some methods for making custom validation possible.

| Method | Arguments | Description | | ---------------------------------- | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | setCustomValidators | (name: string, validators: ValidatorsConfig) | Will set custom defined validators related to the form elements with the corresponding name attribute. | | removeCustomValidator | (name: string) | Will remove any custom validators related to the form element with the corresponding name attribute. | | removeCustomValidators | (names: string[]) | Same as the removeCustomValidator but works with multiple names. | | setCustomDisplayErrorElement | (name: string, selector: string) | Will change the default behavior of showing error messages. The name argument specifies the form element that will be modified. The selector specifies the element in which the error will be displayed. | | removeCustomDisplayErrorElement | (name: string) | Remove the custom error message element previously added using setCustomDisplayErrorElement. The name argument specifies the form element. The default tooltip will be used instead for displaying errors. | | removeCustomDisplayErrorElements | (names: string[]) | Same as the removeCustomDisplayErrorElement method but works with multiple names. |

ValidatorsConfig

It is an object that has the following type:

interface ValidatorsConfig {
    [ValidatorName: string]: {
        method?: (element: HTMLElement) => boolean | Promise<boolean>
        errorMessage?: (element: HTMLElement) => string
    }
}

With the ValidatorName key you define your custom validator name or you can use some of the default validator names to overwrite their behavior.

method is the function that is used to tell the form component if the currently validated element is valid. It receives that element and should return a boolean with the result about the validity of the element. You can use the async function to define the method property. To overwrite the default validators use ValidatorName that has the same name as the one you wish to change:

form.setCustomValidators('username', {
    valueMissing: { // will use this one, no the default
        method: (element) => !element.value,
        errorMessage: () => 'The username is required! '
    }
})

errorMessage is the function that constructs the message if the validation of the form element fails. It receives that element so you can extract its attributes and return a more specific error message. The function should return a string. If this property is added to ValidatorName that is some of the default ones will overwrite the default validation message.

form.setCustomValidators('username', {
    valueMissing: { 
        errorMessage: () => 'The username is required! ' // will use this error message, not the default that is "The value is required."
    }
})

Example

Let us have the following form defined

<gameface-form-control id="custom-validation-form">
    <gameface-text-field name="username" label="User name:" type="text" minlength="5" maxlength="20"></gameface-text-field>
    <span id="username-error"></span>
    <gameface-text-field name="url" label="Website:" type="url"></gameface-text-field>
    <gameface-text-field name="email" label="Email:" type="email"></gameface-text-field>
    <button class="form-element" type="submit">Register</button>
</gameface-form-control>

As you can see some attributes are used to validate the user name. The url and email will be validated by default. We can add our custom validators using the methods exposed in the gameface-form-control component. Note: Custom validation should be added after the form control bundle is added to the page.

// Custom validators should be set after the components library is added!

const form = document.getElementById('custom-validation-form');

let serverError = false, serverNotReachable = false;
//Will set custom validators for the form element with name attribute that has value - "username"
form.setCustomValidators('username', {
    //There is no required attribute to the form element so we can add validation about it here
    valueMissing: {
        method: (element) => !element.value,
        errorMessage: () => 'The username is required! '
    },
    //We can change the default message on the 'tooShort' preset validator
    tooShort: { errorMessage: (element) => `The username should have more than ${element.getAttribute('minlength')} symbols typed! `},
    //Async validator that checks if the user is already added to the database by making a request to the server
    usernameExists: {
        method: async (element) => {
            if (!element.value) return false;

            serverError = false;
            serverNotReachable = false;
            return new Promise((resolve) => {
                const xhr = new XMLHttpRequest();
                xhr.open('GET', `http://localhost:3000/user-exists?username=${element.value}`);
                xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
                xhr.onload = (event) => resolve(event.target.response === 'true');
                xhr.onerror = () => {
                    serverError = true;
                    return resolve(true)
                }
                xhr.timeout = 1000;
                xhr.ontimeout = () => {
                    serverNotReachable = true;
                    return resolve(true)
                }
                xhr.send();
            })
        },
        errorMessage: (element) => {
            if (serverNotReachable) return 'Unable to reach the server! ';
            if (serverError) return 'Unable to reach the server due an error! ';

            return `"${element.value}" already used! Please use another one! `;
        }
    }
});
//By default the error will be visible in a tooltip displayed next to the form element
//We can change that behavior for the user name by selecting another element for this purpose
form.setCustomDisplayErrorElement('username', '#username-error');

//We can set a custom validation of the form element with a custom method and a message
form.setCustomValidators('url', {
    notStartingWithHttpProtocol: {
        method: (element) => !element.value.startsWith('http://') && !element.value.startsWith('https://'),
        errorMessage: () => 'The url should start with "http://" or "https://"!'
    }
});

form.setCustomValidators('email', {
    //We can remove the preset error message if the preset validator for email fails
    //That will also remove the tooltip because no error messages should be visible even if the check fails
    badEmail: {
        errorMessage: () => ''
    }
});

Accessing the XMLHttpRequest

An XMLHttpRequest is created when a form is submitted. It is helpful to access this XHR in case you need to check the status of the request, the response, or if you want to do something on success/error. You can access this request through the properties of the form control:

<gameface-form-control id="my-form" action="http://localhost:3000/options" method="POST">
    <input type="text" name="user" value="name" />
    <button type="submit">Submit</button>
</gameface-form-control>

const form = document.getElementById('my-form');
const xhr = form.xhr;

xhr.addEventListener('progress', () => console.log('onProgress'));
xhr.addEventListener('load', () => console.log('load'));
xhr.addEventListener('error', () => console.log('error'));
xhr.addEventListener('abort', () => console.log('abort'));