본문 바로가기
교육/Spring

Spring 개발자 수업 109일차 - jQuery Ajax를 이용한 post-it 메모장 만들기(작성, 위치 저장, 삭제)

by yhyuk 2021. 8. 31.
728x90
반응형

jQuery Ajax를 이용한 post-it 메모장 만들기(작성, 위치 저장, 삭제)

 

[ 구현 목표 ]

- 어제 작업하던 post-it 마무리 구현을 오늘 해보자.

1. 메모 이동 -> (id, left, top) -> DB 반영
2. 메모 z-index 변경 -> (id, zindex) -> DB반영
3. 메모 내용 수정 -> (id, memo) -> DB반영
-----------------------------------------------------------
4. 메모 삭제 -> DB반영


--> 정리해서 업무 구분을 하자면 이동, z-index 변경, 내용 수정은 UPDATE 작업이며 메모 삭제는 DELETE 작업이다.

오늘의 구현 목표 화면  페이지

 

[ 환경설정 및 파일 생성 ]

- 환경설정, 파일 및 DB테이블은 어제와 동일하다.

- https://kyhyuk.tistory.com/156

 

Spring 개발자 수업 108일차 - jQuery Ajax를 이용한 post-it 메모장 만들기(생성, 확인)

jQuery Ajax를 이용한 post-it 메모장 만들기(생성, 확인) - 기존에 배웠던 Ajax를 활용해 post-it 형식의 메모장을 만들어서 post-it 메모장 생성, 리스트 확인, 메모 작성, 메모 삭제 기능을 구현하기 -

kyhyuk.tistory.com

 

[ MemoController.java ]

- 이동, z-index변경, 내용 수정(edit) 작업과 메모 삭제(del) 작업을 구분지어 나눈다.

@Controller
public class MemoController {
	
    @Autowired
    private AjaxDAO dao;

    @RequestMapping(value = "/memo/edit.action", method = { RequestMethod.POST })
    @ResponseBody
    public int edit(HttpServletRequest req, HttpServletResponse resp, HttpSession session
                     , MemoDTO dto) {
		
        int result = dao.editMemo(dto);

        return result;
	}	
    
    @RequestMapping(value = "/memo/del.action", method = { RequestMethod.POST })
    @ResponseBody
    public int delMemo(HttpServletRequest req, HttpServletResponse resp, HttpSession session
                       , String id) {
		
        int result = dao.delMemo(id);
		
        return result;
	}	

}

 

[ MemoDAO.java ]

@Repository
public class MemoDAO {

    @Autowired
    private SqlSessionTemplate template;

    public int editMemo(MemoDTO dto) {
        return template.update("ajax.editMemo", dto);
    }

    public int delMemo(String id) {
        return template.delete("ajax.delMemo", id);
    }

}

 

[ MemoDTO.java ]

- 어제와 동일

 

[ ajax.xml ]

- 수정, 삭제 쿼리문 작성

<mapper namespace="ajax">

	<update id="editMemo" parameterType="com.test.ajax.MemoDTO">
		update tblAjaxMemo set
			left = #{left},
			top = #{top},
			zindex = #{zindex},
			memo = #{memo}
				where id = #{id}
	</update>
	
	<delete id="delMemo" parameterType="String">
		delete from tblAjaxMemo where id = #{id}
	</delete>

</mapper>

 

 

[ index.jsp ]

  - CSS와 HTML은 어제와 동일하며 Script부분이 코드가 많이 지저분해졌다. (리펙토링 필수... 비슷한 코드가 많음)

  1) post-it 메모지 추가시 발생하는 이벤트

// 메모지 생성 시 무작위 left값
function getLeft() {
	let left = 0;
    while (left < 100) {
    	left = Math.random() * $(document).width() - 250;
    }
    return left;
}

// 메모지 생성 시 무작위 top값
function getTop() {
	let top = 0;
    while (top < 100) {
    	top = Math.random() * $(document).height() - 250;
    }
    return top;
}

let no = ${no + 1}; 	    // id값
let back = ${back + 1}; 	// 이미지 파일명
let zindex = ${zindex + 1};	// 클릭한 postit 가장 앞으로
   		
// 버튼 클릭시 새 메모 추가하기
$('#addMemo').click(function() {

	// post-it 이미지파일(back)이 6개밖에 없으므로..
	if (back > 6) back = 1;
	
    let left = getLeft();
    let top = getTop();
    
    $('body').append('<div class="memo" id="m' + no + '" style="background-image: url(/ajax/resources/images/0' + back + '.png);" data-back="0' + back + '"><div class="btnClose">&times;</div><textarea class="txtMemo" ></textarea></div>')
    		.children()
            .last()
            .draggable({
            	stop: function(event ui) {
                
                	let left = ui.position.left;
                    let top = ui.position.top;
                    let id = this.id;
                    let zindex = $(this).css('z-index');
                    let memo = $(this).find('textarea').val();
                    
                    $.ajax({
                    	type: 'POST',
                        url: '/ajax/memo/edit.action',
                        data: 'left=' + left + '&top=' + top + '&id=' + id + '&zindex=' + zindex + '&memo=' + memo,
                        dataType: 'json',
                        success: function(result) {
                        	if (result == 1) {}
                            else {}
                        },
                        error: function(a, b, c) { 
                        	console.log(a, b, c);
                        }
                    });
                }
            })
            .css('position', 'absolute')  // 메모객체
            .css('left', left + 'px')
            .css('top', top + 'px')
            .mousedown(function() { // 메모지 클릭후 이동(메모객체)
            	$(this).css('z-index', zindex);
                
                let left = parseFloat($(this).css('left'));
                let top = parseFloat($(this).css('top'));
                let id = this.id;
                let memo = $(this).find('textarea').val();
                
                $.ajax({
                	type: 'POST',
                    url: '/ajax/memo/edit.action',
                    data: 'left=' + left + '&top=' + top + '&id=' + id + '&zindex=' + zindex + '&memo=' + memo,
                    dataType: 'json',
                    success: function(result) {
                    	if (result == 1) {}
                        else {}
                    },
                    error: function(a, b, c) {
                    	console.log(a, b, c);
                    }
                });
                
                zindex++;
            })
            .find('.btnClose').click(function() { // 메모객체의 닫기버튼
            	let id = this.parentNode.id;
                
                $.ajax({
                	type: 'POST',
					url: '/ajax/memo/del.action',
                    data: 'id=' + id,
                    dataType: 'json',
                    success: function(result) {
                    	if (result == 1) {}
                        else {}
                    },
                    error: function(a, b, c) {
                    	console.log(a, b, c);
                    }
                });
                
                $(this).parent().remove();
            })
            .next().blur(function() { // 메모 객체의 텍스트 박스
				let left = parseFloat($(this).parent().css('left'));
				let top = parseFloat($(this).parent().css('top'));
				let id = this.parentNode.id;
				let memo = $(this).val();
                
                 $.ajax({
                	type: 'POST',
					url: '/ajax/memo/del.action',
                    data: 'left=' + left + '&top=' + top + '&id=' + id + '&zindex=' + zindex + '&memo=' + memo,
                    dataType: 'json',
                    success: function(result) {
                    	if (result == 1) {}
                        else {}
                    },
                    error: function(a, b, c) {
                    	console.log(a, b, c);
                    }
                });               
            
            });
            
            
            $.ajax({
				type: 'POST',
				url: '/ajax/memo/add.action',
				data: 'id=m' + no + '&background=0' + back + '&left=' + left + '&top=' + top + '&zindex=0',
				dataType: 'json',
				success: function(result) {
					if (result == 1) {}
					else {}
				},
				error: function(a, b, c) {
					console.log(a, b, c);
				}
            });
            
            no++;
            back++;
});

 

 

  2) index.action에 접속했을 때 저장되어 있는 post-it 메모지 출력

<c:forEach items="${list}" var="dto">
$('body').append(`<div class="memo" id="${dto.id}" style="background-image: url(/ajax/resources/images/${dto.background}.png);z-index:${dto.zindex};" data-back="${dto.background}"><div class="btnClose">&times;</div><textarea class="txtMemo">${dto.memo}</textarea></div>`)
		.children()
		.last()
		.draggable({
		stop: function(event, ui) {
   						
			let left = ui.position.left;
			let top = ui.position.top;
			let id = this.id;
			let zindex = $(this).css('z-index');
			let memo = $(this).find('textarea').val();
					
			$.ajax({
				type: 'POST',
				url: '/ajax/memo/edit.action',
				data: 'left=' + left + '&top=' + top + '&id=' + id + '&zindex=' + zindex + '&memo=' + memo,
				dataType: 'json',
				success: function(result) {
					if (result == 1) {}
					else {}
				},
				error: function(a, b, c) {
					console.log(a, b, c);
				}
			});
   						
		}
}) // 메모 객체
.css('position', 'absolute')  // 메모객체
.css('left', '${ dto.left }px')
.css('top', '${ dto.top }px')
.mousedown(function() { // 메모객체
				
	$(this).css('z-index', zindex);
			
	let left = parseFloat($(this).css('left'));
	let top = parseFloat($(this).css('top'));
	let id = this.id;
	let memo = $(this).find('textarea').val();
				
	$.ajax({
		type: 'POST',
		url: '/ajax/memo/edit.action',
		data: 'left=' + left + '&top=' + top + '&id=' + id + '&zindex=' + zindex + '&memo=' + memo,
		dataType: 'json',
		success: function(result) {
			if (result == 1) {}
			else {}
		},
		error: function(a, b, c) {
			console.log(a, b, c);
		}
	});
	   			
	zindex++;
})
.find('.btnClose').click(function() { // 메모객체의 닫기버튼
				
	let id = this.parentNode.id;					
				 
	$.ajax({
		type: 'POST',
		url: '/ajax/memo/del.action',
		data: 'id=' + id,
		dataType: 'json',
		success: function(result) {
			if (result == 1) {} 
			else {}
		},
		error: function(a,b,c) {
			console.log(a,b,c);
		}
	}); 
				
	$(this).parent().remove();
})
.next().blur(function() { // 메모 객체의 텍스트 박스
				
	let left = parseFloat($(this).parent().css('left'));
	let top = parseFloat($(this).parent().css('top'));
	let id = this.parentNode.id;
	let memo = $(this).val();
										 
	$.ajax({
		type: 'POST',
		url: '/ajax/memo/edit.action',
		data: 'left=' + left + '&top=' + top + '&id=' + id + '&zindex=' + zindex + '&memo=' + memo,
		dataType: 'json',
		success: function(result) {
			if (result == 1) {} 
			else {}
		},
		error: function(a,b,c) {
			console.log(a,b,c);
		}
					
	}); 
				
});
</c:forEach>

 

[ Sciprt 정리 ]

- 오늘 수업을 진행하면서 매우 비슷한 코드가 많이 발생해 코드가 많이 지저 분해졌는데, 리펙토링은 따로 할 예정이며 우선 코드별 업무를 구분하여 정리하기

총 두개의 업무로 나누어서 script를 실행 구분을 했으며 다소 복잡해보이지만 비슷한 코드가 많으므로 정리를 따로 해보자

 

[ 결과 화면 ]

- post-it 생성 후 마우스를 클릭 후 이동한 뒤 메모 작성은 물론 삭제 및 수정도 정상적으로 작동하며, DB에 ajax를 통해 새로고침없이 반영이 되어 새로고침을 하더라도 현재 이동한 위치와 내용이 그대로 남아있는것을 볼 수 있다.

기존에 작성 해둔 메모지를 여기저기 이동 및 내용을 수정하고 새로고침했을 때 위치 및 내용이 그대로 저장된다.

 

[ 참고 document ]

- https://api.jqueryui.com/draggable/#event-stop

 

Draggable Widget | jQuery UI API Documentation

Description: Allow elements to be moved using the mouse. Make the selected elements draggable by mouse. If you want not just drag, but drag & drop, see the jQuery UI Droppable plugin, which provides a drop target for draggables. Theming The draggable widge

api.jqueryui.com

 


MEMO>

# 이전에도 느꼈지만, 오늘 ajax를 사용하면서 사용자의 관점으로 브라우저를 사용한다고 생각했을 떄 매우 자연스럽고 편리하다는걸 깨달았다. 한편으로는 개발자는 힘들겠다라는 것도 깨달았다.... 

# 구글링을 통해 지식을 얻는것도 좋지만, 내가 사용하는 API에 대해 100% 정확히 나와있는것은 document 이므로 document를 먼저 보는 습관을 기르자

# 많이 꼬여있는 선처럼 복잡할 것 같은 구현도 하나씩 해나가면 결국엔 할 수 있다!
728x90
반응형

댓글