Skip to content
GitLab
Projects Groups Topics Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in
  • Angular Template Angular Template
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributor statistics
    • Graph
    • Compare revisions
  • Issues 1
    • Issues 1
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 0
    • Merge requests 0
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • IzeniIzeni
  • Angular TemplateAngular Template
  • Wiki
  • cookbook forms

cookbook forms · Changes

Page history
jlewis created page: cookbook forms authored May 03, 2017 by Joe Lewis's avatar Joe Lewis
Hide whitespace changes
Inline Side-by-side
cookbook-forms.md
View page @ 4bf3cab5
a ### Form validation example (http://blog.ng-book.com/the-ultimate-guide-to-forms-in-angular-2/)
\ No newline at end of file ```javascript
...
import { ValidationService } from '../../services';
import { ControlArray, ControlGroup } from '@angular/common';
import { FormBuilder, FormGroup, Validators, FormArray } from '@angular/forms';
@Component...
export class ContactForm implements OnInit {
private contactForm: FormGroup;
public constructor (private formBuilder: FormBuilder) {}
public ngOnInit () {
this.buildForm();
}
private buildForm () {
let nameControl = ['', Validators.required]; // can also use other initial value instead of empty string
let emailControl = ['', ValidationService.emailValidator];
let subjectControl = ['', Validators.required];
let bodyControl = ['', Validators.required];
this.contactForm = this.formBuilder.group({
full_name: nameControl,
email: emailControl,
subject: subjectControl,
body: bodyControl,
});
}
private submitForm (form: any): void {
if (form.valid) {
let payload = form.value;
this.Contact.create(payload).subscribe((res: any) => {
this.buildForm();
this.handleSuccess();
}, (err: any) => {
console.log(err);
});
}
else {console.log('FORM: INVALID');}
}
...
}
```
## Custom app-global error handling
```typescript
import { ErrorHandler } from '@angular/core';
class CustomErrorHandler implements ErrorHandler {
public handleError (error: any) {
// originalError is probably the message you want in a toast, etc
console.log(error.originalError);
// still send error to console, if desired
console.error(error._nativeError);
}
}
```
```
import { NgModule, ErrorHandler } from '@angular/core';
import { CustomErrorHandler } from './path/to/custom/handler';
...
@NgModule({
...
providers: [
{provide: ErrorHandler, useClass: CustomErrorHandler},
],
})
```
## ngFor filtering (ngChange on input which updates array)
## Add the following for errors to appear and disappear automatically
```scss
/* FORMS, INPUTS
----------------------------------------*/
input, textarea {
display: inline-block;
padding: 16px 28px;
border: none;
outline: none;
box-shadow: none;
border-radius: 60px;
color: $gray;
@include font-range(14, 18);
@include sans;
@include placeholder {
color: $grayLt;
@include sans;
@include font-range(14, 18);
}
}
input.ng-invalid.ng-dirty, textarea.ng-invalid.ng-dirty {
border-left: solid red 3px !important;
}
input.ng-valid.ng-dirty, textarea.ng-valid.ng-dirty {
border-left: solid #42A948 3px !important;
}
```
## Example of errors in form HTML
```html
<div class="careerDetail">
<div class="careerDetail__content">
<section class="careerOutline">
<h2 class="careerOutline__title">{{ (career | async)?.title }}</h2>
<div class="careerOutline__location">{{ (career | async)?.location }}</div>
<div [innerHtml]="(career | async)?.description"></div>
</section>
<section class="apply">
<form [formGroup]="applyForm" (submit)="onSubmit(applyForm)">
<div class="apply__header">
APPLY FOR THIS POSITION
</div>
<div class="apply__form">
<input required [formControl]="applyForm.controls['full_name']" class="apply__input" type="text" placeholder="Full Name *">
<input required [formControl]="applyForm.controls['city']" class="apply__input" type="text" placeholder="City*">
<input required [formControl]="applyForm.controls['email']" class="apply__input" type="email" placeholder="Email*">
<input required [formControl]="applyForm.controls['phone_number']" class="apply__input" type="text" placeholder="Phone*">
<div class="formError" *ngIf="applyForm.controls['phone_number'].touched && applyForm.controls['phone_number'].hasError('invalidInternationalPhoneNumber') &&
applyForm.controls['phone_number'].value.length > 0">
Number needs to be in International format. ex) +18881231234
</div>
<textarea required [formControl]="applyForm.controls['message']" class="apply__textarea" placeholder="Message (required)"
rows="10"></textarea>
<input required accept='.doc,.pdf,.txt' id="fileInput" class="apply__fileInput" type="file">
<div class="formError" *ngIf="fileError">
{{fileError}}
</div>
<button [disabled]="!applyForm.valid || fileError" type="submit" class="button"> Apply </button>
</div>
</form>
</section>
</div>
</div>
```
## Component for form errors
``` javascript
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { ValidationService, APIConfigService, HttpService, CareerModel } from '../../shared';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-career',
templateUrl: './career.component.html',
styleUrls: ['./career.component.scss']
})
export class CareerComponent implements OnInit {
private user: {} = undefined;
private career: Promise<{}>;
private careerId: number;
private applyForm: FormGroup;
private success: boolean = false;
private apiUrl: any = this.apiConfig.apiUrl;
private file: any;
private fileError: string = '';
public constructor(
private validation: ValidationService,
private apiConfig: APIConfigService,
private Career: CareerModel,
private route: ActivatedRoute,
private router: Router,
private formBuilder: FormBuilder,
private http: HttpService
) {
}
public ngOnInit() {
this.buildForm();
this.route.params.subscribe(params => {
this.career = this.Career.read(params['id'])
.then(career => {
this.careerId = career.id;
return career;
});
});
}
ngAfterViewInit() {
// Component views are initialized
this.file = document.getElementById('fileInput');
this.file.onchange = () => {
let ext = this.file.files[0].name.match(/\.([^\.]+)$/)[1];
if (ext !== ('pdf' || 'doc' || 'txt')) {
this.fileError = 'accepted formats .pdf, .doc, .txt';
}
else { this.fileError = '' }
}
}
private buildForm() {
let nameControl = ['', Validators.required];
let emailControl = ['', Validators.compose([Validators.required, this.validation.emailValidator])];
let cityControl = ['', Validators.required];
let phoneControl = ['', Validators.compose([Validators.required, this.validation.phoneInternationalValidator])];
let bodyControl = ['', Validators.required];
this.applyForm = this.formBuilder.group({
full_name: nameControl,
email: emailControl,
city: cityControl,
phone_number: phoneControl,
message: bodyControl,
});
}
private onSubmit(form: any): void {
if (form.valid) {
let payload = form.value;
let url = this.apiUrl + '/jobs/' + this.careerId + '/apply/';
let file: any = document.getElementById('fileInput');
file = file.files[0];
let ext = file.name.match(/\.([^\.]+)$/)[1];
if (ext === ('pdf' || 'doc' || 'txt')) {
// file = file.files[0];
let data = new FormData();
Object.keys(payload).map((key) => {
data.append(key, payload[key]);
});
data.append('resume', file, file.name);
this.http.clearToken('Content-Type');
this.http.post(url, data).subscribe((r: any) => {
this.buildForm();
this.success = true;
setTimeout(() => { this.success = false; }, 3000);
}, (err: any) => {
console.log(err);
});
}
else {
alert('File is not a .doc,.txt, or .pdf format');
}
}
else { console.log('FORM: INVALID'); }
}
}
```
\ No newline at end of file
Clone repository
  • angular
  • cookbook forms
  • cookbook routing
  • data store
  • gotchas
  • Home
  • modals
  • sass with bem
  • toolbox
  • typescript
  • webpack