본문 바로가기
Front-end Framework/Angular

[실전 어플리케이션 만들기] 3. 로그인 Form 작성

by kellis 2020. 10. 20.

앞장에서 생성한 LoginFormComponent에 Angular의 @angular/forms 패키지의 FormBuilder, FormGroup, Validators 들을 이용하여 Form 관련 기능을 구현해보겠습니다.

 

Prerequisite

Reactive Forms - https://angular.io/guide/reactive-forms

 

 

참고. 이 예제에서는 Angular 공식 UI Component 모음인 Angular Material을 사용하여 작성되었습니다. Angular material이 필수는 아니기 때문에 bootstrap을 사용하여 UI는 자유롭게 작성할 수 있습니다.

 

1. HTML 작성

1) Form 작성

[login-form.component.html]

<div id="loginContainer">
  <form id="loginForm" [formGroup]="loginForm" (ngSubmit)="login()">
    <h2>LOGIN</h2>
 
    <mat-form-field>
      <input matInput placeholder="ID" formControlName="loginId">
    </mat-form-field>
    <br/>
    <mat-form-field>
      <input matInput placeholder="Password" [type]="hide ? 'text' : 'password'" formControlName="passwd">
      <mat-icon matSuffix (click)="hide = !hide">{{hide ? 'visibility' : 'visibility_off'}}</mat-icon>
    </mat-form-field>
    <br/>
 
    <button type="submit" mat-flat-button color="primary">Login</button>
  </form>
</div>

[login-form.component.css]

#loginContainer{
    padding: 100px;
}
 
#loginForm{
    border: 2px solid #01579B;
    max-width: 300px;
    padding: 10px 10px 20px 10px;
    margin: auto;
    text-align: center;
}
 
h2{
    color: #01579B;
}

mat* 형식으로 작성된 태그나 속성은 Angular Material를 사용한 것입니다.

*Angular Material 관련 내용은 링크를 참조 - https://material.angular.io/components/form-field/overview

 

이 예제에서는 서버로 전송하기 위한 데이터를 input에 있는 값을 [(ngModel)]을 이용하여 양방향 바인딩을 통해 컴포넌트 필드에 값을 받아 할 수 있습니다. 하지만 이방식으로 하게 되면 input 데이터를 json으로 만들기 위한 코딩이 필요하게 됩니다. 

이런 점을 해소할 수 있는 것이 FormGroup을 사용하는 것입니다.

 

formGroup에 LoginFormComponent에서 사용할 Form id를 작성합니다(form 태그의 id 속성과는 무관합니다. id는 css를 위한 속성).

각각 input에 대해 formControlName 속성을 작성하여 form의 속성명을 작성합니다.

*Angular Reactive Form - https://angular.io/guide/reactive-forms

 

 

2) ReactiveFormModule 추가

 

[app.module.ts]

import { SharedModule } from '../../shared/shared.module';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
 
import { AuthRoutingModule } from './auth-routing.module';
import { LoginFormComponent } from './login-form/login-form.component';
import { ReactiveFormsModule } from '@angular/forms';
 
@NgModule({
  imports: [
    CommonModule,
    AuthRoutingModule,
    ReactiveFormsModule,
    SharedModule
  ],
  declarations: [
    LoginFormComponent
  ]
})
export class AuthModule { }

LoginFormComponent 가 속해 있는 AuthModule에서 ReactiveFormModule을 사용할 수 있도록 추가합니다.

 

Material 관련 Module은 shared.module.ts에 추가합니다.

3) Material Module 추가

 

[shared.module.ts]

...
import { MatButtonModule } from '@angular/material/button';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
...
 
@NgModule({
  imports: [
    CommonModule,
    MatButtonModule,
    MatFormFieldModule,
    MatIconModule,
    MatInputModule,
    ...
  ],
  exports: [
    MatButtonModule,
    MatFormFieldModule,
    MatIconModule,
    MatInputModule,
    ...
  ],
...

 


2. FormBuilder를 이용한 FormGroup 생성

 

1) FormBuilder를 이용한 FormGroup 생성

 

[login-form.component.ts] 

import {Component, OnInit} from '@angular/core';
import {FormBuilder, Validators} from '@angular/forms';
 
 
@Component({
  selector: 'app-login-form',
  templateUrl: './login-form.component.html',
  styleUrls: ['./login-form.component.css']
})
export class LoginFormComponent implements OnInit {
  hide;
 
  loginForm = this.fb.group({
    loginId: [''],
    passwd: ['']
  });
 
  constructor(
    private fb: FormBuilder
  ) {}
 
  ngOnInit(): void {
  }
 
  login() {
    const formValues = this.loginForm.value;
    console.log(formValues);
  }
}

생성자에서 FormBuilder를 선언하고, FormBuilder를 이용하여 템플릿에서 작성한 'loginForm' key로 FormGroup을 생성해줍니다.

Form에서 값을 작성 후 버튼을 클릭하면 아래와 같이 결과가 출력됩니다.


3. Validators을 이용한 Validation

 

FormGroup 설정에서 Angular Validators를 이용하여 Validation을 할 수 있습니다. 

1) FormGroup 생성 속성에 Validators 추가, Validation 로직 추가

 

[login-form.component.ts]

import {Component, OnInit} from '@angular/core';
import {FormBuilder, Validators} from '@angular/forms';
 
@Component({
  selector: 'app-login-form',
  templateUrl: './login-form.component.html',
  styleUrls: ['./login-form.component.css']
})
export class LoginFormComponent implements OnInit {
  hide;
 
  loginForm = this.fb.group({
    loginId: ['', Validators.required],
    passwd: ['', Validators.required]
  });
 
  refererUrl: string;
 
  constructor(
    private fb: FormBuilder,
  ) {}
 
  ngOnInit(): void {
  }
 
  login() {
    const formValues = this.loginForm.value;
    if (this.loginForm.invalid) {
      alert('ID/PW를 입력해주세요');
      return;
    }
    console.log(formValues);
  }
}

LoginForm의 validation 결과가 실패면 invalid는 true이며, 여러 Validators를 추가하게 되면 각각 값의 errors에서 해당 내용을 확인할 수 있습니다.

required 말고도 minLength, maxLength(N) ... 등을 이용할 수 있습니다.

참조 : (https://angular.io/guide/form-validation)

 

 

 

댓글