Svelte 이용하여 Form 만들기

Svelte 에서 데이터를 입력하는 Form 을 하나 만들어본다. 이름과 성별정도 입력할 수 있도록 하고, 그 결과를 실시간으로 Object 로 반영하도록 bind 처리까지 간단히 해보자. 대략 아래의 레이아웃으로 만들 예정이다. 여기서 설명하는 건 Svelte 공식홈페이지 Tutorial 에도 있으니 참고한다.

데이터 정의

데이터를 담을 contents 변수를 하나 정의한다. Form 에서 입력한 결과가 json 형태로 실시간으로 반영되도록 할 예정이다. 그리고 성별을 입력할 콤보박스에 들어갈 옵션정보를 json 으로 만들어놓는다. html 태그에 하드코딩 하지 않기 위함이다.

<script>
    let contents = {};
    const cdGender = [ { id : null, name : '-'}, 
        { id : 'M', name : '남' }, 
        { id : 'F', name : '여'}];
</script>

html form 만들기

간단하게 나이와 성별을 입력하도록 input, select 태그를 이용하여 입력란을 만든다. textarea 는 입력결과를 실시간으로 보기 위해서 추가했다. select 태그안에 option 태그는 아까 변수로 선언한 cdGender 를 이용하여 #each 로 반복처리 해준다. 폼에서 입력한 값을 바로바로 json 객체에 값을 반영하려면 bind:value 으로 매핑을 하는 것이 중요하다. 참고로 bootstrap 을 사용하여 레이아웃을 구성했으니, class 정보는 굳이 따라하지 않아도 된다.

<div class="row">
    <div class="col-6">
        <label for="textarea1" class="form-label">결과</label>
        <textarea class="form-control" id="textarea1" rows="5">
            {JSON.stringify(contents, null, 2)}</textarea>
    </div>
    <div class="col-6">
        <div class="mb-2">
            <label for="name" class="form-label">이름</label>
            <input type="text" bind:value={contents.name} class="form-control">
        </div>
        <div class="mb-2">
            <label for="gender" class="form-label">성별</label>
            <select class="form-select" bind:value={contents.gender}>
                {#each cdGender as code, i}
                <option value="{code.id}">{code.name}</option>
                {/each}
            </select>
        </div>
    </div>
</div>

최종결과

하나의 svelte 파일로 만들어서 실행해보면 아래와 같이 값이 실시간으로 바인딩 되는걸 볼 수 있다.

<!-- +page.svelte 최종소스 -->
<script>
    let contents = {};
    const cdGender = [ { id : null, name : '-'}, 
        { id : 'M', name : '남' }, 
        { id : 'F', name : '여'}];
</script>

<div class="row">
    <div class="col-6">
        <label for="textarea1" class="form-label">결과</label>
        <textarea class="form-control" id="textarea1" rows="5">
            {JSON.stringify(contents, null, 2)}</textarea>
    </div>
    <div class="col-6">
        <div class="mb-2">
            <label for="name" class="form-label">이름</label>
            <input type="text" bind:value={contents.name} class="form-control">
        </div>
        <div class="mb-2">
            <label for="gender" class="form-label">성별</label>
            <select class="form-select" bind:value={contents.gender}>
                {#each cdGender as code, i}
                <option value="{code.id}">{code.name}</option>
                {/each}
            </select>
        </div>
    </div>
</div>
svelte 

더 보면 좋을 글들