회원 가입 폼 - 밸리데이션 구조 설계

 

app.ts의 전체적인 구조

 

import template from './app.template';
import { CantContainWhitespace, CantStartNumber, MinimumLengthLimit } from './constant';
import { AnyObject } from './types';
import { TextField, PasswordField, AddressField } from './views';

export default class App {
  template = template;
  data: AnyObject;
  container: HTMLElement;
  fields: AnyObject[];
  active: boolean = false;

  constructor(container: string, data: AnyObject = {}) {
    this.container = document.querySelector(container) as HTMLElement;
    this.data = data;
    this.fields = [];

    this.initialize();
    
    setInterval(this.validFieldMonitor, 1000/30);
  }

  private initialize = () => {
    const nameField = new TextField('#required-fields', { 
      id: 'name', label: '이름', type: 'text', placeholder: '이름을 입력해주세요', require: true,
    });

    const idField = new TextField('#required-fields', { 
      id: 'id', label: '아이디', type: 'text', placeholder: '아이디를 입력해주세요', require: true,
    });

    const emailField = new TextField('#required-fields', { 
      id: 'email', label: '이메일', type: 'email', placeholder: '이메일을 입력해주세요', require: true,
    });
    
    const passwordField = new PasswordField('#required-fields', { 
      id: 'password', label: '비밀번호', placeholder: '비밀번호를 입력해주세요', 
    });

    const addressField = new AddressField('#optional-fields', {
      id: 'address', label: '배송지 주소',
    });

    idField.addValidateRule(CantContainWhitespace);
    idField.addValidateRule(CantStartNumber);
    idField.addValidateRule(MinimumLengthLimit(3));

    emailField.addValidateRule(CantContainWhitespace);

    this.fields.push(nameField);
    this.fields.push(idField);
    this.fields.push(emailField);
    this.fields.push(passwordField);
    this.fields.push(addressField);
  }

  private validFieldMonitor = () => {
    const btnJoin = this.container.querySelector('#btn-join') as HTMLButtonElement;

    if (this.fields.filter(field => field.isValid).length === this.fields.length) {
      this.active = true;
      btnJoin.classList.remove('bg-gray-300');
      btnJoin.classList.add('bg-green-500');
    } else {
      this.active = false;
      btnJoin.classList.remove('bg-green-500');
      btnJoin.classList.add('bg-gray-300');
    }
  }

  private onSubmit = (e: Event) => {
    e.preventDefault();

    if (!this.active) return;

    const submitData: AnyObject = this.fields
        .map(field => ({ [field.name]: field.value }))
        .reduce((a, b) => ({ ...a, ...b }), {});

    console.log(submitData);
  }

  public render = () => {
    this.container.innerHTML = this.template(this.data);
    this.fields.forEach(field => {
      field.render(true);
    });

    this.container.addEventListener('submit', this.onSubmit);
  }
}

app.ts는 각 views에서 가져온 text, password, address 필드의 변경된 사항이나 밸리데이션 구조 등을 전체적으로 취합해서 화면을 렌더링한다.

 

구조를 보면 기본적으로, 화면의 구조적인 UI를 가지고있는 template(app.template.ts), 각 컴포넌트에 해당하는 데이터를 가진 AnyObject를 반환하는 data와 filelds, 최상위 컨테이너를 지정하는 container, 회원가입 시 궁극적인 유효성 체크를 진행하는 active 필드 등이 있다.

 

또한 메소드 initialize()는 초기 화면을 구동했을 시에 사용하는 필드와 해당하는 필드에 들어가는 데이터 등을 인스턴스로 생성한다. validFiledMonitor()은 화면에 있는 모든 필드의 입력과 밸리데이션을 충족 했을 시에 회원 가입을 진행하는데, 모든 조건이 충족되어있는가를 체크하는 메소드이며 onSubmit()은 vaildFieldMonitor()에서 모든 조건을 충족했을 시 회원 가입을 진행할 수 있다. render()는 위이 모든 기능들의 변경에 따라 보여지는 데이터나 UI 등이 변경된다.

 

 

 

 

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

 

#패스트캠퍼스 #패캠챌린지 #직장인인강 #직장인자기계발 #패스트캠퍼스후기 #김민태의프론트엔드아카데미:제1강JavaScript&TypeScriptEssential

+ Recent posts