Skip to content
This repository was archived by the owner on Mar 4, 2025. It is now read-only.

Commit 2944cd8

Browse files
committed
Merge pull request #157 from appirio-tech/form-error-messages
Form error messages
2 parents 8fb7747 + 4701d5d commit 2944cd8

20 files changed

+221
-78
lines changed

app/account/register/register.jade

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@
1313

1414
input(right-placeholder, focused-placeholder="Last", ng-model="vm.lastname", maxlength="64", name="lastname", placeholder="Last Name", type="text", required)
1515

16-
//- Show errors for first and last names once we know whether we can handle accents, other languages, and not symbols/numbers
17-
//- .form-errors
18-
//- p.form-error(ng-show="vm.registerForm.firstname.$dirty && vm.registerForm.firstname.$error.pattern") Names must not contain symbols or numbers.
19-
2016
.country-dropdown
2117
angucomplete-alt(
2218
input-name="country",
@@ -32,7 +28,7 @@
3228
)
3329

3430
.form-errors
35-
p.form-error(ng-show="vm.registerForm.country.$error.required") Please enter a valid country.
31+
p.form-error(ng-show="vm.registerForm.country.$error.required") Please choose a country from the list.
3632

3733
.validation-bar(ng-class="{ 'error-bar': (vm.registerForm.username.$error.usernameIsFree || vm.registerForm.username.$error.minlength || vm.registerForm.username.$error.maxlength), 'success-bar': (vm.registerForm.username.$valid && !vm.registerForm.username.$error.usernameIsFree) }")
3834
input(right-placeholder, focused-placeholder="Username", ng-model="vm.username", ng-model-options="{ debounce: {'default': 500} }", ng-focus="vm.usernameTips = true", ng-blur="vm.usernameTips = false", ng-minlength="2", ng-maxlength="15", name="username", placeholder="Username", type="text", username-is-free, required)
@@ -67,7 +63,7 @@
6763
p.form-error(ng-show="vm.registerForm.email.$dirty && vm.registerForm.email.$invalid") Please enter a valid email address.
6864

6965
.validation-bar(ng-class="{ 'success-bar': (vm.registerForm.password.$valid) }")
70-
toggle-password(ng-if="!vm.isSocialRegistration")
66+
toggle-password-with-tips(ng-if="!vm.isSocialRegistration")
7167

7268
.tips.password-tips(ng-show="vm.passwordFocus")
7369
h3 Password Tips:
@@ -76,14 +72,12 @@
7672

7773
p(ng-class="{ 'has-letter': (vm.registerForm.password.$dirty && !vm.registerForm.password.$error.hasLetter) }") At least one letter
7874

79-
p(ng-class="{ 'has-symbol': (vm.registerForm.password.$dirty && !vm.registerForm.password.$error.hasSymbol) }") At least one symbol
80-
81-
p(ng-class="{ 'has-number': (vm.registerForm.password.$dirty && !vm.registerForm.password.$error.hasNumber) }") At least one number
75+
p(ng-class="{ 'has-symbol-or-number': (vm.registerForm.password.$dirty && !vm.registerForm.password.$error.hasSymbolOrNumber) }") At least one number or symbol
8276

83-
button(type="submit", ng-disabled="vm.registerForm.$invalid", ng-class="{'enabled-button': vm.registerForm.$valid}") Join Now
77+
button(type="submit", ng-disabled="vm.registerForm.$invalid", ng-class="{'enabled-button': vm.registerForm.$valid}") Join
8478

8579
section.terms
86-
p By clicking "JOIN NOW" I agree to Topcoder's
80+
p By clicking "JOIN" I agree to Topcoder's
8781

8882
p #[a(href="http://www.topcoder.com/community/how-it-works/terms/", target="_blank") Terms of Service] and #[a(href="http://www.topcoder.com/community/how-it-works/privacy-policy/", target="_blank") Privacy Policy]
8983

app/account/reset-password/reset-password.jade

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
form.reset-form(name='vm.resetPasswordForm', role="form", ng-submit="vm.resetPasswordForm.$valid && vm.resetPassword()", novalidate)
3737

3838
.validation-bar(ng-class="{ 'success-bar': (vm.resetPasswordForm.password.$valid) }")
39-
toggle-password
39+
toggle-password-with-tips
4040

4141
.tips.password-tips(ng-show="vm.passwordFocus")
4242
h3 Password Tips:
@@ -45,9 +45,7 @@
4545

4646
p(ng-class="{ 'has-letter': (vm.resetPasswordForm.password.$dirty && !vm.resetPasswordForm.password.$error.hasLetter) }") At least one letter
4747

48-
p(ng-class="{ 'has-symbol': (vm.resetPasswordForm.password.$dirty && !vm.resetPasswordForm.password.$error.hasSymbol) }") At least one symbol
49-
50-
p(ng-class="{ 'has-number': (vm.resetPasswordForm.password.$dirty && !vm.resetPasswordForm.password.$error.hasNumber) }") At least one number
48+
p(ng-class="{ 'has-symbol-or-number': (vm.resetPasswordForm.password.$dirty && !vm.resetPasswordForm.password.$error.hasSymbolOrNumber) }") At least one number or symbol
5149

5250
.form-errors
5351
p.form-error(ng-show="vm.resetFailed") We were unable to reset your password. Please request another reset link. If you continue to have trouble, please contact
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
(function() {
2+
'use strict';
3+
4+
angular.module('tcUIComponents').directive('togglePasswordWithTips', togglePasswordWithTips);
5+
6+
function togglePasswordWithTips() {
7+
return {
8+
restrict: 'E',
9+
require: '^form',
10+
templateUrl: 'directives/account/toggle-password-with-tips/toggle-password-with-tips.html',
11+
link: function(scope, element, attrs, formController) {
12+
var vm = scope.vm;
13+
vm.passwordField = formController.password;
14+
vm.placeholder = vm.defaultPlaceholder;
15+
vm.password = '';
16+
17+
var passwordInput = element.children()[0];
18+
19+
element.bind('click', function(event) {
20+
passwordInput.focus();
21+
});
22+
23+
element.bind('keyup', function(event) {
24+
if (event.keyCode === 13) {
25+
passwordInput.blur();
26+
}
27+
});
28+
29+
vm.onFocus = function(event) {
30+
vm.passwordFocus = true;
31+
vm.placeholder = '';
32+
}
33+
34+
vm.onBlur = function(event) {
35+
var relatedTarget = angular.element(event.relatedTarget);
36+
37+
// If you are blurring from the password input and clicking the checkbox
38+
if (relatedTarget.attr('type') === 'checkbox' && relatedTarget.attr('id') === 'passwordCheckbox') {
39+
vm.passwordFocus = true;
40+
vm.placeholder = '';
41+
} else {
42+
// If you are blurring from the password input and clicking anywhere but the checkbox
43+
vm.passwordFocus = false;
44+
45+
if (vm.password === '' || vm.password === undefined) {
46+
vm.placeholder = vm.defaultPlaceholder;
47+
formController.password.$setPristine();
48+
}
49+
}
50+
};
51+
52+
vm.toggleInputType = function() {
53+
var $passwordInput = angular.element(passwordInput);
54+
55+
if ($passwordInput.attr('type') === 'text') {
56+
$passwordInput.attr('type', 'password');
57+
} else {
58+
$passwordInput.attr('type', 'text');
59+
}
60+
}
61+
}
62+
};
63+
}
64+
})();
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
input#password-input(
2+
ng-model="vm.password",
3+
ng-model-options="{allowInvalid: true}",
4+
5+
ng-hide="vm.isSocialRegistration",
6+
focus-on="focusOnInput",
7+
8+
ng-focus="vm.onFocus($event)",
9+
ng-blur="vm.onBlur($event)",
10+
11+
name="password",
12+
type="password",
13+
placeholder="{{vm.placeholder}}",
14+
15+
ng-minlength="8",
16+
ng-maxlength="64",
17+
has-letter,
18+
has-symbol-or-number,
19+
required)
20+
21+
label(ng-show="vm.passwordFocus || vm.passwordField.$dirty") #[input(type="checkbox", id="passwordCheckbox", ng-model="focusOnInput", ng-change="vm.toggleInputType()")] Show
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/* jshint -W117, -W030 */
2+
describe('Toggle Password With Tips Directive', function() {
3+
var scope;
4+
var element;
5+
// var challenge = mockData.getMockChallengeWithUserDetails();
6+
// var spotlightChallenge = mockData.getMockSpotlightChallenges()[0];
7+
8+
beforeEach(function() {
9+
bard.appModule('topcoder');
10+
bard.inject(this, '$compile', '$rootScope');
11+
scope = $rootScope.$new();
12+
});
13+
14+
bard.verifyNoOutstandingHttpRequests();
15+
});

app/directives/account/toggle-password/toggle-password.directive.js

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,52 +10,52 @@
1010
templateUrl: 'directives/account/toggle-password/toggle-password.html',
1111
link: function(scope, element, attrs, formController) {
1212
var vm = scope.vm;
13-
vm.passwordField = formController.password;
14-
vm.placeholder = vm.defaultPlaceholder;
15-
vm.password = '';
13+
vm.currentPasswordField = formController.currentPassword;
14+
vm.currentPasswordPlaceholder = vm.currentPasswordDefaultPlaceholder;
15+
vm.currentPassword = '';
1616

17-
var passwordInput = element.children()[0];
17+
var currentPasswordInput = element.children()[0];
1818

1919
element.bind('click', function(event) {
20-
passwordInput.focus();
20+
currentPasswordInput.focus();
2121
});
2222

2323
element.bind('keyup', function(event) {
2424
if (event.keyCode === 13) {
25-
passwordInput.blur();
25+
currentPasswordInput.blur();
2626
}
2727
});
2828

29-
vm.onFocus = function(event) {
30-
vm.passwordFocus = true;
31-
vm.placeholder = '';
29+
vm.onCPFocus = function(event) {
30+
vm.currentPasswordFocus = true;
31+
vm.currentPasswordPlaceholder = '';
3232
}
3333

34-
vm.onBlur = function(event) {
34+
vm.onCPBlur = function(event) {
3535
var relatedTarget = angular.element(event.relatedTarget);
3636

3737
// If you are blurring from the password input and clicking the checkbox
38-
if (relatedTarget.attr('type') === 'checkbox') {
39-
vm.passwordFocus = true;
40-
vm.placeholder = '';
38+
if (relatedTarget.attr('type') === 'checkbox' && relatedTarget.attr('id') === 'currentPasswordCheckbox') {
39+
vm.currentPasswordFocus = true;
40+
vm.currentPasswordPlaceholder = '';
4141
} else {
4242
// If you are blurring from the password input and clicking anywhere but the checkbox
43-
vm.passwordFocus = false;
43+
vm.currentPasswordFocus = false;
4444

45-
if (vm.password === '' || vm.password === undefined) {
46-
vm.placeholder = vm.defaultPlaceholder;
47-
formController.password.$setPristine();
45+
if (vm.currentPassword === '' || vm.currentPassword === undefined) {
46+
vm.currentPasswordPlaceholder = vm.currentPasswordDefaultPlaceholder;
47+
formController.currentPassword.$setPristine();
4848
}
4949
}
5050
};
5151

52-
vm.toggleInputType = function() {
53-
var $passwordInput = angular.element(passwordInput);
52+
vm.toggleTypeAttribute = function() {
53+
var $currentPasswordInput = angular.element(currentPasswordInput);
5454

55-
if ($passwordInput.attr('type') === 'text') {
56-
$passwordInput.attr('type', 'password');
55+
if ($currentPasswordInput.attr('type') === 'text') {
56+
$currentPasswordInput.attr('type', 'password');
5757
} else {
58-
$passwordInput.attr('type', 'text');
58+
$currentPasswordInput.attr('type', 'text');
5959
}
6060
}
6161
}
Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,17 @@
1-
input#password-input(
2-
ng-model="vm.password",
1+
input#current-password-input(
2+
ng-model="vm.currentPassword",
33
ng-model-options="{allowInvalid: true}",
44

55
ng-hide="vm.isSocialRegistration",
6-
focus-on="refocus",
6+
focus-on="focusOnCurrentPasswordInput",
77

8-
ng-focus="vm.onFocus($event)",
9-
ng-blur="vm.onBlur($event)",
8+
ng-focus="vm.onCPFocus($event)",
9+
ng-blur="vm.onCPBlur($event)",
1010

11-
name="password",
11+
name="currentPassword",
1212
type="password",
13-
placeholder="{{vm.placeholder}}",
13+
placeholder="{{vm.currentPasswordPlaceholder}}",
1414

15-
ng-minlength="8",
16-
ng-maxlength="64",
17-
has-letter,
18-
has-symbol,
19-
has-number,
2015
required)
2116

22-
label(ng-show="vm.passwordFocus || vm.passwordField.$dirty") #[input(type="checkbox", ng-model="refocus", ng-change="vm.toggleInputType()")] Show
17+
label(ng-show="vm.currentPasswordFocus || vm.currentPasswordField.$dirty") #[input(type="checkbox", id="currentPasswordCheckbox", ng-model="focusOnCurrentPasswordInput", ng-change="vm.toggleTypeAttribute()")] Show

app/directives/account/validate-register.directive.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
angular.module('tcUIComponents')
55
.directive('hasLetter', hasLetter)
6-
.directive('hasSymbol', hasSymbol)
6+
.directive('hasSymbolOrNumber', hasSymbolOrNumber)
77
.directive('hasNumber', hasNumber)
88
.directive('usernameIsFree', usernameIsFree)
99
.directive('emailIsAvailable', emailIsAvailable);
@@ -22,12 +22,12 @@
2222
};
2323
}
2424

25-
function hasSymbol() {
25+
function hasSymbolOrNumber() {
2626
return {
2727
require: 'ngModel',
2828
link: function(scope, element, attrs, ctrl) {
29-
ctrl.$validators.hasSymbol = function(modelValue, viewValue) {
30-
if (/[-!$@#%^&*()_+|~=`{}\[\]:";'<>?,.\/]/.test(viewValue)) {
29+
ctrl.$validators.hasSymbolOrNumber = function(modelValue, viewValue) {
30+
if (/[-!$@#%^&*()_+|~=`{}\[\]:";'<>?,.\/]/.test(viewValue) || /[\d]/.test(viewValue)) {
3131
return true;
3232
}
3333
return false;

app/directives/focus-on.directive.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33

44
angular.module('tcUIComponents').directive('focusOn', focusOn);
55

6-
focusOn.$inject = ['$timeout'];
6+
focusOn.$inject = ['$timeout', '$parse'];
77

8-
function focusOn($timeout) {
8+
function focusOn($timeout, $parse) {
99
return function(scope, element, attr) {
10-
scope.$watch('refocus', function(newValue) {
10+
var model = $parse(attr.focusOn);
11+
scope.$watch(model, function(newValue) {
1112
$timeout(function() {
1213
if (newValue !== undefined) {
1314
element[0].focus();

app/index.jade

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ html
5050
link(rel="stylesheet", href="assets/css/member-dashboard/community-updates.css")
5151
link(rel="stylesheet", href="assets/css/layout/header.css")
5252
link(rel="stylesheet", href="assets/css/layout/footer.css")
53+
link(rel="stylesheet", href="assets/css/directives/toggle-password-with-tips.css")
5354
link(rel="stylesheet", href="assets/css/directives/toggle-password.css")
5455
link(rel="stylesheet", href="assets/css/directives/tc-section.css")
5556
link(rel="stylesheet", href="assets/css/directives/tc-paginator.css")
@@ -125,6 +126,7 @@ html
125126
script(src="blocks/logger/logger.js")
126127
script(src="directives/tcui-components.module.js")
127128
script(src="directives/account/toggle-password/toggle-password.directive.js")
129+
script(src="directives/account/toggle-password-with-tips/toggle-password-with-tips.directive.js")
128130
script(src="directives/account/validate-email.directive.js")
129131
script(src="directives/account/validate-login.directive.js")
130132
script(src="directives/account/validate-register.directive.js")

app/settings/account-info/account-info.jade

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@
1919

2020
.address-fields
2121
label *First name (Given name)
22-
input(name="firstname", type="text", value="{{vm.userData.firstName}}", ng-model="vm.userData.firstName")
22+
input(name="firstname", type="text", value="{{vm.userData.firstName}}", ng-model="vm.userData.firstName", maxlength="64", required)
2323

2424
label *Last name (Surname)
25-
input(name="lastname", type="text", value="{{vm.userData.lastName}}", ng-model="vm.userData.lastName")
25+
input(name="lastname", type="text", value="{{vm.userData.lastName}}", ng-model="vm.userData.lastName", maxlength="64", required)
2626

2727
label Address
2828
input(name="address", type="text", value="{{vm.homeAddress.streetAddr1}}", ng-model="vm.homeAddress.streetAddr1")
@@ -52,8 +52,8 @@
5252
minlength="1"
5353
)
5454

55-
.form-errors
56-
p.form-error(ng-show="vm.updateAccountInfo.country.$error.required") Please enter a valid country.
55+
.account-info-error
56+
p.form-error(ng-show="vm.updateAccountInfo.country.$error.required") Please choose a country from the list.
5757

5858

5959
button(type="submit", ng-disabled="vm.updateAccountInfo.$invalid", ng-class="{'enabled-button': vm.updateAccountInfo.$valid}") Save

app/settings/edit-profile/edit-profile.jade

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
)
3434

3535
.form-errors
36-
p.form-error(ng-show="vm.editProfile.location.$error.required") Please enter a valid country.
36+
p.form-error(ng-show="vm.editProfile.location.$error.required") Please choose a country from the list.
3737

3838
.field-section.description
3939
h4.field-title About Me

app/settings/update-password/update-password.controller.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
activate();
1313

1414
function activate() {
15-
vm.defaultPlaceholder = 'Enter New Password';
15+
vm.defaultPlaceholder = 'New Password';
16+
vm.currentPasswordDefaultPlaceholder = 'Current Password';
1617
vm.username = userData.handle;
1718
vm.email = userData.email;
1819
}
@@ -23,7 +24,9 @@
2324
vm.password = '';
2425
vm.currentPassword = '';
2526
vm.newPasswordForm.$setPristine();
27+
vm.currentPasswordFocus = false;
2628
vm.placeholder = vm.defaultPlaceholder;
29+
vm.currentPasswordPlaceholder = vm.currentPasswordDefaultPlaceholder;
2730

2831
$log.info('Your password has been updated.');
2932
})

0 commit comments

Comments
 (0)