ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • PJT 2. TO-DO LIST 구현 하기 (5일차, 완성)
    기타/프로젝트 2021. 6. 16. 17:34

    오늘은 마지막 요구사항인 main 페이지에서 해야할 일 옆에 ->버튼을 클릭하면 TODO에서 DOING으로 넘어가고 DOING에서 누르면 DONE으로 넘어가는 것을 구현하는 것을 완료하여 프로젝트를 완성했다.

     

    솔직히 너무 어려웠다....

    어제 등록 페이지를 완성하고 이것까지 구현하고 프로젝트를 끝낼 생각이였지만 AJAX로 값을 주고 DOM API로 요소를 변경하는게 너무 어려워서 포기할까도 생각했다.

    하지만, 자려고 누운순간 계속해서 어떻게 구현할 수 있을까 생각하고 있었고

    원래는 아침에 일어나서 코딩테스트 문제를 풀지만 무의식적으로 eclipse를 켜고 코드를 짜고 있었다.

    결과적으로 5시간을 투자하여 완성했다.

     

    일단은 첫 번째 어려웠던 HTML innertext에서는 id값과 type값이 보이지 않는 것이다.

    그러면 DOM으로 요소를 가져와도 정작 servlet으로 보내야하는 id, type은 받을 수 없는 것이다.

    어떻게 보이지 않고 HTML에 없는 id, type을 가져올 수 있을까...

    고민을 하던 중 생각한 것은 button의 id와 class로 해당 todo의 id와 type을 줘서 가져오는 것이다.

     

    즉, 아래 코드를 보면

    const buttons = document.querySelectorAll("button")
    for (const button of buttons) {
      button.addEventListener('click', function(event) {
        console.log("clicked!!");
        var target = event.target;
        var type = target.className;
        var id = target.id;

     일단은 queryselectorAll로 해당 HTML페이지의 button 요소를 다 가져온다.

    (buttons에는 linked list로 저장된다.)

    그 후 for문을 돌려서 click 이벤트가 이루어진 요소(=event)를 변수 target에 담고 target.className과 target.id로 값을 가져오는 것이다.

    즉, ->버튼을 누르면 해당 요소가 target에 저장된다.

    ->버튼의 id는 todo의 id값이고 class는 todo의 className이므로 target.className과 target.id로 우리가 servlet에 넘겨줘야하는 데이터인 type과 id를 가져올 수 있는 것이다.

     

    이렇게 첫 번제 문제를 해결했다.

    그 후에는 type, id 변수에 저장한 값을 어떻게 servlet으로 넘겨주어야하는 것이 문제였다.

    var obj = new Object();
    
       obj.id = id;
       obj.type = type;
    				
       const xhr = new XMLHttpRequest();
    
       xhr.open('POST', 'TodoTypeServlet');
       xhr.setRequestHeader('Content-type', 'application/json');
       xhr.send(JSON.stringify(obj));
      }, false)

    나는 JSON에 해당 데이터를 저장한 다음에 xmlhttprequest로 요청을 보내서 servlet에서 받을 수 있도록 했다.

     

    	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		StringBuffer jb = new StringBuffer();
    		String line = null;
    		try {
    			BufferedReader reader = request.getReader();
    			while ((line = reader.readLine()) != null)
    				jb.append(line);
    		} catch (Exception e) {/* report an error */ }
    						
    		JsonParser parser = new JsonParser();
    		JsonElement element = parser.parse(jb.toString());
    		long id = element.getAsJsonObject().get("id").getAsLong();
    		String type = element.getAsJsonObject().get("type").getAsString();
    		
    		TodoDto todo = new TodoDto(id, type);
    		
    		TodoDao dao = new TodoDao();
    		
    		dao.updateTodo(todo);
    		
    		JSONObject obj = new JSONObject();
    		obj.put("result", "success");
    		response.setContentType("application/x-json; charset=UTF-8");
    		response.getWriter().print(obj);
    	}
    

     

    이후, sevlet에서 위 코드를 통해 요청으로 보낸 값을 받아왔다.

    받아온 id, type을 TodoDao 클래스의 updateTodo()메소드를 통해 todo테이블을 수정했다.

    id가 받아온 id인 튜플을 type이 TODO이면 DOING으로 DOING이면 DONE으로 수정하는 것이다.

     

     

    이제 마지막 해결사항은 ->버튼을 누르면 비동기도 메인 페이지를 수정하는 것이다.

    즉, TODO에 있는 할일 중 ->버튼을 누르면 DOING에서 보여주고

    DOING에 있는 할일 중 ->버튼을 누르면 DONE에서 보여주고 DONE에 있는 할일은 ->버튼이 없으므로 ->버튼을 보이지 않게 해야한다.

    이게 제일 어려웠다....

    일단은 내가 가지고 있고 활용할 수 있는 것은 내가 클릭한 ->버튼이 담겨있는 target 변수이다.

    DOM API를 찾아보면서 요소의 부모요소를 리턴해주는 것을 찾게 되었다.

    그러면 버튼을 담고 있는 부모 요소를 옮겨주는 것만 찾으면 되겠구나 생각했다.

    또 찾아본 결과 appendChild로 요소를 자식 요소로 추가하는 것을 알 수 있었다.

     

    appendChild를 쓰는 방법은

    옮기고 싶은 부모 요소.appendChild(옴기고자 하는 자식 요소);

    예제 코드를 보면

    <body>
    <div id = "div1">
    <h1 id ="h1">안녕하세요</h1>
    </div>
    
    <div id = "div2">
    </div>
    
    </body>
    

    안녕하세요 라는 텍스트를 가진 h1의 부모는 id=div1인 div이다.

    여기서 h1을 id가 div2인 div로 옮기고 싶다면 아래 코드처럼 appendChild를 쓰면된다.

    var h1 =document.getElementById("h1");
    var div = document.getElementById("div2");
    
    div.appendChild(h1);

     

    이렇게 하면 안녕하세요는 id=div1인 div에서 id=div2인 div의 자식으로 넘어간다.

    이 방식을 사용해서 비동기로 servlet에게 요청을 보내고 응답이 오면 요소를 움직일 수 있었다.

     

    이로써, 두 번째 프로젝트를 완성했다!!!

    아래의 영상은 최종구현영상이다.

    (코드는 부스트코스 방침 상 공유를 할 수가 없다ㅠㅠ)

     

     

    댓글

Designed by Tistory.