diff options
author | Bryce Johnson <bryce@gitlab.com> | 2016-09-09 14:21:00 +0200 |
---|---|---|
committer | Bryce Johnson <bryce@gitlab.com> | 2016-10-15 08:27:21 +0200 |
commit | 1dd826d4aad2ce6c195bad24b458b1967b74db1d (patch) | |
tree | eca6776fe8b6221e5db79e6e99f2574cb18b52c9 /app/assets/javascripts/username_validator.js.es6 | |
parent | 602cac526d55d10ef05558c296ce7f27205801cc (diff) | |
download | gitlab-ce-1dd826d4aad2ce6c195bad24b458b1967b74db1d.tar.gz |
Make UX upgrades to SignIn/Register views.
- Tab between register and sign in forms
- Add individual input validation error messages
- Validate username
- Update many styles for all login-box forms
Diffstat (limited to 'app/assets/javascripts/username_validator.js.es6')
-rw-r--r-- | app/assets/javascripts/username_validator.js.es6 | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/app/assets/javascripts/username_validator.js.es6 b/app/assets/javascripts/username_validator.js.es6 new file mode 100644 index 00000000000..f8be356af04 --- /dev/null +++ b/app/assets/javascripts/username_validator.js.es6 @@ -0,0 +1,131 @@ +((global) => { + const debounceTimeoutDuration = 1000; + const inputErrorClass = 'gl-field-error-outline'; + const inputSuccessClass = 'gl-field-success-outline'; + const messageErrorSelector = '.username .validation-error'; + const messageSuccessSelector = '.username .validation-success'; + const messagePendingSelector = '.username .validation-pending'; + + class UsernameValidator { + constructor() { + this.inputElement = $('#new_user_username'); + this.inputDomElement = this.inputElement.get(0); + + this.available = false; + this.valid = false; + this.pending = false; + this.fresh = true; + this.empty = true; + + const debounceTimeout = _.debounce((username) => { + this.validateUsername(username); + }, debounceTimeoutDuration); + + this.inputElement.on('keyup.username_check', () => { + const username = this.inputElement.val(); + + this.valid = this.inputDomElement.validity.valid; + this.fresh = false; + this.empty = !username.length; + + if (this.valid) { + return debounceTimeout(username); + } + + this.renderState(); + }); + + // Override generic field validation + this.inputElement.on('invalid', this.handleInvalidInput.bind(this)); + } + + renderState() { + // Clear all state + this.clearFieldValidationState(); + + if (this.valid && this.available) { + return this.setSuccessState(); + } + + if (this.empty) { + return this.clearFieldValidationState(); + } + + if (this.pending) { + return this.setPendingState(); + } + + if (!this.available) { + return this.setUnavailableState(); + } + + if (!this.valid) { + return this.setInvalidState(); + } + } + + handleInvalidInput(event) { + event.preventDefault(); + event.stopPropagation(); + } + + validateUsername(username) { + if (this.valid) { + this.pending = true; + this.available = false; + this.renderState(); + return $.ajax({ + type: 'GET', + url: `/u/${username}/exists`, + dataType: 'json', + success: (res) => this.updateValidationState(res.exists) + }); + } + } + + updateValidationState(usernameTaken) { + if (usernameTaken) { + this.valid = false; + this.available = false; + } else { + this.available = true; + } + this.pending = false; + this.renderState(); + } + + clearFieldValidationState() { + this.inputElement.siblings('p').hide(); + this.inputElement.removeClass(inputErrorClass); + this.inputElement.removeClass(inputSuccessClass); + } + + setUnavailableState() { + const $usernameErrorMessage = this.inputElement.siblings(messageErrorSelector); + this.inputElement.addClass(inputErrorClass).removeClass(inputSuccessClass); + $usernameErrorMessage.show(); + } + + setSuccessState() { + const $usernameSuccessMessage = this.inputElement.siblings(messageSuccessSelector); + this.inputElement.addClass(inputSuccessClass).removeClass(inputErrorClass); + $usernameSuccessMessage.show(); + } + + setPendingState(show) { + const $usernamePendingMessage = $(messagePendingSelector); + if (this.pending) { + $usernamePendingMessage.show(); + } else { + $usernamePendingMessage.hide(); + } + } + + setInvalidState() { + this.inputElement.addClass(inputErrorClass).removeClass(inputSuccessClass); + $(`.gl-field-error`).show(); + } + } + + global.UsernameValidator = UsernameValidator; +})(window); |