Skip to content

Commit a014ea0

Browse files
author
Salma Alam-Naylor
committed
Improve form errors for user
1 parent ccaccc6 commit a014ea0

File tree

5 files changed

+115
-14
lines changed

5 files changed

+115
-14
lines changed

apps/fretonator-web/src/app/common/footer/footer.component.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { GlobalService } from '../../global.service';
55
selector: 'app-footer',
66
templateUrl: './footer.component.html',
77
styleUrls: ['./footer.component.scss'],
8-
encapsulation: ViewEncapsulation.ShadowDom
98
})
109
export class FooterComponent {
1110
date: Date = new Date();

apps/fretonator-web/src/app/pages/contact/contact-index/contact-index.component.html

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,9 @@ <h1 class="form__title">Share the love <span role="img" aria-label="red heart em
3030
</span>
3131
</div>
3232
<ng-container *ngIf="name.touched">
33-
<p class="form__error" *ngIf="name.errors?.required">Enter your name, yo! A fake one will do.</p>
34-
<p class="form__error" *ngIf="name.errors?.pattern">Please enter a valid name that won't break the form!</p>
35-
<p class="form__error" *ngIf="name.errors?.maxlength">Come on, your name isn't
36-
actually {{name.errors?.maxlength.actualLength}}
37-
characters long!</p>
33+
<p class="form__error" *ngIf="name.errors?.required">{{getErrorMessage('name', 'required')}}</p>
34+
<p class="form__error" *ngIf="name.errors?.pattern">{{getErrorMessage('name', 'pattern')}}</p>
35+
<p class="form__error" *ngIf="name.errors?.maxlength">{{getErrorMessage('name', 'maxLength')}}</p>
3836
</ng-container>
3937
<label for="email" class="form__label">
4038
Your contact email
@@ -50,8 +48,7 @@ <h1 class="form__title">Share the love <span role="img" aria-label="red heart em
5048
</span>
5149
</div>
5250
<ng-container *ngIf="email.touched">
53-
<p class="form__error" *ngIf="email.errors?.email">An email address isn't required, but if you'd like me to reply
54-
to your message, please enter a valid one!</p>
51+
<p class="form__error" *ngIf="email.errors?.email">{{getErrorMessage('email', 'valid')}}</p>
5552
</ng-container>
5653

5754
<label for="message" class="form__label">
@@ -67,8 +64,8 @@ <h1 class="form__title">Share the love <span role="img" aria-label="red heart em
6764
</span>
6865
</div>
6966
<ng-container *ngIf="message.touched">
70-
<p class="form__error" *ngIf="message.errors?.required">Go on, give me some feedback!</p>
71-
<p class="form__error" *ngIf="message.errors?.minlength">Come on, you can write more than that!</p>
67+
<p class="form__error" *ngIf="message.errors?.required">{{getErrorMessage('message', 'required')}}</p>
68+
<p class="form__error" *ngIf="message.errors?.minlength">{{getErrorMessage('message', 'minLength')}}</p>
7269
</ng-container>
7370

7471
<div class="form__honeypot">
@@ -77,9 +74,16 @@ <h1 class="form__title">Share the love <span role="img" aria-label="red heart em
7774
</div>
7875

7976
<input type="submit" class="form__submit" formControlName="submit" aria-label="Submit Form"/>
77+
78+
<p class="form__error form__error--global" *ngIf="globalErrors.any">
79+
Please fix the following errors in the form to submit:
80+
<span class="form__error--inner" *ngIf="globalErrors.name">{{getErrorMessage('name', 'general')}}</span>
81+
<span class="form__error--inner" *ngIf="globalErrors.email">{{getErrorMessage('email', 'valid')}}</span>
82+
<span class="form__error--inner" *ngIf="globalErrors.message">{{getErrorMessage('message', 'general')}}</span>
83+
</p>
84+
8085
<p class="form__error form__error--global" *ngIf="formSubmitError">Eeesh! Something went wrong when we tried to
81-
submit the form. Please
82-
try again.</p>
86+
submit the form. Please try again.</p>
8387

8488
</form>
8589
</div>

apps/fretonator-web/src/app/pages/contact/contact-index/contact-index.component.scss

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@
5151
border: pxToRem(2) solid var(--form-input-border-color);
5252
background-color: var(--form-input-bg-color);
5353
color: var(--form-input-color);
54+
55+
@include focus_accessible();
5456
}
5557

5658
.form__input--textArea {
@@ -62,7 +64,7 @@
6264
height: pxToRem($grid-unit * 3);
6365
position: absolute;
6466
transform: translateY(50%);
65-
left: 92%;
67+
right: pxToRem($grid-unit * 2);
6668
}
6769

6870
.form__validIcon--textArea {
@@ -98,6 +100,22 @@
98100
border-top-width: pxToRem(2);
99101
}
100102

103+
.form__error--inner {
104+
display: block;
105+
margin-bottom: pxToRem($grid-unit * 1);
106+
margin-top: pxToRem($grid-unit * 1);
107+
108+
&:before {
109+
display: inline-block;
110+
content: '';
111+
border-radius: 50%;
112+
height: pxToRem($grid-unit * 1.5);
113+
width:pxToRem($grid-unit * 1.5);
114+
margin-right: pxToRem($grid-unit * 2);
115+
background-color: var(--error-fg);
116+
}
117+
}
118+
101119
.form__submit {
102120
@include hard_button_base();
103121
margin-top: pxToRem($grid-unit * 6);
@@ -107,3 +125,13 @@
107125
opacity: 0.5;
108126
}
109127
}
128+
129+
input:-webkit-autofill,
130+
input:-webkit-autofill:hover,
131+
input:-webkit-autofill:focus,
132+
textarea:-webkit-autofill,
133+
textarea:-webkit-autofill:hover,
134+
textarea:-webkit-autofill:focus {
135+
-webkit-box-shadow: 0 0 0 30px var(--form-input-bg-color) inset !important;
136+
-webkit-text-fill-color: var(--form-input-color) !important;
137+
}

apps/fretonator-web/src/app/pages/contact/contact-index/contact-index.component.ts

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { FormService } from '../form.service';
44
import { tap } from 'rxjs/operators';
55
import { Router } from '@angular/router';
66
import { GlobalService } from '../../../global.service';
7+
import { FormErrorMessages } from '../../../util/constants'
78

89
@Component({
910
selector: 'app-contact-index',
@@ -14,6 +15,12 @@ export class ContactIndexComponent implements OnInit, AfterViewInit {
1415
@ViewChild('scrollTarget') scrollTarget: ElementRef<HTMLElement>;
1516
formName = 'Contact';
1617
formSubmitError = false;
18+
globalErrors = {
19+
name: false,
20+
email: false,
21+
message: false,
22+
any: false
23+
};
1724
form = new FormGroup({
1825
honeypot: new FormControl('', [
1926
Validators.maxLength(0)
@@ -32,7 +39,7 @@ export class ContactIndexComponent implements OnInit, AfterViewInit {
3239
]),
3340
submit: new FormControl('Submit', [])
3441
}, {
35-
updateOn: 'blur'
42+
updateOn: 'change'
3643
});
3744

3845
constructor(private formService: FormService,
@@ -48,8 +55,11 @@ export class ContactIndexComponent implements OnInit, AfterViewInit {
4855
}
4956

5057
onSubmit() {
58+
this.resetGlobalErrors();
59+
5160
if (this.form.invalid) {
5261
this.form.markAllAsTouched();
62+
this.calculateGlobalErrors();
5363
return;
5464
}
5565

@@ -99,4 +109,47 @@ export class ContactIndexComponent implements OnInit, AfterViewInit {
99109
return this.form.get('honeypot');
100110
}
101111

112+
resetGlobalErrors() {
113+
this.globalErrors = {
114+
name: false,
115+
email: false,
116+
message: false,
117+
any: false
118+
};
119+
}
120+
121+
getNameError() {
122+
if (!this.name.errors) {
123+
return;
124+
}
125+
return true;
126+
}
127+
128+
getEmailError() {
129+
if (!this.email.errors) {
130+
return;
131+
}
132+
return true;
133+
}
134+
135+
getMessageError() {
136+
if (!this.message.errors) {
137+
return;
138+
}
139+
return true;
140+
}
141+
142+
calculateGlobalErrors() {
143+
this.globalErrors = {
144+
name: this.getNameError(),
145+
email: this.getEmailError(),
146+
message: this.getMessageError(),
147+
any: this.getNameError() || this.getEmailError() || this.getMessageError()
148+
};
149+
}
150+
151+
getErrorMessage(field: string, type: string) {
152+
return FormErrorMessages[field][type];
153+
}
154+
102155
}

apps/fretonator-web/src/app/util/constants.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,3 +636,20 @@ export const StandardModePatterns = [
636636
Mode.aolian,
637637
Mode.locrian
638638
];
639+
640+
export const FormErrorMessages = {
641+
name: {
642+
required: 'Enter your name, yo! A fake one will do.',
643+
pattern: 'Please enter a valid name that won\'t break the form!',
644+
maxLength: 'Come on, your name isn\'t actually that long!',
645+
general: 'There\'s something wrong with the name field.'
646+
},
647+
email: {
648+
valid: 'An email address isn\'t required, but if you\'d like me to reply to your message, please enter a valid one!'
649+
},
650+
message: {
651+
required: 'Go on, give me some feedback!',
652+
minLength: 'Keep typing, you\'re doing great.',
653+
general: 'Oops! There\'s something wrong with the message field.'
654+
}
655+
};

0 commit comments

Comments
 (0)