diff --git a/dist/bouncer.js b/dist/bouncer.js index a7aa608..d8434d3 100644 --- a/dist/bouncer.js +++ b/dist/bouncer.js @@ -1,7 +1,7 @@ /*! * formbouncerjs v1.4.6 * A lightweight form validation script that augments native HTML5 form validation elements and attributes. - * (c) 2019 Chris Ferdinandi + * (c) 2020 Chris Ferdinandi * MIT License * http://github.com/cferdinandi/bouncer */ @@ -82,6 +82,12 @@ // Form Submission disableSubmit: false, + + // Allow blur/click/input events to be opt-out + validateOnBlur: true, + + // Allow validation to be turned off altogether. Useful for server-side validation use. + validateOnSubmit: true, // Custom Events emitEvents: true @@ -536,6 +542,11 @@ } } + // Custom message, passed directly in + if (errors.customMessage) { + return errors.customMessage; + } + // Fallback error message return messages.fallback; @@ -686,6 +697,29 @@ // // Methods // + + /** + * Show an error message in the DOM + * @param {Node} field The field to show an error message for + * @param {Object} errors The errors on the field + * @param {Object} options Additional plugin settings + */ + publicAPIs.showError = function (field, errors, options) { + var _settings = extend(settings, options || {}); + + return showError(field, errors, _settings) + }; + + /** + * Remove an error message from the DOM + * @param {Node} field The field with the error message + * @param {Object} settings The plugin settings + */ + publicAPIs.removeError = function (field, options) { + var _settings = extend(settings, options || {}); + + return removeError(field, _settings); + }; /** * Validate a field @@ -797,10 +831,15 @@ publicAPIs.destroy = function () { // Remove event listeners - document.removeEventListener('blur', blurHandler, true); - document.removeEventListener('input', inputHandler, false); - document.removeEventListener('click', inputHandler, false); - document.removeEventListener('submit', submitHandler, false); + if (settings.validateOnBlur) { + document.removeEventListener('blur', blurHandler, true); + document.removeEventListener('input', inputHandler, false); + document.removeEventListener('click', inputHandler, false); + } + + if (settings.validateOnSubmit) { + document.removeEventListener('submit', submitHandler, false); + } // Remove all errors removeAllErrors(selector, settings); @@ -832,10 +871,15 @@ addNoValidate(selector); // Event Listeners - document.addEventListener('blur', blurHandler, true); - document.addEventListener('input', inputHandler, false); - document.addEventListener('click', inputHandler, false); - document.addEventListener('submit', submitHandler, false); + if (settings.validateOnBlur) { + document.addEventListener('blur', blurHandler, true); + document.addEventListener('input', inputHandler, false); + document.addEventListener('click', inputHandler, false); + } + + if (settings.validateOnSubmit) { + document.addEventListener('submit', submitHandler, false); + } // Emit custom event if (settings.emitEvents) { @@ -862,4 +906,4 @@ return Constructor; -})); \ No newline at end of file +})); diff --git a/dist/bouncer.min.js b/dist/bouncer.min.js index e498430..f083299 100644 --- a/dist/bouncer.min.js +++ b/dist/bouncer.min.js @@ -1,2 +1,2 @@ -/*! formbouncerjs v1.4.6 | (c) 2019 Chris Ferdinandi | MIT License | http://github.com/cferdinandi/bouncer */ -!(function(e,t){"function"==typeof define&&define.amd?define([],(function(){return t(e)})):"object"==typeof exports?module.exports=t(e):e.Bouncer=t(e)})("undefined"!=typeof global?global:"undefined"!=typeof window?window:this,(function(a){"use strict";var l={fieldClass:"error",errorClass:"error-message",fieldPrefix:"bouncer-field_",errorPrefix:"bouncer-error_",patterns:{email:/^([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22))*\x40([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d))*(\.\w{2,})+$/,url:/^(?:(?:https?|HTTPS?|ftp|FTP):\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-zA-Z\u00a1-\uffff0-9]-*)*[a-zA-Z\u00a1-\uffff0-9]+)(?:\.(?:[a-zA-Z\u00a1-\uffff0-9]-*)*[a-zA-Z\u00a1-\uffff0-9]+)*(?:\.(?:[a-zA-Z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/,number:/^(?:[-+]?[0-9]*[.,]?[0-9]+)$/,color:/^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/,date:/(?:19|20)[0-9]{2}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9])|(?:(?!02)(?:0[1-9]|1[0-2])-(?:30))|(?:(?:0[13578]|1[02])-31))/,time:/^(?:(0[0-9]|1[0-9]|2[0-3])(:[0-5][0-9]))$/,month:/^(?:(?:19|20)[0-9]{2}-(?:(?:0[1-9]|1[0-2])))$/},customValidations:{},messageAfterField:!0,messageCustom:"data-bouncer-message",messageTarget:"data-bouncer-target",messages:{missingValue:{checkbox:"This field is required.",radio:"Please select a value.",select:"Please select a value.","select-multiple":"Please select at least one value.",default:"Please fill out this field."},patternMismatch:{email:"Please enter a valid email address.",url:"Please enter a URL.",number:"Please enter a number",color:"Please match the following format: #rrggbb",date:"Please use the YYYY-MM-DD format",time:"Please use the 24-hour time format. Ex. 23:00",month:"Please use the YYYY-MM format",default:"Please match the requested format."},outOfRange:{over:"Please select a value that is no more than {max}.",under:"Please select a value that is no less than {min}."},wrongLength:{over:"Please shorten this text to no more than {maxLength} characters. You are currently using {length} characters.",under:"Please lengthen this text to {minLength} characters or more. You are currently using {length} characters."},fallback:"There was an error with this field."},disableSubmit:!1,emitEvents:!0},c=function(e,t){Array.prototype.forEach.call(e,t)},s=function(){var r={};return c(arguments,(function(e){for(var t in e){if(!e.hasOwnProperty(t))return;"[object Object]"===Object.prototype.toString.call(e[t])?r[t]=s(r[t],e[t]):r[t]=e[t]}})),r},f=function(e,t,r){if("function"==typeof a.CustomEvent){var n=new CustomEvent(t,{bubbles:!0,detail:r||{}});e.dispatchEvent(n)}},d=function(e,t){return{missingValue:(function(e){if(!e.hasAttribute("required"))return!1;if("checkbox"===e.type)return!e.checked;var t=e.value.length;return"radio"===e.type&&(t=Array.prototype.filter.call(e.form.querySelectorAll('[name="'+m(e.name)+'"]'),(function(e){return e.checked})).length),t<1})(e),patternMismatch:(r=e,n=t,a=r.getAttribute("pattern"),!(!(a=a?new RegExp("^(?:"+a+")$"):n.patterns[r.type])||!r.value||r.value.length<1||r.value.match(a))),outOfRange:(function(e){if(!e.value||e.value.length<1)return!1;var t=e.getAttribute("max"),r=e.getAttribute("min"),n=parseFloat(e.value);return t&&t