<실습>
1. board_view.html 마무리
- 댓글 영역 생성
- 타임라인 추가, 페이징 처리
- 모달창 추가
- 댓글등록 시 ajax로 화면처리
- 댓글 수정 기능(모달창) 수정
2. board_list.html -> board_list.jsp로 변환
댓글 영역 생성
먼저, 아래 사이트에서 댓글 영역으로 사용할 디자인의 소스를 가져온다.
adminlte.io/themes/v3/pages/kanban.html
AdminLTE 3 | Kanban Board
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
adminlte.io
우리가 쓸 디자인에 해당하는 부분을 크롬의 검사 기능으로 확인하고, copy elements를 한다.
<div class="card card-primary card-outline........> 이 부분을 copy한다.
복사한 것을 board_view.html의 버튼영역 바로 밑에 붙여넣는다.
<div class="card card-primary card-outline col-12">
<div class="card-header">
<h5 class="card-title">Cread first Milestone</h5>
</div>
</div>
위의 코드에서 card-title을 Add New Apply로 수정하고, 댓글을 입력할 폼 영역을 추가한다.
<div class="card card-primary card-outline col-12">
<div class="card-header">
<h5 class="card-title">Add New Reply</h5>
</div>
<form action="board_view.html" name="reply_form" method="post">
</form>
</div>
board_write.html에서 <div class="card-body"> 요소를 복사해온다. (아래)
<div class="card-body">
<div class="form-group">
<label for="user_id">title</label>
<input type="text" class="form-control" name="user_id" id="user_id" placeholder="제목 입력해주세요." required>
<!-- form에서 input같은 입력태그에는 name 속성이 반드시 필요.name 속성값 = DB 필드 속성명
DB에 입력할 때 값을 전송하게 되는데 전송값을 저장하는 이름이 name이 되고,위에서는 user_id이다.-->
</div>
<div class="form-group">
<!-- label for과 textarea id는 같게 설정 -->
<label for="content">Content</label>
<textarea row="5" name="content" id="content" class="form-control"></textarea>
</div>
<div class="form-group">
<label for="email">writer</label>
<input type="text" class="form-control" name="email" id="email" placeholder="작성자을 입력해주세요." required>
<!-- 필수 입력값은 html5에서 지원하는 유효성 검사 중 required 속성 사용해서 null값을 체크한다.(유효성검사) -->
</div>
<div class="form-group">
<label for="customFile">attach</label>
<div class="custom-file">
<input type="file" name="file" class="custom-file-input" id="customFile">
<label class="custom-file-label" for="customFile">파일을 선택해주세요</label>
</div>
</div><!-- /.card-body -->
board_view.html에서는 필요한 부분을 제외하고 지워주고, board_view에 맞는 내용으로 고쳐준다. (아래)
<form action="board_view.html" name="reply_form" method="post">
<div class="card-body">
<div class="form-group">
<label for="writer">Writer</label>
<input type="text" class="form-control" name="writer" id="writer" placeholder="작성자를 입력해주세요." required>
<!-- form에서 input같은 입력태그에는 name 속성이 반드시 필요.name 속성값 = DB 필드 속성명
DB에 입력할 때 값을 전송하게 되는데 전송값을 저장하는 이름이 name이 되고,위에서는 writer이다.-->
</div>
<div class="form-group">
<label for="reply_text">Reply Text</label>
<input type="text" class="form-control" name="reply_text" id="reply_text" placeholder="내용 입력해주세요." required>
<!-- form에서 input같은 입력태그에는 name 속성이 반드시 필요.name 속성값 = DB 필드 속성명
DB에 입력할 때 값을 전송하게 되는데 전송값을 저장하는 이름이 name이 되고,위에서는 reply_text이다.-->
</div>
<button type="button" class="btn btn-warning float-left mr-1 text-white" id="insertReplyBtn">댓글등록</button>
<!-- 게시판에서는 폼을 전송할때 submit타입을 사용하지만, 댓글은 Ajax로 전송하기 땜누에 button타입으로 지정 -->
</div>
</form>
여기서 댓글 등록이 input태그가 아니고, type이 submit이 아닌 button인 이유는?
- 댓글은 Ajax로 전송할 것이기 때문에 button타입으로 지정한다.
* Ajax란?
- javascript의 라이브러리 중 하나이며, Asyncronized Javascript and Xml의 약자
- 비동기통신으로 자바스크립트로 JSON(text)를 재처리하는 기술이다.
- 비동기? 웹페이지를 리로드하지 않고 데이터를 불러오는 방식
- 브라우저가 가지고 있는 XMLHttpRequest객체를 이용해서 전체 페이지를 새로 고치지 않고 페이지 일부만을 위한 데이터로드 기법
- Json이나 xml형태로 필요한 데이터만 받아 갱신 -> 자원과 시간 절약
- Jquery와 함께 사용하면 적은 코딩량으로 같은 동작할 수 있게 됨
- Rest API 방식으로 화면처리하는 것이 트렌드 (빅데이터를 시각화하는데 RestAPI+Ajax 기술 사용)
- Rest : Representation 기존 데이터를 가지고, 화면 깜빡임 없이 데이터를 재가공하는 처리
- Rest API 사용되는 기술 : 데이터 전송/수신을 Ajax기술(프론트-개발자)로 처리. API(서버단기술)
위의 과정까지 하면 아래처럼 댓글입력란을 만들 수 있다.
댓글 타임라인 생성
이제 댓글 밑에 댓글 타임라인을 만들어준다. 타임라인 디자인 또한 AdminLTE v3의 UI elements - Timeline에서 가져온다.
타임라인 디자인을 전체 다 가져오기에는 불필요한 것이 많기 때문에 두 부분만 따로 따로 가져온다.
1. 타임라벨
<div class="time-label">
<span class="bg-red">10 Feb. 2014</span>
</div>
+
2. 댓글 내용을 보여주는 부분
<div>
<i class="fas fa-envelope bg-blue"></i>
<div class="timeline-item">
<span class="time"><i class="fas fa-clock"></i> 12:05</span>
<h3 class="timeline-header"><a href="#">Support Team</a> sent you an email</h3>
<div class="timeline-body">
Etsy doostang zoodles disqus groupon greplin oooj voxy zoodles,
weebly ning heekya handango imeem plugg dopplr jibjab, movity
jajah plickers sifteo edmodo ifttt zimbra. Babblely odeo kaboodle
quora plaxo ideeli hulu weebly balihoo...
</div>
<div class="timeline-footer">
<a class="btn btn-primary btn-sm">Read more</a>
<a class="btn btn-danger btn-sm">Delete</a>
</div>
</div>
</div>
| |
위 두 가지를 <div class="timeline">으로 묶어주고, 댓글 영역 안쪽, 댓글 폼 영역 밖에 위치시킨다.
내용은 댓글 영역에 맞춰서 변경한다.
<div class="timeline ml-3">
<div class="time-label">
<span class="bg-red">Reply List[1] </span>
</div>
<div>
<i class="fas fa-envelope bg-blue"></i>
<div class="timeline-item">
<h3 class="timeline-header">작성자</h3>
<div class="timeline-body">댓글 입력 테스트</div>
<a class="btn btn-primary btn-sm">수정</a>
<div class="timeline-footer">
</div>
</div>
</div>
* timeline ml-3은 댓글영역와 타임라인 영역의 가로 폭을 맞추기 위함이다. margin-left 3이라는 뜻
*   : 스페이스 한 번과 같다.
페이징 처리
댓글 영역 페이징 처리를 한다.
페이징 영역 소스는 member_list.html에서 쓴 페이징 디자인을 가져온다.
위치는 댓글영역 안 쪽, 타임라인 바로 밑에 위치시킨다.
<!-- 페이징처리 시작 -->
<div class="pagination justify-content-center">
<ul class="pagination">
<li class="paginate_button page-item previous disabled" id="example1_previous"><a href="#" aria-controls="example1" data-dt-idx="0" tabindex="0" class="page-link">«</a></li>
<!-- previous (위) -->
<li class="paginate_button page-item active"><a href="#" aria-controls="example1" data-dt-idx="1" tabindex="0" class="page-link">1</a></li>
<li class="paginate_button page-item "><a href="#" aria-controls="example1" data-dt-idx="2" tabindex="0" class="page-link">2</a></li>
<li class="paginate_button page-item "><a href="#" aria-controls="example1" data-dt-idx="3" tabindex="0" class="page-link">3</a></li>
<!-- next (아래) -->
<li class="paginate_button page-item next" id="example1_next"><a href="#" aria-controls="example1" data-dt-idx="7" tabindex="0" class="page-link">»</a></li>
</ul>
</div>
<!-- 페이징처리 끝 -->
* 여기서 «는 《, »는 》
모달창 추가
댓글 수정 버튼을 눌렀을 때, 나타나는 모달창을 추가한다.
* 모달창이란?
- Modal , 이용자가 팝업 대화상자 내용을 작업하기 전에는 다른 화면으로 이동하지 못하는 방식의 팝업창
- Modeless : 모달리스, 이용자가 팝업 대화상자 내용을 작업하기 전이라도 팝업창을 띄운 상태에서 다른 창으로 이동 가능
모달창의 디자인은 아래의 사이트에서 가져온다.
adminlte.io/themes/v3/pages/UI/modals.html
AdminLTE 3 | Modals & Alerts
adminlte.io
모달창 소스는 푸터 영역의 자바스크립트를 모아놓은 곳 아래에 붙여넣는다. 내용은 설계에 맞게 변경한다.
- .modal fade 의 id="replyModal"로 변경
- .modal-title 작성자로 변경
- .modal-body에 input태그로 replytext 추가
- 버튼 추가
<!-- Modal -->
<div class="modal fade" id="replyModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">작성자</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<input type="text" class="form-control" name="replytext" id="replytext" placeholder="내용 입력해주세요." required>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">닫기</button>
<button type="button" class="btn btn-primary">수정</button>
<button type="button" class="btn btn-danger">삭제</button>
</div>
</div>
</div>
</div>
수정 버튼을 눌렀을 때 나오는 모달창이기 때문에, 댓글수정 버튼도 수정한다.
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
수정
</button>
댓글등록 시 ajax로 화면처리
- 댓글 등록을 누르면, 화면 전체를 reload하지 않고 댓글 구현 부분만 화면 깜빡임없이 재구현 되도록 한다.
- 댓글 등록 시, 댓글 타임라인영역에 DB에 저장된 댓글 번호(rno)가 부여되고 댓글 작성자(replyer), 댓글 내용(replytext)가 출력된다. -> 지금은 DB와 연동되지 않았으므로 더미데이터로 테스트.
댓글 등록 버튼을 클릭했을 때 구현 내용이다.
- printReplyList가 호출되면서 데이터가 출력된다.
- target은 .timelabel 클래스이고, 출력되는 위치는 .timelabel 클래스 영역 아래(이후)이다.
<script>
var printReplyList = function(data, target, templateObject) {
var template = Handlebars.compile(templateObject.html()); //html태그로 변환
var html = template(data); //빅데이터를 리스트탬플릿에 바인딩(데이터결합,묶음) 역할. 변수 html에 저장되었음.
$(".template-div").remove(); // 화면에 보이는 댓글리스트만 지우기
target.after(html); //target은 .time-label 클래스 영역을 가리킨다.
};
</script>
- 댓글등록버튼을 클릭했을 때, 임의로 넣은 더미데이터가 출력되도록 한다.
<script>
$(document).ready(function(){
$("#insertReplyBtn").on("click", function() { //댓글등록버튼 클릭했을 때 구현 내용
// Ajax 이용해서, 화면을 Representation (REST-API방식) 부분 화면을 재구현
$.ajax({
//여기서부터는 프론트엔드 개발자 영역
type:'get', //지금은 html이라서 get방식이지만, jsp로 가면 post방식으로 바꿔야한다.(보안)
url:'board_view.html', //jsp로 가면, ReplyController에서 지정한 url로 변경
dataType:'text', //ReplyController로부터 데이터를 text형식으로 받겠다고 명시.
success:function(result){ //응답이 성공하면(상태값 200 OK), 위 경로에서 반환받은 result(JSON 텍스트 데이터) 이용해서 화면 재구현
//지금은 html이라서 result값을 이용할 수 없기 대문에 댓글더미데이터를 만든다.
result=[
//{rno:댓글번호, bno:게시믈번호, replytext:"첫번째댓글", replyer:"admin", regdate:타임스탬프}
{rno:1,bno:15,replytext:"첫번째댓글",replyer:"admin",regate:1601234512345}, //첫번째 댓글 데이터
{rno:2,bno:15,replytext:"두번째댓글",replyer:"user02",regate:1601234512345} //두번째 댓글 데이터
];
//printReplyList(빅데이터, 출력할 타겟 위치, 빅데이터를 가지고 바인딩된-묶인 템플릿화면))
printReplyList(result, $(".time-label"), $("#template"));//화면에 출려하는 구현함수를 호출하면 실행.
//result값을 받아서 #template으로 가공시켜서 time-label 위치에 출력한다.
}
});
});
});
</script>
댓글 수정 기능(모달창) 수정
- 수정 버튼을 눌렀을 때, 모달창에 작성자가 동적으로 바뀌도록(클릭한 댓글의 댓글작성자와 같도록) 수정.
(하지만 모달창에서는 작성자를 수정 불가능하도록 한다.)