This commit is contained in:
byung eun park 2019-08-28 19:22:54 +09:00
parent fd24101f0e
commit 66d3cc80b1
8 changed files with 253 additions and 233 deletions

View File

@ -18,9 +18,12 @@ export class UsersDataSource extends DataSource<User> {
private paginator: MatPaginator,
private sort: MatSort
) {
User;
super();
User;
}
User;
User;
// Filter
get filter(): string {
return this.filterSubject.value;

View File

@ -1,7 +1,10 @@
<div id="forms" class="page-layout simple fullwidth" fxLayout="column">
<!-- HEADER -->
<div class="header accent p-24 h-160" fxLayout="row" fxLayoutAlign="start center">
<div
class="header accent p-24 h-160"
fxLayout="row"
fxLayoutAlign="start center"
>
<div fxLayout="column" fxLayoutAlign="center start">
<div fxLayout="row" fxLayoutAlign="start center">
<mat-icon class="secondary-text s-18">home</mat-icon>
@ -15,164 +18,123 @@
<!-- CONTENT -->
<div class="content p-24">
<div class="h1">
Reactive Forms
회원가입
</div>
<p class="pt-16 pb-32">
Angular reactive forms facilitate a reactive style of programming that favors explicit management of the
data flowing between a non-UI data model (typically retrieved from a server) and a UI-oriented form model
that retains the states and values of the HTML controls on screen. Reactive forms offer the ease of using
reactive patterns, testing, and validation.
</p>
<div class="h1 pt-32">
Horizontal Stepper
<div
class="mb-24"
fxLayout="column"
fxLayoutAlign="start"
fxLayout.gt-md="row"
>
<form
class="mat-card mat-elevation-z4 p-24 mr-24"
fxLayout="column"
fxLayoutAlign="start"
fxFlex="1 0 auto"
name="registerForm"
[formGroup]="registerForm"
(ngSubmit)="registUser()"
>
<div class="h2 mb-24">기본정보</div>
<div fxLayout="row" fxLayoutAlign="start center" fxFlex="1 0 auto">
<mat-form-field appearance="outline" fxFlex="50" class="pr-4">
<mat-label>아이디</mat-label>
<input matInput formControlName="username" />
<mat-icon matSuffix class="secondary-text">account_circle</mat-icon>
<mat-error>아이디는 필수 사항입니다!</mat-error>
</mat-form-field>
<mat-form-field appearance="outline" fxFlex="50" class="pl-4">
<mat-label>핸드폰</mat-label>
<input matInput formControlName="phone" />
<mat-icon matSuffix class="secondary-text">phone</mat-icon>
<mat-error>핸드폰은 필수 사항입니다!</mat-error>
</mat-form-field>
</div>
<div class="mb-24" fxLayout="column" fxLayoutAlign="start" fxLayout.gt-md="row">
<!--
<p class="pb-32">
Angular Material's stepper provides a wizard-like workflow by dividing content into logical steps.
<code>mat-horizontal-stepper</code> selector can be used to create a horizontal stepper.
</p> -->
<div class="horizontal-stepper-wrapper">
<!-- HORIZONTAL STEPPER EXAMPLE -->
<mat-horizontal-stepper class="mat-elevation-z4" [linear]="true">
<mat-step [stepControl]="horizontalStepperStep1">
<form fxLayout="column" [formGroup]="horizontalStepperStep1">
<ng-template matStepLabel>Fill out your name</ng-template>
<div fxFlex="1 0 auto" fxLayout="column">
<mat-form-field appearance="outline" fxFlex="100">
<mat-label>First Name</mat-label>
<input matInput formControlName="firstName" required>
<mat-error>First Name is required!</mat-error>
<div fxLayout="row" fxLayoutAlign="start center" fxFlex="1 0 auto">
<mat-form-field appearance="outline" fxFlex="50" class="pr-4">
<mat-label>패스워드</mat-label>
<input matInput type="password" formControlName="password" />
<mat-icon matSuffix class="secondary-text">vpn_key</mat-icon>
<mat-error>
패스워드는 필수 사항입니다!
</mat-error>
</mat-form-field>
<mat-form-field appearance="outline" fxFlex="100">
<mat-label>Last Name</mat-label>
<input matInput formControlName="lastName" required>
<mat-error>Last Name is required!</mat-error>
<mat-form-field appearance="outline" fxFlex="50" class="pl-4">
<mat-label>패스워드 (확인)</mat-label>
<input matInput type="password" formControlName="passwordConfirm" />
<mat-icon matSuffix class="secondary-text">vpn_key</mat-icon>
<mat-error
*ngIf="registerForm.get('passwordConfirm').hasError('required')"
>
패스워드 확인은 필수 사항입니다!
</mat-error>
<mat-error
*ngIf="
!registerForm.get('passwordConfirm').hasError('required') &&
registerForm
.get('passwordConfirm')
.hasError('passwordsNotMatching')
"
>
패스워드가 일치하지 않습니다!
</mat-error>
</mat-form-field>
</div>
<div fxLayout="row" fxLayoutAlign="center center">
<button mat-raised-button matStepperNext type="button" color="accent">
Next
<div fxLayout="row" fxLayoutAlign="start center" fxFlex="1 0 auto">
<mat-form-field appearance="outline" fxFlex="50">
<mat-label>닉네임</mat-label>
<input matInput formControlName="nickname" required />
<mat-icon matSuffix class="secondary-text">account_circle</mat-icon>
<mat-error>닉네임은 필수 사항입니다!!</mat-error>
</mat-form-field>
<mat-form-field appearance="outline" fxFlex="50" class="px-8">
<mat-label>이메일</mat-label>
<input matInput formControlName="email" />
<mat-icon matSuffix class="secondary-text">mail</mat-icon>
</mat-form-field>
</div>
<div fxLayout="row wrap" fxLayoutAlign="start center" fxFlex="1 0 auto">
<mat-form-field appearance="outline" fxFlex="100">
<mat-label>비고</mat-label>
<textarea
matInput
formControlName="descriptions"
placeholder="부가적인 설명"
></textarea>
</mat-form-field>
</div>
<button
mat-raised-button
color="accent"
class="submit-button"
aria-label="CREATE AN ACCOUNT"
[disabled]="registerForm.invalid"
>
CREATE AN ACCOUNT
</button>
</div>
</form>
</mat-step>
<mat-step [stepControl]="horizontalStepperStep2">
<form fxLayout="column" [formGroup]="horizontalStepperStep2">
<ng-template matStepLabel>Fill out your address</ng-template>
<div fxFlex="1 0 auto" fxLayout="row">
<mat-form-field appearance="outline" fxFlex="100">
<mat-label>Address</mat-label>
<textarea matInput formControlName="address" required>
1600 Amphitheatre Pkwy
</textarea>
<mat-error>Address is required!</mat-error>
</mat-form-field>
<div class="mat-card form-errors-model p-24 mat-elevation-z4">
<div class="h2 mb-24">계좌정보</div>
<pre>계좌정보</pre>
</div>
<div fxLayout="row" fxLayoutAlign="center center">
<button class="mr-8" mat-raised-button matStepperPrevious type="button" color="accent">
Previous
</button>
<button mat-raised-button matStepperNext type="button" color="accent">
Next
</button>
</div>
</form>
</mat-step>
<mat-step [stepControl]="horizontalStepperStep3">
<form fxLayout="column" [formGroup]="horizontalStepperStep3">
<ng-template matStepLabel>Fill out your address</ng-template>
<div fxFlex="1 0 auto" fxLayout="column">
<mat-form-field appearance="outline" fxFlex="100">
<mat-label>City</mat-label>
<input matInput formControlName="city" required>
<mat-error>City is required!</mat-error>
</mat-form-field>
<mat-form-field appearance="outline" fxFlex="100">
<mat-label>State</mat-label>
<input matInput formControlName="state" required>
<mat-error>State is required!</mat-error>
</mat-form-field>
<mat-form-field appearance="outline" fxFlex="100">
<mat-label>Postal Code</mat-label>
<input matInput #postalCode2 formControlName="postalCode" maxlength="5" required>
<mat-hint align="end">{{postalCode2.value.length}} / 5</mat-hint>
<mat-error>Postal Code is required!</mat-error>
</mat-form-field>
</div>
<div fxLayout="row" fxLayoutAlign="center center">
<button class="mr-8" mat-raised-button matStepperPrevious type="button" color="accent">
Previous
</button>
<button mat-raised-button matStepperNext type="button" color="accent">
Next
</button>
</div>
</form>
</mat-step>
<mat-step>
<ng-template matStepLabel>Done</ng-template>
<div class="h2 m-16" fxLayout="row" fxLayoutAlign="center center">
Thank your for filling out our form.
</div>
<div fxLayout="row" fxLayoutAlign="center center">
<button class="mr-8" mat-raised-button matStepperPrevious type="button" color="accent">
Previous
</button>
<button mat-raised-button type="button" color="accent" (click)="finishHorizontalStepper()">
Finish
</button>
</div>
</mat-step>
</mat-horizontal-stepper>
<!-- / HORIZONTAL STEPPER EXAMPLE -->
</div>
<div class="mat-card form-errors-model p-24 mat-elevation-z4">
<div class="h2 mb-24">Reactive Form Model</div>
<pre>아아아다다다다다다다</pre>
</div>
<div class="mat-card form-errors-model p-24 mat-elevation-z4">
<div class="h2 mb-24">Reactive Form Model</div>
<pre>아아아다다다다다다다</pre>
</div>
<!-- / CONTENT -->
</div>
</div>
</div>

View File

@ -1,7 +1,5 @@
:host {
.content {
form {
width: 100%;
max-width: 800px !important;

View File

@ -1,15 +1,28 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import {
AbstractControl,
FormBuilder,
FormGroup,
ValidationErrors,
ValidatorFn,
Validators
} from '@angular/forms';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/internal/operators';
import { take } from 'rxjs/operators';
import { fuseAnimations } from 'src/@fuse/animations';
import { User } from 'src/modules/user/model/user.model';
import { SignupRequest } from 'src/modules/auth/model/auth-signup-request.model';
import { AuthService } from 'src/modules/auth/service/auth.service';
@Component({
selector: 'app-user-regist',
templateUrl: './user-regist.component.html',
styleUrls: ['./user-regist.component.scss']
styleUrls: ['./user-regist.component.scss'],
encapsulation: ViewEncapsulation.Emulated,
animations: fuseAnimations
})
export class UserRegistComponent implements OnInit, OnDestroy {
form: FormGroup;
registerForm: FormGroup;
// Horizontal Stepper
horizontalStepperStep1: FormGroup;
horizontalStepperStep2: FormGroup;
@ -25,7 +38,8 @@ export class UserRegistComponent implements OnInit, OnDestroy {
* @param {FormBuilder} _formBuilder
*/
constructor(
private _formBuilder: FormBuilder
private _formBuilder: FormBuilder,
private _authService: AuthService
) {
// Set the private defaults
this._unsubscribeAll = new Subject();
@ -40,37 +54,23 @@ export class UserRegistComponent implements OnInit, OnDestroy {
*/
ngOnInit() {
// Reactive Form
this.form = this._formBuilder.group({
company: [
{
value: 'Google',
disabled: true
}, Validators.required
],
firstName: ['', Validators.required],
lastName: ['', Validators.required],
address: ['', Validators.required],
address2: ['', Validators.required],
city: ['', Validators.required],
state: ['', Validators.required],
postalCode: ['', [Validators.required, Validators.maxLength(5)]],
country: ['', Validators.required]
this.registerForm = this._formBuilder.group({
username: ['', Validators.required],
phone: ['', Validators.required],
password: ['', Validators.required],
passwordConfirm: ['', [Validators.required, confirmPasswordValidator]],
nickname: ['', Validators.required],
email: [''],
descriptions: ['']
});
// Horizontal Stepper form steps
this.horizontalStepperStep1 = this._formBuilder.group({
firstName: ['', Validators.required],
lastName: ['', Validators.required]
});
this.horizontalStepperStep2 = this._formBuilder.group({
address: ['', Validators.required]
});
this.horizontalStepperStep3 = this._formBuilder.group({
city: ['', Validators.required],
state: ['', Validators.required],
postalCode: ['', [Validators.required, Validators.maxLength(5)]]
// Update the validity of the 'passwordConfirm' field
// when the 'password' field changes
this.registerForm
.get('password')
.valueChanges.pipe(takeUntil(this._unsubscribeAll))
.subscribe(() => {
this.registerForm.get('passwordConfirm').updateValueAndValidity();
});
}
@ -83,21 +83,44 @@ export class UserRegistComponent implements OnInit, OnDestroy {
this._unsubscribeAll.complete();
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Finish the horizontal stepper
*/
finishHorizontalStepper(): void {
alert('You have finished the horizontal stepper!');
registUser(): void {
let user: SignupRequest = <SignupRequest>this.registerForm.value;
console.log(user);
this._authService
.signup(user)
.pipe(take(1))
.subscribe(
res => {
console.log(res);
},
err => {
console.log(err);
}
/**
* Finish the vertical stepper
*/
finishVerticalStepper(): void {
alert('You have finished the vertical stepper!');
);
}
}
export const confirmPasswordValidator: ValidatorFn = (
control: AbstractControl
): ValidationErrors | null => {
if (!control.parent || !control) {
return null;
}
const password = control.parent.get('password');
const passwordConfirm = control.parent.get('passwordConfirm');
if (!password || !passwordConfirm) {
return null;
}
if (passwordConfirm.value === '') {
return null;
}
if (password.value === passwordConfirm.value) {
return null;
}
return { passwordsNotMatching: true };
};

View File

@ -0,0 +1,8 @@
export interface SignupRequest {
username: string;
nickname: string;
email: string;
password: string;
descriptions: string;
phone: string;
}

View File

@ -7,6 +7,7 @@ import { JwtSigninResponse } from '../model/jwt-signin-response.model';
import { CookieService } from 'ngx-cookie-service';
import { API_BASE_URL } from 'src/modules/common/type/injection-token.type';
import { SignupRequest } from '../model/auth-signup-request.model';
@Injectable({ providedIn: 'root' })
export class AuthService {
@ -14,8 +15,33 @@ export class AuthService {
private httpClient: HttpClient,
private cookieService: CookieService,
@Inject(API_BASE_URL) private apiBaseUrl: string
) { }
) {}
public signup(signupInfo: SignupRequest): Observable<any> {
const ll = JSON.stringify(signupInfo);
const username = signupInfo.username;
const password = signupInfo.password;
const email = signupInfo.email;
const phone = signupInfo.phone;
const descriptions = signupInfo.descriptions;
const nickname = signupInfo.nickname;
return this.httpClient
.post<any>(`${this.apiBaseUrl}/auth/signup`, {
username,
nickname,
email,
password,
descriptions,
phone
})
.pipe(
map(res => {
console.log('signup response: ' + res);
return res;
})
);
}
public authenticate(
username: string,
password: string

View File

@ -14,5 +14,6 @@ export interface User extends DateAudit {
otpKey?: string;
otp?: string;
requireReset?: boolean;
phone?: string;
descriptions?: string;
}

View File

@ -7,11 +7,10 @@ import { Page } from 'src/modules/common/data/model/page';
@Injectable()
export class UserService {
constructor(
@Inject(API_BASE_URL) private apiBaseUrl: string,
private httpClient: HttpClient
) { }
) {}
public getAllUsers(): Observable<Page<User>> {
return this.httpClient.get<Page<User>>(`${this.apiBaseUrl}/users`, {});