-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #37 from michelegiorgi/development
release 1.4.2
- Loading branch information
Showing
21 changed files
with
303 additions
and
504 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,101 +1,197 @@ | ||
import { el, uid } from './helpers' | ||
const { __ } = wp.i18n | ||
import 'parsleyjs' | ||
const { __, sprintf } = wp.i18n | ||
let fieldOptions = { | ||
text: { | ||
multiple: false, | ||
}, | ||
textarea: { | ||
multiple: false, | ||
}, | ||
email: { | ||
multiple: false, | ||
rules: { | ||
email: __("This value should be a valid email", "formality"), | ||
} | ||
}, | ||
number: { | ||
multiple: false, | ||
rules: { | ||
number: __("This value should be a valid number", "formality"), | ||
number_min: /* translators: validation */ __("This value should be greater than or equal to %s", "formality"), | ||
number_max: /* translators: validation */ __("This value should be lower than or equal to %s", "formality"), | ||
} | ||
}, | ||
select: { | ||
multiple: false, | ||
}, | ||
multiple: { | ||
multiple: true, | ||
}, | ||
rating: { | ||
multiple: true, | ||
}, | ||
switch: { | ||
multiple: false, | ||
}, | ||
upload: { | ||
multiple: false, | ||
rules: { | ||
file: __("This is not a valid file", "formality"), | ||
file_ext: /* translators: validation */ __('%s file extension is not allowed', 'formality'), | ||
file_size: __('Your file exceeds the size limit', 'formality'), | ||
} | ||
}, | ||
} | ||
|
||
export default { | ||
init() { | ||
//init validation | ||
$(el("form")).each(function() { | ||
uid($(this)) | ||
$(el("section", "uid")).each(function(index, section) { | ||
$(section).find(':input').attr('data-parsley-group', 'step-' + index) | ||
let validate = this; | ||
const forms = document.querySelectorAll(el("form")) | ||
forms.forEach(function(form){ | ||
validate.addStepIndexes(form) | ||
const inputs = form.querySelectorAll('input, select, textarea') | ||
inputs.forEach(function(input){ | ||
validate.liveUpdate(input) | ||
}) | ||
}) | ||
this.field_error() | ||
this.field_success() | ||
this.form_error() | ||
this.i18n() | ||
}, | ||
checkstep(index, newindex) { | ||
//validate single step | ||
let valid = false | ||
let options = this.parsley_options() | ||
if(index > newindex) { | ||
valid = true | ||
} else { | ||
$(el("form", "uid")).parsley(options).whenValidate({ | ||
group: 'step-' + index, | ||
}).done(function() { | ||
valid = true | ||
$(el("nav_section", "uid")).eq(index).addClass(el("nav_section", false, "--validated")) | ||
}, | ||
addStepIndexes(form) { | ||
const sections = form.querySelectorAll(el("section")) | ||
sections.forEach(function(section, index){ | ||
const fields = section.querySelectorAll(el("field")) | ||
fields.forEach(function(field){ | ||
field.setAttribute('data-step', index) | ||
}) | ||
}) | ||
}, | ||
liveUpdate(input) { | ||
let validate = this; | ||
input.addEventListener('input', function(){ | ||
let field = input.closest(el("field")) | ||
validate.validateField(field, true) | ||
}) | ||
}, | ||
validateStep(form, index, newindex) { | ||
if(index > newindex) { return true } | ||
const valid = this.validateForm(form, index) | ||
if(valid) { | ||
const sections = form.querySelectorAll(el("nav_section", "uid")) | ||
sections[index].classList.add(el("nav_section", false, "--validated")) | ||
} | ||
return valid | ||
}, | ||
form() { | ||
//validate standard form (1 step) | ||
let options = this.parsley_options() | ||
$(el("form", "uid")).parsley(options) | ||
}, | ||
parsley_options() { | ||
//create parsley options array | ||
let options = { | ||
classHandler: function (element) { | ||
return element.$element.closest(el("field")) | ||
}, | ||
errorClass: el("field_error", false), | ||
errorsContainer: function(element) { | ||
return element.$element.closest(el("input")).find(el("input", true, "__status")) | ||
}, | ||
successClass: el("field_success", false), | ||
errorsWrapper: '<ul class="'+el("input_errors", false)+'"></ul>', | ||
checkRule(input, rule) { | ||
let result = { | ||
valid: false, | ||
placeholder: '', | ||
} | ||
return options | ||
switch(rule) { | ||
case 'required': | ||
if(NodeList.prototype.isPrototypeOf(input)){ | ||
input.forEach(function(single, i){ if(single.checked) { result.valid = true; } }) | ||
} else { | ||
result.valid = input.value !== '' | ||
} | ||
break | ||
case 'email': | ||
result.valid = input.value.match(/^(([^<>()\[\]\\.,;:\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,}))$/) | ||
break | ||
case 'checked': | ||
result.valid = input.checked | ||
break | ||
case 'notchecked': | ||
result.valid = !input.checked | ||
break | ||
case 'number': | ||
result.valid = !isNaN(input.value) | ||
break | ||
case 'number_min': | ||
result.placeholder = input.min | ||
result.valid = parseFloat(input.value) >= result.placeholder | ||
break | ||
case 'number_max': | ||
result.placeholder = input.max | ||
result.valid = parseFloat(input.value) <= result.placeholder | ||
break | ||
case 'file': | ||
result.valid = input.files.length ? true : false | ||
break | ||
case 'file_ext': | ||
result.file = input.files.length ? input.files[0] : false | ||
if(result.file && result.file.type !== '') { | ||
result.formats = input.getAttribute('accept').split(", ") | ||
result.placeholder = ('.' + result.file.name.split('.').pop()).toLowerCase() | ||
result.valid = result.formats.indexOf(result.placeholder) !== -1 | ||
} | ||
break | ||
case 'file_size': | ||
result.file = input.files.length ? input.files[0] : false | ||
if(result.file && result.file.size > 0) { | ||
result.valid = result.file.size <= parseInt(input.getAttribute('data-max-size')) | ||
} | ||
break | ||
} | ||
return result; | ||
}, | ||
form_error() { | ||
window.Parsley.on('form:error', function() { | ||
|
||
}) | ||
changeFieldStatus(field, name, valid=true, error='') { | ||
const form = field.closest(el('form')) | ||
const status = field.querySelector(el('input_status')) | ||
const legend = form.querySelector(el('nav_legend', true, ' li[data-name="' + name + '"]')) | ||
field.classList.toggle(el("field", false, "--error"), !valid); | ||
status.innerHTML = !error ? '' : ('<div class="' + el("input_errors", false) + '">' + error + '</div>') | ||
if(legend) { legend.classList.toggle("error", !valid) } | ||
if(!valid) { | ||
const section = form.querySelector(el("nav_section", "uid", "--active")) | ||
if(section) { section.classList.remove(el("nav_section", false, "--validated")) } | ||
} | ||
field.classList.add(el("field", false, "--validated")); | ||
}, | ||
field_error() { | ||
//field error event | ||
window.Parsley.on('field:error', function() { | ||
const id = $(this.$element).attr("id") | ||
uid($(this.$element)) | ||
$(el("nav_legend", 'uid', ' li[data-name="' + id + '"]')).addClass("error") | ||
const index = $(el("nav_section", "uid")).index(el("nav_section", "uid", "--active")) | ||
$(el("nav_section", "uid")).eq(index).removeClass(el("nav_section", false, "--validated")) | ||
}) | ||
validateField(field, soft=false) { | ||
if(field.hasAttribute('data-excluded')) { return true } | ||
let validate = this; | ||
const type = field.getAttribute('data-type') | ||
const required = field.classList.contains(el("field", false, "--required")) | ||
const validated = field.classList.contains(el("field", false, "--validated")) | ||
let rules = 'rules' in fieldOptions[type] ? Object.keys(fieldOptions[type]['rules']) : [] | ||
const multiple = fieldOptions[type]['multiple'] | ||
if(required) { rules.unshift('required') } | ||
const input = multiple ? field.querySelectorAll('input, select, textarea') : field.querySelector('input, select, textarea') | ||
const name = multiple ? input[0].name : input.name | ||
let valid = true; | ||
let error = ''; | ||
if(!rules.includes('required') && !multiple && !input.value) { | ||
//skip validation | ||
} else { | ||
rules.forEach(function(rule){ | ||
if(valid) { | ||
const check = validate.checkRule(input, rule) | ||
if(!check.valid) { | ||
error = rule == 'required' ? __("This value is required", "formality") : sprintf(fieldOptions[type]['rules'][rule], check.placeholder); | ||
valid = false; | ||
} | ||
} | ||
}) | ||
} | ||
if(!soft || (soft && validated)) { | ||
validate.changeFieldStatus(field, name, valid, error) | ||
} | ||
return valid; | ||
}, | ||
field_success() { | ||
//field success event | ||
window.Parsley.on('field:success', function() { | ||
const id = $(this.$element).attr("id") | ||
uid($(this.$element)) | ||
$(el("nav_legend", "uid", ' li[data-name="' + id + '"]')).removeClass("error") | ||
validateForm(form, step=null) { | ||
let validate = this | ||
let errors = false | ||
const selector = step == null ? el("field") : el("field", true, '[data-step="'+step+'"]') | ||
let fields = form.querySelectorAll(selector) | ||
let firsterror = false | ||
fields.forEach(function(field, i){ | ||
const error = !validate.validateField(field) | ||
if(!errors && error) { | ||
errors = true | ||
firsterror = field.querySelector('input, select, textarea') | ||
} | ||
}) | ||
}, | ||
i18n() { | ||
window.Parsley.addMessages('en', { | ||
defaultMessage: __("This value seems to be invalid", "formality"), | ||
type: { | ||
email: __("This value should be a valid email", "formality"), | ||
url: __("This value should be a valid url", "formality"), | ||
number: __("This value should be a valid number", "formality"), | ||
integer: __("This value should be a valid integer", "formality"), | ||
digits: __("This value should be digits", "formality"), | ||
alphanum: __("This value should be alphanumeric", "formality"), | ||
}, | ||
required: __("This value is required", "formality"), | ||
pattern: __("This value seems to be invalid", "formality"), | ||
min: /* translators: validation */ __("This value should be greater than or equal to %s", "formality"), | ||
max: /* translators: validation */ __("This value should be lower than or equal to %s", "formality"), | ||
range: /* translators: validation */ __("This value should be between %s and %s", "formality"), | ||
minlength: /* translators: validation */ __("This value is too short. It should have %s characters or more", "formality"), | ||
maxlength: /* translators: validation */ __("This value is too long. It should have %s characters or fewer", "formality"), | ||
length: /* translators: validation */ __("This value length is invalid. It should be between %s and %s characters long", "formality"), | ||
check: /* translators: validation */ __("You must select between %s and %s choices", "formality"), | ||
}); | ||
window.Parsley.setLocale('en'); | ||
if(firsterror) { firsterror.focus() } | ||
return !errors | ||
} | ||
} |
Oops, something went wrong.