Skip to content
This repository was archived by the owner on Feb 26, 2024. It is now read-only.

Commit b355a29

Browse files
tiepptPatrickJS
authored andcommitted
feat: add contact form using Reactive Forms Module (#141)
1 parent 5cb368e commit b355a29

File tree

7 files changed

+101
-4
lines changed

7 files changed

+101
-4
lines changed

src/app/app.component.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ <h3>
1313
<a [routerLink]="['/github', 'angular']">
1414
Github Repos
1515
</a>
16+
|
17+
<a [routerLink]="['/contact']">
18+
Contact Us
19+
</a>
1620
</nav>
1721

1822
<main>

src/app/app.module.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {RouterModule} from "@angular/router";
33
import {rootRouterConfig} from "./app.routes";
44
import {AppComponent} from "./app.component";
55
import {GithubService} from "./github/shared/github.service";
6-
import {FormsModule} from "@angular/forms";
6+
import {FormsModule, ReactiveFormsModule} from "@angular/forms";
77
import {BrowserModule} from "@angular/platform-browser";
88
import {HttpModule} from "@angular/http";
99
import {AboutComponent} from './about/about.component';
@@ -12,10 +12,11 @@ import {RepoBrowserComponent} from './github/repo-browser/repo-browser.component
1212
import {RepoListComponent} from './github/repo-list/repo-list.component';
1313
import {RepoDetailComponent} from './github/repo-detail/repo-detail.component';
1414
import {LocationStrategy, HashLocationStrategy} from '@angular/common';
15+
import { ContactComponent } from './contact/contact.component';
1516

1617
@NgModule({
17-
declarations: [AppComponent, AboutComponent, RepoBrowserComponent, RepoListComponent, RepoDetailComponent, HomeComponent],
18-
imports : [BrowserModule, FormsModule, HttpModule, RouterModule.forRoot(rootRouterConfig)],
18+
declarations: [AppComponent, AboutComponent, RepoBrowserComponent, RepoListComponent, RepoDetailComponent, HomeComponent, ContactComponent],
19+
imports : [BrowserModule, FormsModule, ReactiveFormsModule, HttpModule, RouterModule.forRoot(rootRouterConfig)],
1920
providers : [GithubService, {provide: LocationStrategy, useClass: HashLocationStrategy}],
2021
bootstrap : [AppComponent]
2122
})

src/app/app.routes.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {HomeComponent} from './home/home.component';
44
import {RepoBrowserComponent} from './github/repo-browser/repo-browser.component';
55
import {RepoListComponent} from './github/repo-list/repo-list.component';
66
import {RepoDetailComponent} from './github/repo-detail/repo-detail.component';
7+
import { ContactComponent } from './contact/contact.component';
78

89
export const rootRouterConfig: Routes = [
910
{path: '', redirectTo: 'home', pathMatch: 'full'},
@@ -18,6 +19,7 @@ export const rootRouterConfig: Routes = [
1819
{path: ':repo', component: RepoDetailComponent}
1920
]
2021
}]
21-
}
22+
},
23+
{path: 'contact', component: ContactComponent}
2224
];
2325

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
.form-content {
2+
width: 90%;
3+
max-width: 600px;
4+
margin: 0 auto;
5+
}
6+
.form-content .sd-form-control {
7+
display: block;
8+
margin-bottom: 10px;
9+
width: 100%;
10+
padding: 10px;
11+
}
12+
.form-content textarea.sd-form-control {
13+
max-width: 100%;
14+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<h2>Contact Reactive Form</h2>
2+
3+
<form (ngSubmit)="submitForm()" [formGroup]="contactForm" novalidate>
4+
<div class="form-content">
5+
<label>
6+
Name:
7+
<input type="text" formControlName="name" class="sd-form-control" placeholder="Enter your name.">
8+
</label>
9+
<label>
10+
Email:
11+
<input type="email" formControlName="email" class="sd-form-control" placeholder="Enter your email.">
12+
</label>
13+
<label>
14+
Content:
15+
<textarea formControlName="content" class="sd-form-control" placeholder="Content here."></textarea>
16+
</label>
17+
<div class="form-submit">
18+
<button type="submit">Submit</button>
19+
</div>
20+
</div>
21+
</form>
22+
23+
<div class="form-value">
24+
Form value:
25+
<pre>
26+
{{contactForm.value | json}}
27+
</pre>
28+
<p>
29+
Status: {{contactForm.status}}
30+
</p>
31+
<p>
32+
Valid: {{contactForm.valid}}
33+
</p>
34+
<p>Submit then open console to see full form.</p>
35+
</div>
36+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Component, OnInit } from '@angular/core';
2+
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
3+
import CustomValidators from '../forms/CustomValidators';
4+
5+
@Component({
6+
selector: 'app-contact',
7+
templateUrl: './contact.component.html',
8+
styleUrls: ['./contact-component.css']
9+
})
10+
export class ContactComponent implements OnInit {
11+
contactForm: FormGroup;
12+
constructor(private formBuilder: FormBuilder) {}
13+
14+
ngOnInit() {
15+
this.contactForm = this.formBuilder.group({
16+
name: ['', Validators.required],
17+
email: ['', [Validators.required, CustomValidators.validateEmail]],
18+
content: ['', [Validators.required, Validators.minLength(10)]]
19+
});
20+
}
21+
submitForm(): void {
22+
console.log(this.contactForm);
23+
}
24+
}

src/app/forms/CustomValidators.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import {FormControl} from '@angular/forms';
2+
3+
export default class CustomValidators {
4+
/**
5+
* sample from http://blog.thoughtram.io/angular/2016/03/14/custom-validators-in-angular-2.html
6+
*/
7+
static validateEmail(c: FormControl) {
8+
let EMAIL_REGEXP = /(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/;
9+
10+
return EMAIL_REGEXP.test(c.value) ? null : {
11+
validateEmail: {
12+
valid: false
13+
}
14+
};
15+
}
16+
}

0 commit comments

Comments
 (0)