diff --git a/dist/client-side-validations.esm.js b/dist/client-side-validations.esm.js index 430701de..13ed1f92 100644 --- a/dist/client-side-validations.esm.js +++ b/dist/client-side-validations.esm.js @@ -16,6 +16,23 @@ function _typeof(o) { }, _typeof(o); } +var arrayHasValue = function arrayHasValue(value, otherValues) { + for (var i = 0, l = otherValues.length; i < l; i++) { + if (value === otherValues[i]) { + return true; + } + } + return false; +}; +var createElementFromHTML = function createElementFromHTML(html) { + var element = document.createElement('div'); + element.innerHTML = html; + return element.firstChild; +}; +var isValuePresent = function isValuePresent(value) { + return !/^\s*$/.test(value || ''); +}; + var ClientSideValidations = { callbacks: { element: { @@ -153,35 +170,56 @@ var ClientSideValidations = { formBuilders: { 'ActionView::Helpers::FormBuilder': { add: function add($element, settings, message) { - var $form = jQuery($element[0].form); - if ($element.data('valid') !== false && $form.find("label.message[for=\"".concat($element.attr('id'), "\"]"))[0] == null) { - var $inputErrorField = jQuery(settings.input_tag); - var $labelErrorField = jQuery(settings.label_tag); - var $label = $form.find("label[for=\"".concat($element.attr('id'), "\"]:not(.message)")); - if ($element.attr('autofocus')) { - $element.attr('autofocus', false); + var element = $element[0]; + var form = element.form; + var inputErrorTemplate = createElementFromHTML(settings.input_tag); + var inputErrorElement = element.closest(".".concat(inputErrorTemplate.getAttribute('class').replace(/ /g, '.'))); + if (!inputErrorElement) { + inputErrorElement = inputErrorTemplate; + if (element.getAttribute('autofocus')) { + element.setAttribute('autofocus', false); + } + element.before(inputErrorElement); + inputErrorElement.querySelector('span#input_tag').replaceWith(element); + var inputErrorLabelMessageElement = inputErrorElement.querySelector('label.message'); + if (inputErrorLabelMessageElement) { + inputErrorLabelMessageElement.setAttribute('for', element.id); + } + } + var labelElement = form.querySelector("label[for=\"".concat(element.id, "\"]:not(.message)")); + if (labelElement) { + var labelErrorTemplate = createElementFromHTML(settings.label_tag); + var labelErrorContainer = labelElement.closest(".".concat(labelErrorTemplate.getAttribute('class').replace(/ /g, '.'))); + if (!labelErrorContainer) { + labelElement.after(labelErrorTemplate); + labelErrorTemplate.querySelector('label#label_tag').replaceWith(labelElement); } - $element.before($inputErrorField); - $inputErrorField.find('span#input_tag').replaceWith($element); - $inputErrorField.find('label.message').attr('for', $element.attr('id')); - $labelErrorField.find('label.message').attr('for', $element.attr('id')); - $labelErrorField.insertAfter($label); - $labelErrorField.find('label#label_tag').replaceWith($label); } - $form.find("label.message[for=\"".concat($element.attr('id'), "\"]")).text(message); + var labelMessageElement = form.querySelector("label.message[for=\"".concat(element.id, "\"]")); + if (labelMessageElement) { + labelMessageElement.textContent = message; + } }, remove: function remove($element, settings) { - var $form = jQuery($element[0].form); - var $inputErrorFieldClass = jQuery(settings.input_tag).attr('class'); - var $inputErrorField = $element.closest(".".concat($inputErrorFieldClass.replace(/ /g, '.'))); - var $label = $form.find("label[for=\"".concat($element.attr('id'), "\"]:not(.message)")); - var $labelErrorFieldClass = jQuery(settings.label_tag).attr('class'); - var $labelErrorField = $label.closest(".".concat($labelErrorFieldClass.replace(/ /g, '.'))); - if ($inputErrorField[0]) { - $inputErrorField.find("#".concat($element.attr('id'))).detach(); - $inputErrorField.replaceWith($element); - $label.detach(); - $labelErrorField.replaceWith($label); + var element = $element[0]; + var form = element.form; + var inputErrorClass = createElementFromHTML(settings.input_tag).getAttribute('class'); + var inputErrorElement = element.closest(".".concat(inputErrorClass.replace(/ /g, '.'))); + if (inputErrorElement) { + inputErrorElement.querySelector("#".concat(element.id)).remove(); + inputErrorElement.replaceWith(element); + } + var labelElement = form.querySelector("label[for=\"".concat(element.id, "\"]:not(.message)")); + if (labelElement) { + var labelErrorClass = createElementFromHTML(settings.label_tag).getAttribute('class'); + var labelErrorElement = labelElement.closest(".".concat(labelErrorClass.replace(/ /g, '.'))); + if (labelErrorElement) { + labelErrorElement.replaceWith(labelElement); + } + } + var labelMessageElement = form.querySelector("label.message[for=\"".concat(element.id, "\"]")); + if (labelMessageElement) { + labelMessageElement.remove(); } } } @@ -245,18 +283,6 @@ var ClientSideValidations = { } }; -var arrayHasValue = function arrayHasValue(value, otherValues) { - for (var i = 0, l = otherValues.length; i < l; i++) { - if (value === otherValues[i]) { - return true; - } - } - return false; -}; -var isValuePresent = function isValuePresent(value) { - return !/^\s*$/.test(value || ''); -}; - var absenceLocalValidator = function absenceLocalValidator($element, options) { var element = $element[0]; if (isValuePresent(element.value)) { diff --git a/dist/client-side-validations.js b/dist/client-side-validations.js index adb0b324..91cd4e2a 100644 --- a/dist/client-side-validations.js +++ b/dist/client-side-validations.js @@ -20,6 +20,23 @@ }, _typeof(o); } + var arrayHasValue = function arrayHasValue(value, otherValues) { + for (var i = 0, l = otherValues.length; i < l; i++) { + if (value === otherValues[i]) { + return true; + } + } + return false; + }; + var createElementFromHTML = function createElementFromHTML(html) { + var element = document.createElement('div'); + element.innerHTML = html; + return element.firstChild; + }; + var isValuePresent = function isValuePresent(value) { + return !/^\s*$/.test(value || ''); + }; + var ClientSideValidations = { callbacks: { element: { @@ -157,35 +174,56 @@ formBuilders: { 'ActionView::Helpers::FormBuilder': { add: function add($element, settings, message) { - var $form = jQuery($element[0].form); - if ($element.data('valid') !== false && $form.find("label.message[for=\"".concat($element.attr('id'), "\"]"))[0] == null) { - var $inputErrorField = jQuery(settings.input_tag); - var $labelErrorField = jQuery(settings.label_tag); - var $label = $form.find("label[for=\"".concat($element.attr('id'), "\"]:not(.message)")); - if ($element.attr('autofocus')) { - $element.attr('autofocus', false); + var element = $element[0]; + var form = element.form; + var inputErrorTemplate = createElementFromHTML(settings.input_tag); + var inputErrorElement = element.closest(".".concat(inputErrorTemplate.getAttribute('class').replace(/ /g, '.'))); + if (!inputErrorElement) { + inputErrorElement = inputErrorTemplate; + if (element.getAttribute('autofocus')) { + element.setAttribute('autofocus', false); + } + element.before(inputErrorElement); + inputErrorElement.querySelector('span#input_tag').replaceWith(element); + var inputErrorLabelMessageElement = inputErrorElement.querySelector('label.message'); + if (inputErrorLabelMessageElement) { + inputErrorLabelMessageElement.setAttribute('for', element.id); + } + } + var labelElement = form.querySelector("label[for=\"".concat(element.id, "\"]:not(.message)")); + if (labelElement) { + var labelErrorTemplate = createElementFromHTML(settings.label_tag); + var labelErrorContainer = labelElement.closest(".".concat(labelErrorTemplate.getAttribute('class').replace(/ /g, '.'))); + if (!labelErrorContainer) { + labelElement.after(labelErrorTemplate); + labelErrorTemplate.querySelector('label#label_tag').replaceWith(labelElement); } - $element.before($inputErrorField); - $inputErrorField.find('span#input_tag').replaceWith($element); - $inputErrorField.find('label.message').attr('for', $element.attr('id')); - $labelErrorField.find('label.message').attr('for', $element.attr('id')); - $labelErrorField.insertAfter($label); - $labelErrorField.find('label#label_tag').replaceWith($label); } - $form.find("label.message[for=\"".concat($element.attr('id'), "\"]")).text(message); + var labelMessageElement = form.querySelector("label.message[for=\"".concat(element.id, "\"]")); + if (labelMessageElement) { + labelMessageElement.textContent = message; + } }, remove: function remove($element, settings) { - var $form = jQuery($element[0].form); - var $inputErrorFieldClass = jQuery(settings.input_tag).attr('class'); - var $inputErrorField = $element.closest(".".concat($inputErrorFieldClass.replace(/ /g, '.'))); - var $label = $form.find("label[for=\"".concat($element.attr('id'), "\"]:not(.message)")); - var $labelErrorFieldClass = jQuery(settings.label_tag).attr('class'); - var $labelErrorField = $label.closest(".".concat($labelErrorFieldClass.replace(/ /g, '.'))); - if ($inputErrorField[0]) { - $inputErrorField.find("#".concat($element.attr('id'))).detach(); - $inputErrorField.replaceWith($element); - $label.detach(); - $labelErrorField.replaceWith($label); + var element = $element[0]; + var form = element.form; + var inputErrorClass = createElementFromHTML(settings.input_tag).getAttribute('class'); + var inputErrorElement = element.closest(".".concat(inputErrorClass.replace(/ /g, '.'))); + if (inputErrorElement) { + inputErrorElement.querySelector("#".concat(element.id)).remove(); + inputErrorElement.replaceWith(element); + } + var labelElement = form.querySelector("label[for=\"".concat(element.id, "\"]:not(.message)")); + if (labelElement) { + var labelErrorClass = createElementFromHTML(settings.label_tag).getAttribute('class'); + var labelErrorElement = labelElement.closest(".".concat(labelErrorClass.replace(/ /g, '.'))); + if (labelErrorElement) { + labelErrorElement.replaceWith(labelElement); + } + } + var labelMessageElement = form.querySelector("label.message[for=\"".concat(element.id, "\"]")); + if (labelMessageElement) { + labelMessageElement.remove(); } } } @@ -249,18 +287,6 @@ } }; - var arrayHasValue = function arrayHasValue(value, otherValues) { - for (var i = 0, l = otherValues.length; i < l; i++) { - if (value === otherValues[i]) { - return true; - } - } - return false; - }; - var isValuePresent = function isValuePresent(value) { - return !/^\s*$/.test(value || ''); - }; - var absenceLocalValidator = function absenceLocalValidator($element, options) { var element = $element[0]; if (isValuePresent(element.value)) { diff --git a/src/core.js b/src/core.js index 8c4134d2..26a18023 100644 --- a/src/core.js +++ b/src/core.js @@ -1,4 +1,5 @@ import jQuery from 'jquery' +import { createElementFromHTML } from './utils' const ClientSideValidations = { callbacks: { @@ -140,38 +141,76 @@ const ClientSideValidations = { formBuilders: { 'ActionView::Helpers::FormBuilder': { add: ($element, settings, message) => { - const $form = jQuery($element[0].form) - - if ($element.data('valid') !== false && ($form.find(`label.message[for="${$element.attr('id')}"]`)[0] == null)) { - const $inputErrorField = jQuery(settings.input_tag) - const $labelErrorField = jQuery(settings.label_tag) - const $label = $form.find(`label[for="${$element.attr('id')}"]:not(.message)`) - if ($element.attr('autofocus')) { - $element.attr('autofocus', false) + const element = $element[0] + + const form = element.form + + const inputErrorTemplate = createElementFromHTML(settings.input_tag) + let inputErrorElement = element.closest(`.${inputErrorTemplate.getAttribute('class').replace(/ /g, '.')}`) + + if (!inputErrorElement) { + inputErrorElement = inputErrorTemplate + + if (element.getAttribute('autofocus')) { + element.setAttribute('autofocus', false) + } + + element.before(inputErrorElement) + inputErrorElement.querySelector('span#input_tag').replaceWith(element) + + const inputErrorLabelMessageElement = inputErrorElement.querySelector('label.message') + + if (inputErrorLabelMessageElement) { + inputErrorLabelMessageElement.setAttribute('for', element.id) } - $element.before($inputErrorField) - $inputErrorField.find('span#input_tag').replaceWith($element) - $inputErrorField.find('label.message').attr('for', $element.attr('id')) - $labelErrorField.find('label.message').attr('for', $element.attr('id')) - $labelErrorField.insertAfter($label) - $labelErrorField.find('label#label_tag').replaceWith($label) } - $form.find(`label.message[for="${$element.attr('id')}"]`).text(message) + + const labelElement = form.querySelector(`label[for="${element.id}"]:not(.message)`) + + if (labelElement) { + const labelErrorTemplate = createElementFromHTML(settings.label_tag) + const labelErrorContainer = labelElement.closest(`.${labelErrorTemplate.getAttribute('class').replace(/ /g, '.')}`) + + if (!labelErrorContainer) { + labelElement.after(labelErrorTemplate) + labelErrorTemplate.querySelector('label#label_tag').replaceWith(labelElement) + } + } + + const labelMessageElement = form.querySelector(`label.message[for="${element.id}"]`) + + if (labelMessageElement) { + labelMessageElement.textContent = message + } }, remove: ($element, settings) => { - const $form = jQuery($element[0].form) - const $inputErrorFieldClass = jQuery(settings.input_tag).attr('class') - const $inputErrorField = $element.closest(`.${$inputErrorFieldClass.replace(/ /g, '.')}`) - const $label = $form.find(`label[for="${$element.attr('id')}"]:not(.message)`) - - const $labelErrorFieldClass = jQuery(settings.label_tag).attr('class') - const $labelErrorField = $label.closest(`.${$labelErrorFieldClass.replace(/ /g, '.')}`) - - if ($inputErrorField[0]) { - $inputErrorField.find(`#${$element.attr('id')}`).detach() - $inputErrorField.replaceWith($element) - $label.detach() - $labelErrorField.replaceWith($label) + const element = $element[0] + + const form = element.form + + const inputErrorClass = createElementFromHTML(settings.input_tag).getAttribute('class') + const inputErrorElement = element.closest(`.${inputErrorClass.replace(/ /g, '.')}`) + + if (inputErrorElement) { + inputErrorElement.querySelector(`#${element.id}`).remove() + inputErrorElement.replaceWith(element) + } + + const labelElement = form.querySelector(`label[for="${element.id}"]:not(.message)`) + + if (labelElement) { + const labelErrorClass = createElementFromHTML(settings.label_tag).getAttribute('class') + const labelErrorElement = labelElement.closest(`.${labelErrorClass.replace(/ /g, '.')}`) + + if (labelErrorElement) { + labelErrorElement.replaceWith(labelElement) + } + } + + const labelMessageElement = form.querySelector(`label.message[for="${element.id}"]`) + + if (labelMessageElement) { + labelMessageElement.remove() } } } diff --git a/src/helpers.js b/src/helpers.js deleted file mode 100644 index f135535b..00000000 --- a/src/helpers.js +++ /dev/null @@ -1,18 +0,0 @@ -export const arrayHasValue = (value, otherValues) => { - for (let i = 0, l = otherValues.length; i < l; i++) { - if (value === otherValues[i]) { - return true - } - } - - return false -} - -export const isValuePresent = (value) => { - return !/^\s*$/.test(value || '') -} - -export default { - arrayHasValue, - isValuePresent -} diff --git a/src/utils.js b/src/utils.js new file mode 100644 index 00000000..ef5b68ae --- /dev/null +++ b/src/utils.js @@ -0,0 +1,40 @@ +export const addClass = (element, customClass) => { + if (customClass) { + element.classList.add(...customClass.split(' ')) + } +} + +export const arrayHasValue = (value, otherValues) => { + for (let i = 0, l = otherValues.length; i < l; i++) { + if (value === otherValues[i]) { + return true + } + } + + return false +} + +export const createElementFromHTML = (html) => { + const element = document.createElement('div') + element.innerHTML = html + + return element.firstChild +} + +export const isValuePresent = (value) => { + return !/^\s*$/.test(value || '') +} + +export const removeClass = (element, customClass) => { + if (customClass) { + element.classList.remove(...customClass.split(' ')) + } +} + +export default { + addClass, + arrayHasValue, + createElementFromHTML, + isValuePresent, + removeClass +} diff --git a/src/validators/local/absence_presence.js b/src/validators/local/absence_presence.js index 87cd4b06..acaee991 100644 --- a/src/validators/local/absence_presence.js +++ b/src/validators/local/absence_presence.js @@ -1,4 +1,4 @@ -import { isValuePresent } from '../../helpers' +import { isValuePresent } from '../../utils' export const absenceLocalValidator = ($element, options) => { const element = $element[0] diff --git a/src/validators/local/acceptance.js b/src/validators/local/acceptance.js index 49bc5215..62b26687 100644 --- a/src/validators/local/acceptance.js +++ b/src/validators/local/acceptance.js @@ -1,4 +1,4 @@ -import { arrayHasValue } from '../../helpers' +import { arrayHasValue } from '../../utils' const DEFAULT_ACCEPT_OPTION = ['1', true] diff --git a/src/validators/local/exclusion_inclusion.js b/src/validators/local/exclusion_inclusion.js index db313b9a..6783dddd 100644 --- a/src/validators/local/exclusion_inclusion.js +++ b/src/validators/local/exclusion_inclusion.js @@ -1,4 +1,4 @@ -import { arrayHasValue, isValuePresent } from '../../helpers' +import { arrayHasValue, isValuePresent } from '../../utils' const isInList = (value, otherValues) => { const normalizedOtherValues = [] diff --git a/src/validators/local/format.js b/src/validators/local/format.js index 66c51e35..4d3936dd 100644 --- a/src/validators/local/format.js +++ b/src/validators/local/format.js @@ -1,4 +1,4 @@ -import { isValuePresent } from '../../helpers' +import { isValuePresent } from '../../utils' const isMatching = (value, regExpOptions) => { return new RegExp(regExpOptions.source, regExpOptions.options).test(value) diff --git a/src/validators/local/length.js b/src/validators/local/length.js index 3b2c6f12..2b22dc2d 100644 --- a/src/validators/local/length.js +++ b/src/validators/local/length.js @@ -1,4 +1,4 @@ -import { isValuePresent } from '../../helpers' +import { isValuePresent } from '../../utils' const VALIDATIONS = { is: (a, b) => { diff --git a/src/validators/local/numericality.js b/src/validators/local/numericality.js index 46e00d69..85e2bf9a 100644 --- a/src/validators/local/numericality.js +++ b/src/validators/local/numericality.js @@ -1,5 +1,5 @@ import ClientSideValidations from '../../core' -import { isValuePresent } from '../../helpers' +import { isValuePresent } from '../../utils' const VALIDATIONS = { even: (a) => { diff --git a/vendor/assets/javascripts/rails.validations.js b/vendor/assets/javascripts/rails.validations.js index adb0b324..91cd4e2a 100644 --- a/vendor/assets/javascripts/rails.validations.js +++ b/vendor/assets/javascripts/rails.validations.js @@ -20,6 +20,23 @@ }, _typeof(o); } + var arrayHasValue = function arrayHasValue(value, otherValues) { + for (var i = 0, l = otherValues.length; i < l; i++) { + if (value === otherValues[i]) { + return true; + } + } + return false; + }; + var createElementFromHTML = function createElementFromHTML(html) { + var element = document.createElement('div'); + element.innerHTML = html; + return element.firstChild; + }; + var isValuePresent = function isValuePresent(value) { + return !/^\s*$/.test(value || ''); + }; + var ClientSideValidations = { callbacks: { element: { @@ -157,35 +174,56 @@ formBuilders: { 'ActionView::Helpers::FormBuilder': { add: function add($element, settings, message) { - var $form = jQuery($element[0].form); - if ($element.data('valid') !== false && $form.find("label.message[for=\"".concat($element.attr('id'), "\"]"))[0] == null) { - var $inputErrorField = jQuery(settings.input_tag); - var $labelErrorField = jQuery(settings.label_tag); - var $label = $form.find("label[for=\"".concat($element.attr('id'), "\"]:not(.message)")); - if ($element.attr('autofocus')) { - $element.attr('autofocus', false); + var element = $element[0]; + var form = element.form; + var inputErrorTemplate = createElementFromHTML(settings.input_tag); + var inputErrorElement = element.closest(".".concat(inputErrorTemplate.getAttribute('class').replace(/ /g, '.'))); + if (!inputErrorElement) { + inputErrorElement = inputErrorTemplate; + if (element.getAttribute('autofocus')) { + element.setAttribute('autofocus', false); + } + element.before(inputErrorElement); + inputErrorElement.querySelector('span#input_tag').replaceWith(element); + var inputErrorLabelMessageElement = inputErrorElement.querySelector('label.message'); + if (inputErrorLabelMessageElement) { + inputErrorLabelMessageElement.setAttribute('for', element.id); + } + } + var labelElement = form.querySelector("label[for=\"".concat(element.id, "\"]:not(.message)")); + if (labelElement) { + var labelErrorTemplate = createElementFromHTML(settings.label_tag); + var labelErrorContainer = labelElement.closest(".".concat(labelErrorTemplate.getAttribute('class').replace(/ /g, '.'))); + if (!labelErrorContainer) { + labelElement.after(labelErrorTemplate); + labelErrorTemplate.querySelector('label#label_tag').replaceWith(labelElement); } - $element.before($inputErrorField); - $inputErrorField.find('span#input_tag').replaceWith($element); - $inputErrorField.find('label.message').attr('for', $element.attr('id')); - $labelErrorField.find('label.message').attr('for', $element.attr('id')); - $labelErrorField.insertAfter($label); - $labelErrorField.find('label#label_tag').replaceWith($label); } - $form.find("label.message[for=\"".concat($element.attr('id'), "\"]")).text(message); + var labelMessageElement = form.querySelector("label.message[for=\"".concat(element.id, "\"]")); + if (labelMessageElement) { + labelMessageElement.textContent = message; + } }, remove: function remove($element, settings) { - var $form = jQuery($element[0].form); - var $inputErrorFieldClass = jQuery(settings.input_tag).attr('class'); - var $inputErrorField = $element.closest(".".concat($inputErrorFieldClass.replace(/ /g, '.'))); - var $label = $form.find("label[for=\"".concat($element.attr('id'), "\"]:not(.message)")); - var $labelErrorFieldClass = jQuery(settings.label_tag).attr('class'); - var $labelErrorField = $label.closest(".".concat($labelErrorFieldClass.replace(/ /g, '.'))); - if ($inputErrorField[0]) { - $inputErrorField.find("#".concat($element.attr('id'))).detach(); - $inputErrorField.replaceWith($element); - $label.detach(); - $labelErrorField.replaceWith($label); + var element = $element[0]; + var form = element.form; + var inputErrorClass = createElementFromHTML(settings.input_tag).getAttribute('class'); + var inputErrorElement = element.closest(".".concat(inputErrorClass.replace(/ /g, '.'))); + if (inputErrorElement) { + inputErrorElement.querySelector("#".concat(element.id)).remove(); + inputErrorElement.replaceWith(element); + } + var labelElement = form.querySelector("label[for=\"".concat(element.id, "\"]:not(.message)")); + if (labelElement) { + var labelErrorClass = createElementFromHTML(settings.label_tag).getAttribute('class'); + var labelErrorElement = labelElement.closest(".".concat(labelErrorClass.replace(/ /g, '.'))); + if (labelErrorElement) { + labelErrorElement.replaceWith(labelElement); + } + } + var labelMessageElement = form.querySelector("label.message[for=\"".concat(element.id, "\"]")); + if (labelMessageElement) { + labelMessageElement.remove(); } } } @@ -249,18 +287,6 @@ } }; - var arrayHasValue = function arrayHasValue(value, otherValues) { - for (var i = 0, l = otherValues.length; i < l; i++) { - if (value === otherValues[i]) { - return true; - } - } - return false; - }; - var isValuePresent = function isValuePresent(value) { - return !/^\s*$/.test(value || ''); - }; - var absenceLocalValidator = function absenceLocalValidator($element, options) { var element = $element[0]; if (isValuePresent(element.value)) {