summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/gl_field_error.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/gl_field_error.js')
-rw-r--r--app/assets/javascripts/gl_field_error.js288
1 files changed, 143 insertions, 145 deletions
diff --git a/app/assets/javascripts/gl_field_error.js b/app/assets/javascripts/gl_field_error.js
index f7cbecc0385..76de249ac3b 100644
--- a/app/assets/javascripts/gl_field_error.js
+++ b/app/assets/javascripts/gl_field_error.js
@@ -1,164 +1,162 @@
-/* eslint-disable no-param-reassign */
-((global) => {
- /*
- * This class overrides the browser's validation error bubbles, displaying custom
- * error messages for invalid fields instead. To begin validating any form, add the
- * class `gl-show-field-errors` to the form element, and ensure error messages are
- * declared in each inputs' `title` attribute. If no title is declared for an invalid
- * field the user attempts to submit, "This field is required." will be shown by default.
- *
- * Opt not to validate certain fields by adding the class `gl-field-error-ignore` to the input.
- *
- * Set a custom error anchor for error message to be injected after with the
- * class `gl-field-error-anchor`
- *
- * Examples:
- *
- * Basic:
- *
- * <form class='gl-show-field-errors'>
- * <input type='text' name='username' title='Username is required.'/>
- * </form>
- *
- * Ignore specific inputs (e.g. UsernameValidator):
- *
- * <form class='gl-show-field-errors'>
- * <div class="form-group>
- * <input type='text' class='gl-field-errors-ignore' pattern='[a-zA-Z0-9-_]+'/>
- * </div>
- * <div class="form-group">
- * <input type='text' name='username' title='Username is required.'/>
- * </div>
- * </form>
- *
- * Custom Error Anchor (allows error message to be injected after specified element):
- *
- * <form class='gl-show-field-errors'>
- * <div class="form-group gl-field-error-anchor">
- * <input type='text' name='username' title='Username is required.'/>
- * // Error message typically injected here
- * </div>
- * // Error message now injected here
- * </form>
- *
- * */
-
- /*
- * Regex Patterns in use:
- *
- * Only alphanumeric: : "[a-zA-Z0-9]+"
- * No special characters : "[a-zA-Z0-9-_]+",
- *
- * */
-
- const errorMessageClass = 'gl-field-error';
- const inputErrorClass = 'gl-field-error-outline';
- const errorAnchorSelector = '.gl-field-error-anchor';
- const ignoreInputSelector = '.gl-field-error-ignore';
-
- class GlFieldError {
- constructor({ input, formErrors }) {
- this.inputElement = $(input);
- this.inputDomElement = this.inputElement.get(0);
- this.form = formErrors;
- this.errorMessage = this.inputElement.attr('title') || 'This field is required.';
- this.fieldErrorElement = $(`<p class='${errorMessageClass} hide'>${this.errorMessage}</p>`);
-
- this.state = {
- valid: false,
- empty: true,
- };
-
- this.initFieldValidation();
- }
+/**
+ * This class overrides the browser's validation error bubbles, displaying custom
+ * error messages for invalid fields instead. To begin validating any form, add the
+ * class `gl-show-field-errors` to the form element, and ensure error messages are
+ * declared in each inputs' `title` attribute. If no title is declared for an invalid
+ * field the user attempts to submit, "This field is required." will be shown by default.
+ *
+ * Opt not to validate certain fields by adding the class `gl-field-error-ignore` to the input.
+ *
+ * Set a custom error anchor for error message to be injected after with the
+ * class `gl-field-error-anchor`
+ *
+ * Examples:
+ *
+ * Basic:
+ *
+ * <form class='gl-show-field-errors'>
+ * <input type='text' name='username' title='Username is required.'/>
+ * </form>
+ *
+ * Ignore specific inputs (e.g. UsernameValidator):
+ *
+ * <form class='gl-show-field-errors'>
+ * <div class="form-group>
+ * <input type='text' class='gl-field-errors-ignore' pattern='[a-zA-Z0-9-_]+'/>
+ * </div>
+ * <div class="form-group">
+ * <input type='text' name='username' title='Username is required.'/>
+ * </div>
+ * </form>
+ *
+ * Custom Error Anchor (allows error message to be injected after specified element):
+ *
+ * <form class='gl-show-field-errors'>
+ * <div class="form-group gl-field-error-anchor">
+ * <input type='text' name='username' title='Username is required.'/>
+ * // Error message typically injected here
+ * </div>
+ * // Error message now injected here
+ * </form>
+ *
+ */
+
+/**
+ * Regex Patterns in use:
+ *
+ * Only alphanumeric: : "[a-zA-Z0-9]+"
+ * No special characters : "[a-zA-Z0-9-_]+",
+ *
+ */
+
+const errorMessageClass = 'gl-field-error';
+const inputErrorClass = 'gl-field-error-outline';
+const errorAnchorSelector = '.gl-field-error-anchor';
+const ignoreInputSelector = '.gl-field-error-ignore';
+
+class GlFieldError {
+ constructor({ input, formErrors }) {
+ this.inputElement = $(input);
+ this.inputDomElement = this.inputElement.get(0);
+ this.form = formErrors;
+ this.errorMessage = this.inputElement.attr('title') || 'This field is required.';
+ this.fieldErrorElement = $(`<p class='${errorMessageClass} hide'>${this.errorMessage}</p>`);
+
+ this.state = {
+ valid: false,
+ empty: true,
+ };
+
+ this.initFieldValidation();
+ }
- initFieldValidation() {
- const customErrorAnchor = this.inputElement.parents(errorAnchorSelector);
- const errorAnchor = customErrorAnchor.length ? customErrorAnchor : this.inputElement;
+ initFieldValidation() {
+ const customErrorAnchor = this.inputElement.parents(errorAnchorSelector);
+ const errorAnchor = customErrorAnchor.length ? customErrorAnchor : this.inputElement;
- // hidden when injected into DOM
- errorAnchor.after(this.fieldErrorElement);
- this.inputElement.off('invalid').on('invalid', this.handleInvalidSubmit.bind(this));
- this.scopedSiblings = this.safelySelectSiblings();
- }
+ // hidden when injected into DOM
+ errorAnchor.after(this.fieldErrorElement);
+ this.inputElement.off('invalid').on('invalid', this.handleInvalidSubmit.bind(this));
+ this.scopedSiblings = this.safelySelectSiblings();
+ }
- safelySelectSiblings() {
- // Apply `ignoreSelector` in markup to siblings whose visibility should not be toggled
- const unignoredSiblings = this.inputElement.siblings(`p:not(${ignoreInputSelector})`);
- const parentContainer = this.inputElement.parent('.form-group');
+ safelySelectSiblings() {
+ // Apply `ignoreSelector` in markup to siblings whose visibility should not be toggled
+ const unignoredSiblings = this.inputElement.siblings(`p:not(${ignoreInputSelector})`);
+ const parentContainer = this.inputElement.parent('.form-group');
- // Only select siblings when they're scoped within a form-group with one input
- const safelyScoped = parentContainer.length && parentContainer.find('input').length === 1;
+ // Only select siblings when they're scoped within a form-group with one input
+ const safelyScoped = parentContainer.length && parentContainer.find('input').length === 1;
- return safelyScoped ? unignoredSiblings : this.fieldErrorElement;
- }
+ return safelyScoped ? unignoredSiblings : this.fieldErrorElement;
+ }
- renderValidity() {
- this.renderClear();
+ renderValidity() {
+ this.renderClear();
- if (this.state.valid) {
- this.renderValid();
- } else if (this.state.empty) {
- this.renderEmpty();
- } else if (!this.state.valid) {
- this.renderInvalid();
- }
+ if (this.state.valid) {
+ this.renderValid();
+ } else if (this.state.empty) {
+ this.renderEmpty();
+ } else if (!this.state.valid) {
+ this.renderInvalid();
}
+ }
- handleInvalidSubmit(event) {
- event.preventDefault();
- const currentValue = this.accessCurrentValue();
- this.state.valid = false;
- this.state.empty = currentValue === '';
-
- this.renderValidity();
- this.form.focusOnFirstInvalid.apply(this.form);
- // For UX, wait til after first invalid submission to check each keyup
- this.inputElement.off('keyup.fieldValidator')
- .on('keyup.fieldValidator', this.updateValidity.bind(this));
- }
+ handleInvalidSubmit(event) {
+ event.preventDefault();
+ const currentValue = this.accessCurrentValue();
+ this.state.valid = false;
+ this.state.empty = currentValue === '';
+
+ this.renderValidity();
+ this.form.focusOnFirstInvalid.apply(this.form);
+ // For UX, wait til after first invalid submission to check each keyup
+ this.inputElement.off('keyup.fieldValidator')
+ .on('keyup.fieldValidator', this.updateValidity.bind(this));
+ }
- /* Get or set current input value */
- accessCurrentValue(newVal) {
- return newVal ? this.inputElement.val(newVal) : this.inputElement.val();
- }
+ /* Get or set current input value */
+ accessCurrentValue(newVal) {
+ return newVal ? this.inputElement.val(newVal) : this.inputElement.val();
+ }
- getInputValidity() {
- return this.inputDomElement.validity.valid;
- }
+ getInputValidity() {
+ return this.inputDomElement.validity.valid;
+ }
- updateValidity() {
- const inputVal = this.accessCurrentValue();
- this.state.empty = !inputVal.length;
- this.state.valid = this.getInputValidity();
- this.renderValidity();
- }
+ updateValidity() {
+ const inputVal = this.accessCurrentValue();
+ this.state.empty = !inputVal.length;
+ this.state.valid = this.getInputValidity();
+ this.renderValidity();
+ }
- renderValid() {
- return this.renderClear();
- }
+ renderValid() {
+ return this.renderClear();
+ }
- renderEmpty() {
- return this.renderInvalid();
- }
+ renderEmpty() {
+ return this.renderInvalid();
+ }
- renderInvalid() {
- this.inputElement.addClass(inputErrorClass);
- this.scopedSiblings.hide();
- return this.fieldErrorElement.show();
- }
+ renderInvalid() {
+ this.inputElement.addClass(inputErrorClass);
+ this.scopedSiblings.hide();
+ return this.fieldErrorElement.show();
+ }
- renderClear() {
- const inputVal = this.accessCurrentValue();
- if (!inputVal.split(' ').length) {
- const trimmedInput = inputVal.trim();
- this.accessCurrentValue(trimmedInput);
- }
- this.inputElement.removeClass(inputErrorClass);
- this.scopedSiblings.hide();
- this.fieldErrorElement.hide();
+ renderClear() {
+ const inputVal = this.accessCurrentValue();
+ if (!inputVal.split(' ').length) {
+ const trimmedInput = inputVal.trim();
+ this.accessCurrentValue(trimmedInput);
}
+ this.inputElement.removeClass(inputErrorClass);
+ this.scopedSiblings.hide();
+ this.fieldErrorElement.hide();
}
+}
- global.GlFieldError = GlFieldError;
-})(window.gl || (window.gl = {}));
+window.gl = window.gl || {};
+window.gl.GlFieldError = GlFieldError;