@furashcka/feedback.js v0.1.10
About
feedback.js it's simple library with beautiful API for validation and sending forms.
Why use feedback.js?
1. You don't need thinking about browser supporting, supports ie9+\ 2. You can sending data with files, if browser not supports FormData feedback.js sends form to iframe\ 3. Very simple API\ 4. Convenient validation\ 5. Your code becomes more understandable and takes up less space\ 6. Without dependencies
Installation
<script src="https://cdn.jsdelivr.net/gh/furashcka/feedback.js@0.1.10/dist/feedback.min.js"></script>
Install via NPM
npm i @furashcka/feedback.js
Install via Yarn
yarn add @furashcka/feedback.js
Quick start
<form method="post">
<div class="error" style="display: none;"></div>
<input type="text" name="name" placeholder="Your name" />
<input type="text" name="email" placeholder="Your E-mail" />
<button>Submit</button>
</form>
var feedback = new Feedback($("form").get(0));
// Validation initialization
feedback.schema({
name: function () {
if (this.isEmpty()) return "Please, write your name.";
},
email: function () {
if (!this.isEmail()) return "Email is not correct!";
},
});
// Error handling
feedback.validate({
error: function (msg) {
$("form .error").text(msg).show();
},
success: function () {
$("form .error").hide();
},
});
Options and Events
default options
var el = document.querySelector("form");
var opts = {
focusIncorrectInput: true,
fireSchemaByTurn: true,
blockSubmitWhenFormSending: true,
fireValidateAndAjaxWhenSubmit: true,
resetFormAfterAjax: true,
schema: {},
validationStep: 0,
validationStepChanged: function () {},
ajax: {
loadingClass: "--loading",
url: el.action || location.href,
method: el.method || "POST",
iframePolyfill: "auto",
iframePostMessage: false,
iframeTimeout: 0,
before: function () {},
after: function () {},
success: function () {},
error: function () {},
progress: function () {},
},
validate: {
before: function () {},
after: function () {},
success: function () {},
error: function () {},
},
};
var feedback = new Feedback(el, opts);
focusIncorrectInput
true: set focus in incorrect input\ false: nothing happens
Type: boolean\ Default: true
fireSchemaByTurn
true: if you want to show the first error found and stop validating\ false: if you want to show all errors at once
Type: boolean\ Default: true
blockSubmitWhenFormSending
true: the next form sending is blocked while the previous one is sending\ false: nothing happens, form send by default
Type: boolean\ Default: true
fireValidateAndAjaxWhenSubmit
true: when form sending, checks all errors and send form by AJAX\ false: nothing happens, form send by default
Type: boolean\ Default: true
resetFormAfterAjax
true: calls form.reset()
; after successful send\
false: nothing happens
Type: boolean\ Default: true
schema
{key: value} - object with all logics for validations inputs, key it's name attribute <input name="email">
or other form element, value it's function, calls when fires validate API.\
Also you can use steps, when need step by step validation.\
When you set step index, you need set "step-{number}"
var feedback = new Feedback(el, {
schema: {
email: function () {
if (!this.isEmail()) return "Email is not correct!";
},
},
});
// with steps
var feedback = new Feedback(el, {
schema: {
"step-0": {
name: function () {
if (!this.isEmpty()) return "Please, enter your name.";
},
},
"step-1": {
email: function () {
if (!this.isEmail()) return "Email is not correct!";
},
},
},
});
// is recommended use API:
var feedback = new Feedback(el);
feedback.schema({
email: function () {
if (!this.isEmail()) return "Email is not correct!";
},
});
// with steps
feedback.schema("step-0", {
name: function () {
if (!this.isEmpty()) return "Please, enter your name.";
},
});
feedback.schema("step-1", {
email: function () {
if (!this.isEmail()) return "Email is not correct!";
},
});
Input API this - it's array of inputs grouped by name with API from validator.js if need validate input without this context, call like: Instance.inputsGroupedByName.inputName.isEmpty()
get - returns input element by index; if index empty returns first element; if index -1 returns last element\ isAnyChecked - returns true if any input checked, and return false if any not checked\ forEach - method calls a function once for each element in an array inputs\ equals - check if the string matches the comparison\ isAlpha - check if the string contains only letters (a-zA-Z)\ isAlphanumeric - check if the string contains only letters and numbers\ isCreditCard - check if the string is a credit card\ isEmail - check if the string is an email\ isEmpty - check if the string has a length of zero\ isFloat - check if the string is a float\ isIn - check if the string is in a array of allowed values\ isInt - check if the string is an integer\ isMobilePhone - check if the string is a mobile phone number\ isNumeric - check if the string contains only numbers\ isURL - check if the string is an URL\ matches - check if string matches the pattern
read more about each can be here
Type: Object\ Default: empty object
validationStep
needs for step by step validation
Type: number\ Default: 0
validationStepChanged
calls after validationStep changes
Type: function\ Default: empty function
ajax
object for setting AJAX options:
var feedback = new Feedback(el, {
ajax: {
url: "//httpbin.org/post",
method: "post",
},
});
// is recommended use API:
var feedback = new Feedback(el);
feedback.ajax({
url: "//httpbin.org/post",
method: "post",
});
Type: object\ Default: object
ajax.loadingClass
adds class to form element when sends data
Type: string\ Default: --loading
ajax.url
URL address to which the request is sent
Type: string\ Default: action attribute from form element or location.href (if empty action attribute)
ajax.method
HTTP request method: GET | POST | PUT | PATCH | DELETE
Type: string\ Default: method attribute from form element or 'POST' (if empty method attribute)
ajax.iframePolyfill
auto: 1) browser supports XMLHttpRequest v2.0, feedback.js sends files and strings together, 2) browser supports only XMLHttpRequest v1.0, feedback.js sends only strings, XMLHttpRequest v1.0 will be uses if form element don't have any inputs with type=file 3) need send files and strings together, but browser don't support XMLHttpRequest v2.0, feedback.js sends to iframe and show warning to console\ true: feedback.js sends strings and files always to iframe\ false: uses XMLHttpRequest v2.0 or XMLHttpRequest v1.0, if browser not support XMLHttpRequest v2.0 and form element have any inputs with type=file, feedback.js sends only strings and show warning to console
Type: string or boolean\ Default: auto
ajax.iframePostMessage
true: waits until call Window.postMessage() from iframe for response from server and after call ajax.success\ false: nothing happens
Type: boolean\ Default: false
ajax.iframeTimeout
1000 (or more): waits 1000 (or more) milliseconds for iframe.load event, if iframe.load event not called until 1000 (or more) milliseconds, calls ajax.error\ 0: waits endlessly
Type: number\ Default: 0
ajax.before
calls before sending by AJAX
Type: function\ Default: empty function
ajax.after
calls after sending by AJAX
Type: function\ Default: empty function
ajax.success
calls if the request succeeds, arguments: type (String) - 'ajax.2.0 or ajax.1.0 or iframe'; xhr (XMLHttpRequest object)
feedback.ajax({
success: function (type, xhr) {
switch (type) {
case "ajax.1.0":
console.log("1.0", xhr);
break;
case "ajax.2.0":
console.log("2.0", xhr);
break;
case "iframe":
console.log("iframe", xhr);
break;
}
},
});
Type: function\ Default: empty function
ajax.error
calls if the request fails, arguments: type (String) - 'ajax.2.0 or ajax.1.0'; xhr (XMLHttpRequest object), not calls if uses iframe
feedback.ajax({
error: function (type, xhr) {
switch (type) {
case "ajax.1.0":
console.log("1.0", xhr);
break;
case "ajax.2.0":
console.log("2.0", xhr);
break;
}
},
});
Type: function\ Default: empty function
ajax.progress
calls periodically with information when an XMLHttpRequest before success completely, this in function it's form element, arguments: percent (Number)
feedback.ajax({
progress: function (percent) {
console.log("progress - " + percent + "%");
},
});
Type: function\ Default: empty function
validate
object with validation events:
var feedback = new Feedback(el, {
validate: {
error: function (err, inputsArray) {},
},
});
// is recommended use API:
var feedback = new Feedback(el);
feedback.validate({
error: function (err, inputsArray) {},
});
Type: object\ Default: object
validate.before
calls before validating
Type: function\ Default: empty function
validate.after
calls after validating
Type: function\ Default: empty function
validate.success
calls, if validation successful
Type: function\ Default: empty function
validate.error
calls, if validation has errors, arguments: errorMessage (String); inputsArr (Array) - inputs grouped by name
feedback.validate({
error: function (errorMessage, inputsArr) {
var err = "<p>" + errorMessage + "</p>";
var el = inputsArr[0];
el.insertAdjacentHTML("beforebegin", err);
// or with jQuery
$(el).before(err);
},
});
Type: function\ Default: empty function
API
// you can do:
feedback.schema(/* ... */).validate(/* ... */).ajax(/* ... */);
/* ... other API */
// or
feedback.schema(/* ... */);
feedback.validate(/* ... */);
feedback.ajax(/* ... */);
schema
function for updating options.schema
feedback.schema({
/* ... */
});
// with steps
feedback.schema("step-0", {
/* ... */
});
feedback.schema("step-1", {
/* ... */
});
step
function for updating options.validationStep; and options.validationStepChanged;\ get return current step;\ set, next, prev update current step;\ changed init change event.
feedback.step("get"); // return options.validationStep
feedback.step("set", 1); // options.validationStep = 1;
feedback.step("next"); // options.validationStep++;
feedback.step("prev"); // options.validationStep--;
feedback.step("changed", function () {}); // options.validationStepChanged = function () {};
ajax
function for updating options.ajax and sending\ updating:
feedback.ajax({
/* ... */
});
sending form:
feedback.ajax();
sending selected inputs:
feedback.ajax(["name", "age"]);
validate
function for updating options.validate and validating; returns boolean\ updating:
feedback.validate({
/* ... */
});
validating:
if (feedback.validate() === true) {
/* ... */
}
update
if your form is dynamical you need call update when your form changed
feedback.update();
fireValidateError
call validate.error event
var el = form.querySelector('input[name="email"]');
feedback.fireValidateError("Error: wrong email!", [el]);
resetForm
reset form by default
feedback.resetForm();
destroy
remove all events and return null for clearing variable
feedback = feedback.destroy();
console.log(feedback); // null