UNPKG

@govuk-pay/pay-js-commons

Version:

Reusable js scripts for GOV.UK Pay Node.js projects

108 lines (106 loc) 4.11 kB
'use strict'; // NPM Dependencies var every = require('lodash/every'); // Local Dependencies var checks = require('../../utils/field-validation-checks'); exports.enableFieldValidation = function () { var allForms = Array.prototype.slice.call(document.getElementsByTagName('form')); allForms.filter(function (form) { return form.hasAttribute('data-validate'); }).map(function (form) { return form.addEventListener('submit', initValidation, false); }); }; function initValidation(e) { var form = e.target; e.preventDefault(); clearPreviousErrors(); var validatedFields = findFields(form).map(function (field) { return validateField(form, field); }); if (every(validatedFields)) { form.submit(); } else { populateErrorSummary(form); } } function clearPreviousErrors() { var previousErrorsMessages = Array.prototype.slice.call(document.querySelectorAll('.error-message, .error-summary')); var previousErrorsFields = Array.prototype.slice.call(document.querySelectorAll('.form-group.error')); previousErrorsMessages.map(function (error) { return error.remove(); }); previousErrorsFields.map(function (errorField) { return errorField.classList.remove('error'); }); } function findFields(form) { var formFields = Array.prototype.slice.call(form.querySelectorAll('input, textarea, select')); return formFields.filter(function (field) { return field.hasAttribute('data-validate'); }); } function validateField(form, field) { var result; var validationTypes = field.getAttribute('data-validate').split(' '); validationTypes.forEach(function (validationType) { switch (validationType) { case 'required': result = checks.isEmpty(field.value); break; case 'currency': result = checks.isCurrency(field.value); break; case 'email': result = checks.isValidEmail(field.value); break; case 'phone': result = checks.isPhoneNumber(field.value); break; case 'https': result = checks.isHttps(field.value); break; case 'belowMaxAmount': result = checks.isAboveMaxAmount(field.value); break; case 'passwordLessThanTenChars': result = checks.isPasswordLessThanTenChars(field.value); break; case 'isFieldGreaterThanMaxLengthChars': result = checks.isFieldGreaterThanMaxLengthChars(field.value, field.getAttribute('data-validate-max-length')); break; case 'isNaxsiSafe': result = checks.isNaxsiSafe(field.value); break; default: result = false; break; } if (result) { applyErrorMessaging(form, field, result); } }); return !field.closest('.form-group').classList.contains('error'); } function applyErrorMessaging(form, field, result) { var formGroup = field.closest('.form-group'); if (!formGroup.classList.contains('error')) { formGroup.classList.add('error'); document.querySelector('label[for="' + field.id + '"]').insertAdjacentHTML('beforeend', '<span class="error-message">' + result + '</span>'); } } function populateErrorSummary(form) { var erroringFields = Array.prototype.slice.call(form.querySelectorAll('.form-group.error label')); var errorMessages = erroringFields.map(function (field) { var id = field.getAttribute('for'); var label = field.innerHTML.split('<')[0].trim(); return { label: label, id: id }; }); form.parentNode.insertAdjacentHTML('afterbegin', "<div id=\"error-summary\" class=\"error-summary\" role=\"group\" aria-labelledby=\"error-summary-heading\" tabindex=\"-1\">\n <h2 class=\"heading-medium error-summary-heading\" id=\"error-summary-heading\">\n There was a problem with the details you gave for:\n </h2>\n <ul class=\"error-summary-list\">\n ".concat(errorMessages.map(function (message) { return "<li class=\"error-".concat(message.id, "\"><a href=\"#").concat(message.id, "\">").concat(message.label, "</a></li>"); }).join(''), "\n </ul>\n </div>")); window.scroll(0, 0); }