form-management
Layer for advanced form field validation and user interaction handling.
Install
$ yarn add form-management
Usage
<form id="myForm">
<label for="myInput">My input</label>
<input type="text" name="myInput" id="myInput" class="field" data-validators="required myValidator"/>
<input type="submit" value="Submit"/>
</form>
const
formManagement = require('form-management'),
{Form} = formManagement;
let Form = new Form({
form: document.querySelector('#myForm'),
handlers: {
save: () => {
alert('Ready to submit');
}
},
validators: {
myValidator: (value, field) => {
return {
valid: checkMyFieldValue(field, value),
hint: 'This field is not valid'
};
}
}
})
function checkMyFieldValue(field, value) {
// custom field validation rule
}
API
Form.constructor(config)
config | object
-
form |
element
<form>
element -
handlers |
object
event handlers, all are called in the Form scope.-
save |
function
optional
is called when user submits the form -
delete |
function
optional
is called when user press the delete button -
change |
function
optional
is called when any field changes its value, acceptsfield
as the first argument -
cancel |
function
optional
is called when user cancels edits
-
save |
-
id |
string
optional
custom form ID -
validators |
object
optional
custom validation functions dictionary, each in form:
validatorName(value, field) {
return {
valid: [Boolean],
hint: [String]
};
}
-
plugins |
object
optional
dictionary of special fields, each in form:
{
init: fn(field) {},
getValue() {
return value;
}
}
-
editable |
boolean
optional
enable form editing. Default istrue
. -
editOnClick |
boolean
optional
enable edit mode by clicking somewhere on form. Default isfalse
. -
persistentEditMode |
boolean
optional
edit mode is always enabled (standard form behavior). Default istrue
. -
displayEdit |
boolean
optional
display edit button. Default isfalse
. -
displayDelete |
boolean
optional
display delete button. Default isfalse
. -
translate |
function
optional
translator function in form:
function(text) {
return translatedText;
}
-
autoFocus |
boolean
optional
focus the first editable field on edit start. Default isfalse
. -
validatePreviousOnFocus |
boolean
optional
validate all fields up to the current. Default istrue
. -
validateOnBlur |
boolean
optional
validate field when it loses focus. Also validate the whole form when the current field is the last one. Default istrue
.
Form.getEl()
Returns <form>
element associated with the Form
instance.
Form.getOriginalData()
Returns key-value object with initial form data representation.
- text input is a
string
- selectable is an
array
ofstring
values - checkbox is a
boolean
- empty field is
undefined
Form.getData()
Returns key-value object with current form data representation.
- text input is a
string
- selectable is an
array
ofstring
values - checkbox is a
boolean
- empty field is
undefined
Form.getId()
Returns custom form ID set in constructor
or by Form.setId()
method.
Form.isDirty()
Returns true
if current data differs from initial data, otherwise returns false
.
Form.setEditable(editable)
Sets the form is editable or not. If new editable
state is false
, form editing is cancelled.
editable | boolean
New editable
state to be set
Form.setData(data)
Sets new initial data and overwrites values in fields.
data | object
Key-value object with new form data.
- either
array
ofstring
values or astring
value for a selectable -
boolean
for a checkable -
undefined
clears the field - if field name is not listed in keys, nothing happens to the field
Form.setId(id)
Sets new custom ID.
id | string|number
Form.edit()
Switches to editing mode (if not yet). Focuses the first editable field if autoFocus
option is enabled.
Form.cancel(triggerCallback)
Switches to read mode (if not disabled by persistentEditMode
), removes validation hints and invalid states, clears dirty state and blurs form fields. cancel
handler is not being called in this method.
triggerCallback | boolean
optional
By default the cancel
handler is not triggerred when calling Form.cancel()
. This option allows you to set it to true
and let the callback be called after form edit mode is cancelled (even if it's in persistent edit mode). Default is false
.
Form.save(triggerCallback)
Runs form validation and calls save
handler if successfull. save
handler is not being called in this method.
triggerCallback | boolean
optional
By default the save
handler is not triggerred when calling Form.save()
. This option allows you to set it to true
and let the callback be called with the validation result. Default is false
.
Form.reset()
Resets form to the default state using original data values.
Form.validateForm()
Validates all form fields.
Form.validateField(field)
Iterates all fields validators contained in data-validators
attribute.
If any validator fails, validation stops immediately and sets invalid
class to the field element. If there's a label
with proper for
attribute, it gets data-hint
attribute containing validator hint
(if any). The label
also gets invalid
class.
Validation result is cached and is executed just once until field value changes.
field | element
Form.resetValidation(fieldName)
Clears validation cache for field values.
fieldName | string
optional
Form.showLoadingMask()
Displays a .loading-mask
child element, if exists.
Form.hideLoadingMask()
Hides a .loading-mask
child element, if exists.
Advanced
Read/edit mode
Form is also useful when you want to switch between two states - READ (for record representation) and EDIT (for record editing). By accessing the edit mode (by clicking .edit-button
or whole form
in case of editOnClick
is true
) the <form>
element gets a class active
.
The form is using readonly
attribute to represent READ state, but don't worry - the original readonly
attributes are being preserved when user switches to EDIT mode.
<!-- Your initial form definition... -->
<form>
<input type="text" name="myInput" class="field" readonly="readonly"/>
<input type="text" name="myInput" class="field"/>
</form>
<!-- ... becomes this in READ mode... -->
<form>
<input type="text" name="myInput" class="field" readonly="readonly" data-readonly="true"/>
<input type="text" name="myInput" class="field" readonly="readonly"/>
</form>
<!-- ... and this in EDIT mode. -->
<form class="active">
<input type="text" name="myInput" class="field" readonly="readonly"/>
<input type="text" name="myInput" class="field"/>
</form>
Control buttons
You may add control buttons for edit, save, delete or cancel.
<form id="myForm">
<input type="text" name="myInput" class="field"/>
<input type="button" value="Edit" class="edit-button"/>
<input type="button" value="Save" class="save-button"/>
<input type="button" value="Cancel" class="cancel-button"/>
<input type="button" value="Delete" class="delete-button"/>
</form>
Loading mask
If you include <div class="loading-mask"></div>
, it will be displayed automatically when user submits the form or if she hits the delete button. It's up to you to call Form.hideLoadingMask()
in a subsequent request callback.
Testing
Tests are using AVA library
$ yarn test // run all tests
$ yarn test -- -m 'Test title RegExp' // run test with matching title