Skip to content

Instantly share code, notes, and snippets.

@im4aLL
Created September 20, 2019 07:00
Show Gist options
  • Select an option

  • Save im4aLL/b4afae0d20e132073213abadb7446a2b to your computer and use it in GitHub Desktop.

Select an option

Save im4aLL/b4afae0d20e132073213abadb7446a2b to your computer and use it in GitHub Desktop.
es6 form validator (laravel style)
/**
* Serialize form value into Object
*
* @return jquery plugin
*/
$.fn.serializeObject = function (settings) {
const o = {};
let a = this.serializeArray();
if (a.length > 0 && settings && settings.excludePrefix) {
const tempArray = [];
$.each(a, function(index, val) {
const name = val.name.replace(settings.excludePrefix, '');
const value = val.value;
tempArray.push({
name,
value
});
});
a = [...tempArray];
}
$.each(a, function () {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
import { Validate } from './validate.js';
export class RequestForm {
constructor() {
this.validate = new Validate();
this.init();
}
init() {
this.validateForm();
}
validateForm() {
const self = this;
$('.request__form').submit(function(event) {
event.preventDefault();
const data = $(this).serializeObject();
self.validate.data(data).rules({
'rf_name': 'required',
'rf_email': 'required|email',
'rf_phone': 'required|array',
'rf_is_healthcare_provider': 'required|radio',
'rf_comments': 'required_if:rf_is_healthcare_provider,no',
'rf_provider_count': 'required_if:is_healthcare_provider,yes',
'rf_health_associated': 'required_if:is_healthcare_provider,yes',
}, {
'rf_name': 'Please write your name',
});
console.log(self.validate.result());
});
}
}
export class Validate {
constructor() {
this.defaults = {
messages: {
'required': 'This field is required',
'required_if': 'This field is required (if)',
'email': 'Please enter valid email',
}
}
this.reset();
}
reset() {
this.dataObject = {};
this.ruleObject = {};
this.messageObject = {};
this._formRule = {};
this._errors = [];
}
data(data) {
this.reset();
this.dataObject = {...data};
return this;
}
rules(rules, messages) {
this.ruleObject = {...rules};
this.messageObject = {...messages};
return this;
}
result() {
this._prepareRules();
console.log(this._formRule);
for (const name in this._formRule) {
const result = this._checkFieldByRule(name, this._formRule[name]);
if (!result.isValid) {
this._errors.push({
name,
message: result.message,
});
}
}
return {
valid: this._errors.length === 0 ? true : false,
errors: this._errors,
}
}
_prepareRules() {
for (const prop in this.ruleObject ) {
this._formRule[prop] = this._generateRules(this.ruleObject[prop]);
}
return this;
}
_generateRules(ruleText) {
const obj = {};
if (!ruleText || ruleText.length === 0) {
return obj;
}
for (let value of ruleText.split('|')) {
if (value.includes(':')) {
for (let value of value.split(':')) {
if (value.includes(',')) {
const a = value.split(',');
if (!obj['when']) {
obj['when'] = [];
}
for (let i = 0; i < a.length; i = i + 2) {
obj['when'].push({
name: a[i],
val: a[i+1],
});
}
} else {
obj[value] = true;
}
}
} else {
obj[value] = true;
}
}
return obj;
}
_checkFieldByRule(name, ruleObj) {
const result = {
isValid: false,
value: '',
message: '',
};
let value = '';
if (ruleObj.array) {
value = this._getArrayFieldValueByName(name);
} else if (ruleObj.radio) {
value = this._getRadioFieldValueByName(name);
} else {
value = this._getFieldValueByName(name);
}
if (ruleObj.required) {
if (value.length > 0) {
result.isValid = true;
}
result.message = this.messageObject[name] ? this.messageObject[name] : this.defaults.messages.required;
} else if (ruleObj.required_if) {
result.isValid = true;
let conditionMatchCounter = 0;
for (let field of ruleObj.when) {
if (this._formRule[field.name]) {
const v = this._checkFieldByRule(field.name, this._formRule[field.name]);
if (field.val === v.value) {
conditionMatchCounter++;
}
}
}
if (conditionMatchCounter === ruleObj.when.length) {
result.isValid = value.length > 0 ? true : false;
}
result.message = this.messageObject[name] ? this.messageObject[name] : this.defaults.messages.required_if;
}
if (ruleObj.email && value.length > 0) {
const pattern = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
result.isValid = pattern.test(value);
result.message = this.messageObject[name] ? this.messageObject[name] : this.defaults.messages.email;
}
result.value = value;
return result;
}
_getFieldValueByName(name) {
const field = document.querySelector(`[name=${name}]`);
return field ? field.value.trim() : '';
}
_getArrayFieldValueByName(name) {
const arr = [];
const nodeList = document.querySelectorAll(`[name='${name}[]']`);
for (const node of nodeList) {
const value = node.value.trim();
if (value && value.length > 0) {
arr.push(node.value.trim());
}
}
return nodeList.length === arr.length ? arr.join('') : '';
}
_getRadioFieldValueByName(name) {
const field = document.querySelector(`[name=${name}]:checked`);
return field ? field.value.trim() : '';
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment