코딩 강의/컨텐츠를 만들어 볼까요

웹 언어 코딩으로 심리 테스트 만들기 #4 데이터 입력

아미넴 2021. 2. 9.

기다리시는 분이 계셨을 지는 모르겠지만 ㅎㅎ 조금 늦어져서 죄송합니다. 이번에는 깊게 들어가면 복잡한 고급 스킬이지만 단순히 따라하기는 어렵지 않은 내용을 다루어 보겠습니다.

 

웹 언어 코딩으로 심리 테스트 만들기 #3 화면 전환 기능 구현

 

웹 언어 코딩으로 심리 테스트 만들기 #3 화면 전환 기능 구현

이번에는 지난 시간에 만든 인트로, 메인, 결과 화면을 차례로 이동 시키는 코드 작성을 해보겠습니다. 웹 언어 코딩으로 심리 테스트 만들기 #2 인트로 및 결과 화면 작성 웹 언어 코딩으로 심리

sangminem.tistory.com

 

목차

     

    VueJS 추가 개념 설명

    이미 처음부터 VueJS 프레임워크를 사용하기 위한 구조를 잡아 놓은 상태인데요. 이번 시간에는 사용자가 무엇을 선택했는지에 따라 동작을 다르게 하기 위해 VueJS 기능을 활용하여 데이터를 다루어 볼 예정입니다. 이제부터 프레임워크의 장점이 드러나기 시작합니다.

     

    사용자의 선택에 의해 결과가 바뀔 때마다 화면에 표시되는 내용도 바뀌어야 함은 당연하지요. 하지만 아무런 도구도 쓰지 않고 순수하게 HTML, JS 코드로만 작성한다면, 선택지에 따라 바뀌는 부분이 많지 않음에도 불구하고 같은 코드를 중복 작성해야 하는 등 비효율적인 상황에 직면하게 될 때가 많습니다. VueJS는 그런 상황에서 매우 간결하고 효율적인 코딩을 할 수 있도록 도와주는 역할을 합니다.

     

    이 강의에서 프레임워크 개념을 상세히 설명하려면 배보다 배꼽이 커지는 격이므로 생략하기로 합니다.

     

    HTML 변경하기

    VueJS 기능을 활용하기 위해 기존에 작성했던 HTML을 조금 수정해 볼 건데요. 기존에는 HTML 내에 표현하고자 하는 내용을 그대로 적었다면 이제는 별도로 관리를 하기 위해 변수로 대체하는 작업을 해 보겠습니다. test.html 파일 내용을 수정하시면 됩니다.

    <!DOCTYPE html>
    <html>
        <head>
            <!-- 생략 -->
        </head>
        <body>
            <div id="test">
                <div id="intro" class="intro-wrap">
                    <!-- 도입부 -->
                    <div class="intro">
                        <div class="intro-story" v-on:click="start">{{intro}}</div> <!-- intro 변수로 변경 -->
                    </div>
                </div>
                <div id="main">
                    <!-- 질문 시작 -->
                    <div class="title-wrap">
                        <h2 class="title">{{title}}</h2> <!-- title 변수로 변경 -->
                    </div>
    
                    <div class="question-wrap">
                        <h3 class="question">
                            {{question[index]}} <!-- question 변수로 변경 -->
                        </h3>
                    </div>
                    <div class="answer-wrap">
                        <div class="answer">
                            <!-- answer 변수로 변경 -->
                            <div class="answer" v-for="(aVal, aIdx) in answer[index]">
                                <input type="radio" :id="index+'a'+aIdx" :value="aIdx" v-model="selection[index]"> <!-- selection 변수로 변경 -->
                                <label :for="index+'a'+aIdx">{{aVal}}</label>
                            </div>
                        </div>
                    </div>
                    <div class="bottom">
                        <div class="controller-wrap">
                            <button class='prev-btn' v-on:click="prev">이전</button>
                            <button class='next-btn' v-on:click="next">다음</button>
                        </div>
                    </div>
                </div>
                <div id="result" class="result-wrap">
                    <!-- 결과 -->
                    <div class="result">{{result}}</div> <!-- result 변수로 변경 -->
                </div>
            </div>
            <script src="./js/test.js"></script>
        </body>
    </html>

    테스트를 시작합니다 라고 적었던 부분을 {{intro}}로 변경했는데요. 여기서 이중으로 중괄호를 쓴 부분은 VueJS 프레임워크 문법인데, 그 부분을 인식하여 JS에 만든 Vue 객체의 data에 선언된 변수로 내용을 대체하는 기능을 합니다.

     

    질문은 여러 개일 수 있으므로 question 배열 변수로 관리하겠습니다.

    그리고 질문마다 선택지가 있고 선택지는 여러 개이므로 2차원 배열로 관리하는 것이 좋아 보입니다. 변수 명은 answer 로 정했습니다. v-for 속성을 활용하여 같은 형태의 DOM으로 여러 개의 선택지를 표현한 부분이 있는데 일단은 따라 작성하시면 됩니다. 또한 질문마다 선택 항목을 저장해야 하므로 selection 배열 변수로 관리합니다. v-model 속성에 의하여 선택 값이 저장이 됩니다.

    그리고 선택에 따른 결과result 변수에 담기로 하겠습니다. 질문의 순서index 변수로 관리하면 될 것 같습니다.

     

     

    JS 변경하기

    개념을 모르면 이해는 어렵지만 내용이 비교적 간단하므로 무작정 따라하기엔 어렵지 않습니다. test.js 파일을 수정하시면 됩니다.

    var test = new Vue({
        el: '#test',
        data: {
            intro: '테스트를 시작 합니다',
            title: '샘플 테스트',
            index: 0,
            question: [],
            answer: [],
            selection: [],
            result: ''
        },
        mounted: function() {
            // 생략
    
            // 질문1, 선택지1 추가
            this.question.push('커피와 술 중에 즐겨 마시는 것은?');
            this.answer.push(['커피','술']);
        },
        methods: {
            // 생략
            next: function() {
                //생략
                
                // 결과 작성
                this.result = this.answer[0][this.selection[0]] + '을(를) 좋아하는 타입 입니다';
            }
        }
    });

    Vue 객체 안에 data 항목을 추가하고 그 안에 필요한 변수들을 선언하면 됩니다. 잘 모르더라도 직관적으로 납득이 되긴 하실 겁니다. 우리가 엑셀의 동작 원리를 다 알고 쓰는 건 아닌 것 처럼 여기서도 일단은 그렇게 넘어 가시길 바랍니다.

     

    intro 변수에 테스트를 시작 합니다, title 변수에 샘플 테스트 라는 내용을 대입 시켰습니다. 아까 말한 내용 기억하시죠? test.html 파일 내용의 {{intro}} 부분을 테스트를 시작 합니다로 대체하게 됩니다. 참고로 index는 0부터 시작하며 여기서는 질문을 1개만 넣을 것이므로 index를 증가시키는 로직은 없습니다.

    배열에 내용을 추가하기 위해서는 push라는 메서드를 활용합니다. 그렇게 question 배열에 질문을 하나 추가하였고, answer 배열에 선택지 배열을 추가하였습니다.

    next 메서드에서는 선택한 결과를 활용하여 결과를 만들어 result 변수에 담았고, 그 내용이 결과 화면에 보이게 됩니다.

     

     

    결과 보기

    변수로 바꾸어 JS에 내용을 작성하였지만 실행을 하면 기존과 동일하게 보입니다.

     

    테스트를 시작 합니다를 클릭해 보겠습니다.

     

    커피를 선택해 보겠습니다.

     

    술을 선택해 보겠습니다.

     

    선택에 따라 결과가 다르게 나타나는 것을 확인할 수 있습니다. 이를 활용하여 앞으로 더욱 다채로운 결과를 낼 수 있을 것으로 기대 됩니다.

     

     

     

     

    다음 시간에는 질문을 여러 개 작성하고 결과를 볼 수 있도록 변경해 보도록 하겠습니다.

    감사합니다 :)

     

     

    웹 언어 코딩으로 심리 테스트 만들기 #5 선다형, 단답형 복합 구현

     

    웹 언어 코딩으로 심리 테스트 만들기 #5 선다형, 단답형 복합 구현

    이번 시간은 기능을 대폭 강화해 보도록 할게요. 이전, 다음 버튼을 실제로 용도에 맞게 완성시키고 질문, 답변도 좀 더 다양하게 구성할 수 있도록 개선할 예정입니다. 웹 언어 코딩으로 심리

    sangminem.tistory.com

     

    반응형

    댓글4

    • 다있어 2021.02.16 10:14

      항상 기다리고 있습니다~ 화이팅!!
      답글

    • 질문드립니다 2021.04.24 21:27

      질문 답변 선택할 때 꼭 input type 라디오로 해야 하나요?
      <ul >
      <li :id="index+'a'+aIdx" :value="aIdx" v-model="selection[index]" v-on:click="next" >
      <label :for="index+'a'+aIdx" >{{aVal}}</label>
      </li>
      </ul>

      이런 식으로 작성했습니다.

      화면에 뿌려지는 것은 잘 되는데, 답변 선택 시 undefined을(를) 좋아하는 타입입니다. 라고 뜨네요.
      답글

      • 아미넴 2021.04.24 21:52 신고

        화면에서 데이터를 입력 받을 때 사용하는 것이 input 태그인데 다른 태그를 이용한다면 별도 구현을 해주지 않는 이상 불가능해 보입니다.

    💲 추천 글