Modern, simple but powerful form validation library written in pure JavaScript, with no dependencies.
This is the right choice for you if you have a website or landing page without frameworks.
The library is very simple. There are no complicated predefined rules here because there are many npm packages that provide these rules. It only can checks the rules and inserts the error or success message into the container, which can be found in the current HTML using the querySelector method, or dynamically created and inserted into the HTML. The library also has many callbacks, such as on successful validation of the entire form or on failure of a field validation.
- small size and zero dependencies
- custom rules
- custom messages
- custom styles and css classes for valid/invalid fields and success/error messages
- custom places for the messages
npm i simpower-validation
Then it can be used as an imported module with module bundlers:
import SimpowerValidation from 'simpower-validation';
const validate = new SimpowerValidation('#form');
If you don't use module bundlers, you can import SimpowerValidation via a browser:
import SimpowerValidation from '[relative or absolute path to node_modules folder]/simpower-validation/simpower-validation.esm.js';
const validate = new SimpowerValidation('#form');
Or you can just include SimpowerValidation script on your page from CDN and call it as window.SimpowerValidation
:
<script src="https://cdn.jsdelivr.net/npm/simpower-validation/simpower-validation.production.min.js"></script>
<script>
window.addEventListener('DOMContentLoaded', () => {
const validate = new window.SimpowerValidation('#form');
});
</script>
Let's say we have a basic HTML layout:
<form id="form">
<label for="name">Enter your name</label>
<input id="name" name="name" type="text" placeholder="Enter your name" />
<label for="email">Enter your email</label>
<input id="email" name="email" type="email" placeholder="Enter your email" />
<button type="submit">Submit</button>
</form>
Next, let's add SimpowerValidation to the layout and define some rules.
First, we must create an instance new SimpowerValidation('#form')
by passing a form selector, or the element as an argument.
Second, we must call .addField()
with the field selector, or DOM element, or field name attribute as the first argument and the rules array as the second argument.
const validation = new SimpowerValidation('#form');
validation
.addField('name', [
{
validator(inputValue) {
return inputValue.trim();
},
errorMessage: 'Name is required',
},
{
validator(inputValue) {
const nameRegEx = /^[a-zA-Z]{1,40}$/;
return inputValue.match(nameRegEx);
},
errorMessage: 'Name is invalid',
},
])
.addField('email', [
{
validator(inputValue) {
if (!inputValue.trim()) {
return true
}
const emailRegEx = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return inputValue.match(emailRegEx);
},
errorMessage: 'Email is invalid'
},
]);
That's all! The form is now validated!
See the current example.
Let's consider API.
const validation = new SimpowerValidation(parentElement: string | Element[, globalConfig: object]);
Let's change the HTML layout mentioned above:
<form id="form">
<label for="name">Enter your name</label>
<input id="name" name="name" type="text" placeholder="Enter your name" />
<label for="email">Enter your email</label>
<input id="email" name="email" type="email" placeholder="Enter your email" />
<button type="submit">Submit</button>
</form>
<div id="messagesContainerForAllInputs"></div>
<div id="messageContainerForEmailInput"></div>
const validation = new SimpowerValidation(
'#form',
{
validateFieldOnEvent: {
event: 'blur',
afterFirstSubmition: true,
lockInputOnValidation: false,
fieldValueHandler(fieldValue) {
return fieldValue;
},
ruleErrorMessages: {
on: true,
position: {
append: '#messagesContainerForAllInputs',
},
removeContainerFromDOMAfterSuccess: true,
classes: ['message-css-class', 'error-message-css-class'],
},
successfulValidationMessage: {
on: true,
successMessage: 'Validation succeeded',
position: {
append: '#messagesContainerForAllInputs',
},
removeContainerFromDOMAfterFail: true,
classes: ['message', 'message_success'],
},
invalidViewOfField: {
on: true,
classes: ['input_view_invalid'],
},
validViewOfField: {
on: true,
classes: ['input_view_valid'],
},
},
validateOnSubmit: {
lockFormOnValidation: false,
revalidateAllFieldsBeforeSubmition: false,
},
},
)
validateFieldOnEvent | ||
---|---|---|
Field | Description | Type |
event | JavaScript Event. tdis event is added to form elements tdat have been added for validation. When tde event fires, validation starts. If tde event name is invalid, unvalidated elements will be validated when attempting to submit. | string |
afterFirstSubmition | If true, validation after the event specified in the 'event' parameter will work only after the first submission attempt. | boolean |
lockInputOnValidation | This option is useful if an asynchronous validator is specified. It sets the disabled attribute on the fields for the duration of the validation. | boolean |
fieldValueHandler | If exists, this function change value which take validator functin. It is very useful feature if you, for example, use masks for inputs (you can use `fieldValueHandler`for unmasking of input value before validation. | function |
ruleErrorMessages.on | Enable error message | boolean |
ruleErrorMessages.position | Define where error message will be inserted. It has four optional properties: 'append', 'prepand', 'after' and 'before'. Possible value type is string | Element. | object |
ruleErrorMessages. removeContainerFromDOMAfterSuccess |
If true, a error message will be deleted after a successful validation. | boolean |
ruleErrorMessages.classes | ССS classes to be added to containers with error messages. | Array with css classes |
successedValidationMessage.on | Enable success messages | boolean |
successedValidationMessage.on | Text of success messages | string |
successedValidationMessage.position | Define where success message will be inserted. It has four optional properties: 'append', 'prepand', 'after' and 'before'. Possible value type is string | Element. | object |
successedValidationMessage. removeContainerFromDOMAfterFail |
If true, a success message will be deleted after a failed validation. | boolean |
successedValidationMessage.classes | ССS classes to be added to containers with success messages. | Array witd css classes |
invalidViewOfField.on | Enable invalid views of fields | boolean |
invalidViewOfField.classes | ССS classes to be added to invalid fields. | Array witd css classes |
validViewOfField.on | Enable valid views of fields/td> | boolean |
validViewOfField.classes | ССS classes to be added to valid fields. | Array witd css classes |
validateOnSubmit | ||
---|---|---|
Field | Description | Type |
lockFormOnValidation | This option is useful if an asynchronous validator is specified. It sets the disabled attribute for all form elements. | boolean |
revalidateAllFieldsBeforeSubmition | Enables forced validation of all fields before submission, even those that have already been validated. | boolean |
The first argument is the field selector, or DOM element, or field name attribute.
The second argument is the rules array.
The third argument contain local config for field. The argument is structurally identical to validateFieldOnEvent
object in the global config.
Example of the full setting:
{
validator(value) {
return value.toString().trim()
},
errorMessage: 'The field is required'
}
In this example validator
method return boolean. In case false, then value of errorMessage
will be inserted in error message container, if showing of error messages is enabled.
There is the other variant of rule object:
{
validator(value) {
if (typeof value !== 'string') {
return {
result: false,
errorMessage: 'The value must be of type "string".'
}
} else if (!value.trim()) {
return {
result: false,
errorMessage: 'The value must not be of type "number".'
}
}
return true;
},
}
validator
method can return an object with an error message, the text content of which depends on various conditions.
The argument is structurally identical to validateFieldOnEvent
object in the global config.
The third argument overrides the corresponding properties in the global configuration for the specific field.
So, for example, if we set the following setting for the email field in the example above, the name field will be validated after the blur event, while the email field will be validated after the input event. Also it changes container for error or successful messages.
{
event: 'input',
ruleErrorMessages: {
position: {
append: '#messageContainerForEmailInput',
},
},
successfulValidationMessage: {
position: {
append: '#messageContainerForEmailInput',
},
},
}
There are four types of callbacks:
- when field or form validation starts:
validation.onStartValidation(callback: function, eventName: string): validation
- when field or form validation ends:
validation.onEndValidation(callback: function, eventName: string): validation
- when field or form validation succeeded:
validation.onSuccess(callback: function, eventName: string): validation
- when field or form validation failed:
validation.onFail(callback: function, eventName: string): validation
Callbacks have two arguments. The first argument is built-in event object, the second one is the object in case of validation of all fields during submition attemt or a field in case of validation of a field.
The callbacks take two arguments. The first argument is the built-in event object, the second is the object validation.form
when submitting, or the object (validation.fields[someFieldId]
) in case of validation of a field.
Example of the object (validation.form
):
{
elem: <form id="form">...</form>,
formElements: elem.elements,
submitting: false,
isSubmitted: true,
}
Example of the object (validation.fields[someFieldId]
):
{
elem: <input id="email" name="email" type="email" placeholder="Enter your email"/>,
defaultValue: elem.defaultValue,
rules: [
{
validator(inputValue) {
if (!inputValue.trim()) {
return true
}
const emailRegEx = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return inputValue.match(emailRegEx);
}
errorMessage: 'Email is invalid'
},
]
eventHandlers: Map(1) {{
handlerName: 'validateOnFieldInput',
event: 'input'
} => validation.validateOnFieldEvent.bind(validation)},
isValid: false,
isPotentiallyValid: false,
wasValidated: false,
successMessage: null,
errorMessage: null,
errorMessageIsShown: false,
successMessageIsShown: false,
config: {
event: 'input'
},
}