diff options
author | Bryce Johnson <bryce@gitlab.com> | 2016-10-21 13:49:09 +0200 |
---|---|---|
committer | Bryce Johnson <bryce@gitlab.com> | 2016-11-01 16:48:37 +0100 |
commit | 93bd3dd8a8f587dc860c72653364d853c27bc6fd (patch) | |
tree | b45644f71d9e21dec030480570d56848eda8ae12 /app | |
parent | aba94f65f039908d14643f3854e3c2901ff843aa (diff) | |
download | gitlab-ce-93bd3dd8a8f587dc860c72653364d853c27bc6fd.tar.gz |
Upgrade gl_field_errors to support more use cases.
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/javascripts/gl_field_errors.js.es6 | 54 | ||||
-rw-r--r-- | app/assets/javascripts/username_validator.js.es6 | 1 | ||||
-rw-r--r-- | app/assets/stylesheets/framework/forms.scss | 32 | ||||
-rw-r--r-- | app/assets/stylesheets/pages/login.scss | 30 | ||||
-rw-r--r-- | app/views/devise/shared/_signup_box.html.haml | 2 |
5 files changed, 82 insertions, 37 deletions
diff --git a/app/assets/javascripts/gl_field_errors.js.es6 b/app/assets/javascripts/gl_field_errors.js.es6 index be6c3ec274f..fa3e131c43b 100644 --- a/app/assets/javascripts/gl_field_errors.js.es6 +++ b/app/assets/javascripts/gl_field_errors.js.es6 @@ -4,18 +4,56 @@ * 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 `show-gl-field-errors` to the form element, and ensure error messages are - * declared in each inputs' title attribute. + * 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. * - * Example: + * 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='show-gl-field-errors'> * <input type='text' name='username' title='Username is required.'/> - *</form> + * </form> + * + * Ignore specific inputs (e.g. UsernameValidator): + * + * <form class='show-gl-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='show-gl-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 }) { @@ -34,16 +72,18 @@ } initFieldValidation() { + const customErrorAnchor = this.inputElement.parents(errorAnchorSelector); + const errorAnchor = customErrorAnchor.length ? customErrorAnchor : this.inputElement; + // hidden when injected into DOM - this.inputElement.after(this.fieldErrorElement); + 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 with input validity - const ignoreSelector = '.validation-ignore'; - const unignoredSiblings = this.inputElement.siblings(`p:not(${ignoreSelector})`); + 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 @@ -125,7 +165,7 @@ } } - const customValidationFlag = 'no-gl-field-errors'; + const customValidationFlag = 'gl-field-error-ignore'; class GlFieldErrors { constructor(form) { diff --git a/app/assets/javascripts/username_validator.js.es6 b/app/assets/javascripts/username_validator.js.es6 index c4dde575c6e..023ec0838dc 100644 --- a/app/assets/javascripts/username_validator.js.es6 +++ b/app/assets/javascripts/username_validator.js.es6 @@ -25,7 +25,6 @@ this.inputElement.on('keyup.username_check', () => { const username = this.inputElement.val(); - this.state.valid = this.inputDomElement.validity.valid; this.state.empty = !username.length; diff --git a/app/assets/stylesheets/framework/forms.scss b/app/assets/stylesheets/framework/forms.scss index 761c07384f4..514d0868ba1 100644 --- a/app/assets/stylesheets/framework/forms.scss +++ b/app/assets/stylesheets/framework/forms.scss @@ -136,3 +136,35 @@ label { color: $red-normal; } +.show-gl-field-errors { + .gl-field-success-outline { + border: 1px solid $green-normal; + + &:focus { + box-shadow: 0 0 0 1px $green-normal inset, 0 1px 1px rgba(0, 0, 0, 0.075) inset, 0 0 4px 0 $green-normal; + border: 0 none; + } + } + + .gl-field-error-outline { + border: 1px solid $red-normal; + + &:focus { + box-shadow: 0 0 0 1px $red-normal inset, 0 1px 1px rgba(0, 0, 0, 0.075) inset, 0 0 4px 0 rgba(210, 40, 82, 0.6); + border: 0 none; + } + } + + .gl-field-success-message { + color: $green-normal; + } + + .gl-field-error-message { + color: $red-normal; + } + + .gl-field-hint { + color: $gl-text-color; + } +} + diff --git a/app/assets/stylesheets/pages/login.scss b/app/assets/stylesheets/pages/login.scss index a2f5c6c6bd3..10f67b47998 100644 --- a/app/assets/stylesheets/pages/login.scss +++ b/app/assets/stylesheets/pages/login.scss @@ -75,43 +75,17 @@ .login-body { font-size: 13px; - input + p { margin-top: 5px; } - .gl-field-success-outline { - border: 1px solid $green-normal; - - &:focus { - box-shadow: 0 0 0 1px $green-normal inset, 0 1px 1px rgba(0, 0, 0, 0.075) inset, 0 0 4px 0 $green-normal; - border: 0 none; - } - } - - .gl-field-error-outline { - border: 1px solid $red-normal; - - &:focus { - box-shadow: 0 0 0 1px $red-normal inset, 0 1px 1px rgba(0, 0, 0, 0.075) inset, 0 0 4px 0 rgba(210, 40, 82, 0.6); - border: 0 none; - } - } - - .username .validation-success, - .gl-field-success-message { + .username .validation-success { color: $green-normal; } - .username .validation-error, - .gl-field-error-message { + .username .validation-error { color: $red-normal; } - - .gl-field-hint { - color: $gl-text-color; - } - } } diff --git a/app/views/devise/shared/_signup_box.html.haml b/app/views/devise/shared/_signup_box.html.haml index d0bbcf3115e..99cde88fb08 100644 --- a/app/views/devise/shared/_signup_box.html.haml +++ b/app/views/devise/shared/_signup_box.html.haml @@ -8,7 +8,7 @@ = f.text_field :name, class: "form-control top", required: true, title: "This field is required." %div.username.form-group = f.label :username - = f.text_field :username, class: "form-control middle no-gl-field-error", pattern: "[a-zA-Z0-9]+", required: true, title: 'Please create a username with only alphanumeric characters.' + = f.text_field :username, class: "form-control middle", pattern: "[a-zA-Z0-9]+", required: true, title: 'Please create a username with only alphanumeric characters.' %p.validation-error.hide Username is already taken. %p.validation-success.hide Username is available. %p.validation-pending.hide Checking username availability... |