Skip to content

Commit

Permalink
Merge pull request #37 from michelegiorgi/development
Browse files Browse the repository at this point in the history
release 1.4.2
  • Loading branch information
michelegiorgi authored Nov 27, 2021
2 parents c73e7fb + 2455895 commit 6145061
Show file tree
Hide file tree
Showing 21 changed files with 303 additions and 504 deletions.
23 changes: 8 additions & 15 deletions assets/scripts/public/core/conditional.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { el, uid } from './helpers'
import 'parsleyjs'

export default {
init() {
Expand Down Expand Up @@ -43,7 +42,7 @@ export default {
valid = true;
} else if (index == 0 && (typeof rule[1] !== 'undefined') && rule[1].operator == "&&" ) {
valid = false;
break;
break;
} else if((rule[index].operator=="&&") && (rule[index]._key > 1)) {
valid = false;
break;
Expand Down Expand Up @@ -85,18 +84,12 @@ export default {
},
validation($field, disable=true) {
//reset validation if required
const $required = $field.find("[required]")
if($required) {
const navlink = ' li[data-name="' + $required.attr("id") + '"]'
if(disable) {
$required.attr("data-parsley-excluded", "true")
$(el("nav_list", true, navlink)).addClass("disabled")
} else {
$required.attr("data-parsley-excluded", "false")
$(el("nav_list", true, navlink)).removeClass("disabled")
}
uid($field)
$(el("form", "uid")).parsley().refresh()
const $input = $field.find("[required]")
if(disable) {
$field[0].setAttribute('data-excluded','')
} else {
$field[0].removeAttribute('data-excluded')
}
$(el("nav_list", true, ' li[data-name="' + $input.attr("name") + '"]')).toggleClass("disabled", disable)
},
}
}
4 changes: 2 additions & 2 deletions assets/scripts/public/core/nav.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ export default {
$(el("button", "uid", "--prev")).toggle(false)
$(el("button", "uid", "--next")).toggle(false)
}
validate.form()
}
})
},
Expand All @@ -87,7 +86,8 @@ export default {
})
function gotoStep(index) {
const currentstep = current();
if(validate.checkstep(currentstep, index)) {
const form = document.querySelector(el("form", "uid"))
if(validate.validateStep(form, currentstep, index)) {
const $steps = $(el("section", "uid"))
const $nav = $(el("nav_section", "uid"))
const atTheEnd = index >= $steps.length - 1
Expand Down
11 changes: 7 additions & 4 deletions assets/scripts/public/core/submit.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { el, uid } from './helpers'
import hooks from './hooks'
import validate from './validate'

/* eslint-disable no-unused-vars */

export default {
init() {
//init form submit
var submit = this
window.Parsley.on('form:init', function() {
$(this.$element).submit(function(e){
e.preventDefault()
let submit = this
let forms = document.querySelectorAll(el('form'))
forms.forEach(function(form) {
form.addEventListener("submit", function(e) {
e.preventDefault();
if(!validate.validateForm(form)) { return false; }
uid($(this))
submit.token()
hooks.event('FormSubmit')
Expand Down
4 changes: 3 additions & 1 deletion assets/scripts/public/core/uiux.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,9 @@ export default {
if($(el("button", "uid", "--next")).is(":visible")) {
$(el("button", "uid", "--next")).click()
} else {
$(el("form", "uid")).submit()
let form = document.querySelector(el("form", "uid"))
let event = new Event('submit', { 'bubbles': true, 'cancelable': true });
form.dispatchEvent(event);
}
} else {
//
Expand Down
262 changes: 179 additions & 83 deletions assets/scripts/public/core/validate.js
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
}
}
Loading

0 comments on commit 6145061

Please sign in to comment.