1. 회원가입 기능
- 아이디, 비밀번호, 비밀번호 확인, 이름, 이메일 -> 필수입력 자바스크립트 추가하기
- form.jsp
<form class="bg-light border p-3" method="post" action="register.jsp" onsubmit="return checkForm();"> <%-- 같은 폴더에 있는 register.jsp --%>
<div class="mb-3">
<label class="form-label">아이디</label>
<input type="text" class="form-control" name="id" />
</div>
<div class="mb-3">
<label class="form-label">비밀번호</label>
<input type="password" class="form-control" name="password" />
</div>
<div class="mb-3">
<label class="form-label">비밀번호 확인</label>
<input type="password" class="form-control" name="password2" />
</div>
<div class="mb-3">
<label class="form-label">이름</label>
<input type="text" class="form-control" name="name" />
</div>
<div class="mb-3">
<label class="form-label">이메일</label>
<input type="text" class="form-control" name="email" />
</div>
<div class="text-end">
<a href="../home.jsp" class="btn btn-secondary">취소</a> <%-- 상위 폴더에 있는 home.jsp --%>
<button type="submit" class="btn btn-primary">회원가입</button>
</div>
</form>
</div>
<script type="text/javascript">
function checkForm(){ // 제출할 때 아이디,비밀번호 체크하기
var idField = document.querySelector("[name=id]");
var passwordField = document.querySelector("[name=password]");
var password2Field = document.querySelector("[name=password2]");
var nameField = document.querySelector("[name=name]");
var emailField = document.querySelector("[name=email]");
if(idField.value === ""){
alert("아이디는 필수입력값입니다.");
idField.focus();
return false;
}
if(passwordField.value === ""){
alert("비밀번호는 필수입력값입니다.");
passwordField.focus();
return false;
}
if(passwordField.value != password2Field.value){
alert("비밀번호가 서로 일치하지 않습니다.");
passwordField.focus();
return false;
}
if(nameField.value === ""){
alert("이름은 필수입력값입니다.");
nameField.focus();
return false;
}
if(emailField.value === ""){
alert("이메일은 필수입력값입니다.");
emailField.focus();
return false;
}
return true;
}
</script>
</body>
</html>

2. 로그인 기능
- 입력값 누락되지 않는 자바스크립트
- login.jsp
<div id="error-message-box" class="alert alert-danger d-none">
<strong>입력값 누락</strong> <span id="message-box"></span>
</div>
<form class="bg-light border p-3" method="post" action="login.jsp" onsubmit="return checkLoginForm();">
<div class="mb-3">
<label class="form-label">아이디</label>
<input type="text" class="form-control" name="id" />
</div>
<div class="mb-3">
<label class="form-label">비밀번호</label>
<input type="password" class="form-control" name="password" />
</div>
<div class="text-end">
<button type="submit" class="btn btn-primary">로그인</button>
<a href="form.jsp" class="btn btn-secondary">회원가입</a>
</div>
</form>
</div>
<script type="text/javascript">
function checkLoginForm(){
var idField = document.querySelector("[name=id]");
var passwordField = document.querySelector("[name=password]");
var errorMessageBox = document.querySelector("#error-message-box");
var messageBox = document.querySelector("#message-box");
if(idField.value === ""){
errorMessageBox.classList.remove("d-none");
messageBox.textContent = "아이디는 필수입력값입니다.";
idField.focus();
return false;
}
if(passwordField.value === ""){
errorMessageBox.classList.remove("d-none");
messageBox.textContent = "비밀번호는 필수입력값입니다.";
passwordField.focus();
return false;
}
return true;
}
</script>
</body>

3. 검색기능 (동적 쿼리)
검색어가 없을 때와 있을 때, 조회순 판매량 순으로 정렬할 때마다 SQL을 각각 작성해야 하면 비효율
-> 다이나믹 쿼리 (동적 쿼리) !!

검색어 포함하는 부분이 어떨 때는 포함되고, 어떨 때는 포함되지 않도록 하고 싶어
-> 다이나믹 쿼리 ( <dynamic></dynamic> )
-> 언제 포함하고싶은데?
-> 조건 삽입
<isNotNull property="keyword">
map에서 keyword값을 찾았는데 null이 아닐 때
- list.jsp
<%@page import="com.sample.util.Pagination"%>
<%@page import="com.sample.vo.User"%>
<%@page import="com.sample.vo.Board"%>
<%@page import="java.util.List"%>
<%@page import="com.sample.dao.BoardDao"%>
<%@page import="java.util.HashMap"%>
<%@page import="java.util.Map"%>
<%@page import="com.sample.util.StringUtils"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js"></script>
<title>익명 게시판</title>
</head>
<body>
<jsp:include page="../common/header.jsp">
<jsp:param name="menu" value="board"/>
</jsp:include>
<div class="container my-3">
<%
int rows = StringUtils.stringToInt(request.getParameter("rows"), 10); // 없으면 10개씩 가져오기
String sort = StringUtils.nullToValue(request.getParameter("sort"), "date");
int currentPage = StringUtils.stringToInt(request.getParameter("page"), 1);
String opt = StringUtils.nullToValue(request.getParameter("opt"), "title");
String keyword = StringUtils.nullToValue(request.getParameter("keyword"), "");
BoardDao boardDao = new BoardDao();
Map<String, Object> param = new HashMap<>();
if(!opt.isEmpty() && !keyword.isEmpty()){ // keyword가 ""일 때는 추가x(keyword=null), 값이 있을 때는 추가
param.put("opt", opt);
param.put("keyword", keyword);
}
// 총 게시글 개수 조회 (키워드에 해당하는)
int totalRows = boardDao.getTotalRows(param); // 빈 keyword -> 비어있는 param전달, 값있는 keyword -> 값있는 param전달
// Pagination 객체 생성
Pagination pagination = new Pagination(currentPage, totalRows, rows);
// 게시글 목록 조회
param.put("sort", sort);
param.put("begin", pagination.getBegin());
param.put("end", pagination.getEnd());
List<Board> boardList = boardDao.getBoards(param); // begin,end는 무조건 포함, keyword는 포함 될수도 안될수도 있음
%>
<h1 class="mb-3 fs-4 border p-2 bg-light">게시글 리스트</h1>
<div class="d-flex justify-content-between">
<div>
<a href="list.jsp?rows=5" class="btn btn-sm <%=rows == 5 ? "btn-dark" : "btn-outline-dark" %>" onclick="changeRows(event, 5)">5개씩</a>
<a href="list.jsp?rows=10" class="btn btn-sm <%=rows == 10 ? "btn-dark" : "btn-outline-dark" %>" onclick="changeRows(event, 10)">10개씩</a>
<a href="list.jsp?rows=20" class="btn btn-sm <%=rows == 20 ? "btn-dark" : "btn-outline-dark" %>" onclick="changeRows(event, 20)">20개씩</a>
</div>
<div>
<a href="list.jsp?sort=date" class="btn btn-sm <%="date".equals(sort) ? "btn-dark" : "btn-outline-dark" %>" onclick="changeSort(event, 'date')">최신순</a>
<a href="list.jsp?sort=title" class="btn btn-sm <%="title".equals(sort) ? "btn-dark" : "btn-outline-dark" %>" onclick="changeSort(event, 'title')">제목순</a>
<a href="list.jsp?sort=read" class="btn btn-sm <%="read".equals(sort) ? "btn-dark" : "btn-outline-dark" %>" onclick="changeSort(event, 'read')">조회수 많은 순</a>
</div>
<form class="row row-cols-lg-auto g-3 align-items-center" action="list.jsp">
<input type="hidden" name="page" value="<%=currentPage %>" /> <!-- 서버로 보내야 하는 값을 여기다가 적어 -->
<input type="hidden" name="rows" value="<%=rows %>" />
<input type="hidden" name="sort" value="<%=sort %>" />
<div class="col-12">
<select class="form-select form-select-sm" name="opt">
<option value="title" <%="title".equals(opt) ? "selected" : "" %>> 제목</option>
<option value="writer" <%="writer".equals(opt) ? "selected" : "" %>> 작성자</option>
<option value="content" <%="content".equals(opt) ? "selected" : "" %>> 내용</option>
</select>
</div>
<div class="col-12">
<input type="text" class="form-control form-control-sm" name="keyword" value="<%=keyword %>">
</div>
<div class="col-12">
<button type="button" class="btn btn-primary btn-sm" onclick="submitForm(1);">검색</button> <!-- submit을 해버리면 저대로 보내버려서 page번호를 1로 못바꿈 -->
</div>
</form>
</div>
<table class="table">
<thead>
<tr>
<th>번호</th>
<th>제목</th>
<th>작성자</th>
<th>조회수</th>
<th>리뷰갯수</th>
<th>등록일</th>
</tr>
</thead>
<tbody>
<%
if (boardList.isEmpty()) {
%>
<tr><td class="text-center" colspan="6"> 게시글 정보가 없습니다. </td></tr>
<%
} else {
for (Board board : boardList) {
%>
<tr>
<td><%=board.getNo() %></td>
<td><a href="detail.jsp?no=<%=board.getNo() %>"><%=board.getTitle() %></a></td>
<td><%=board.getWriter() %></td>
<td><%=board.getReadCount() %></td>
<td><%=board.getReviewCount() %></td>
<td><%=StringUtils.dateToText(board.getCreatedDate()) %></td>
</tr>
<%
}
}
%>
</tbody>
</table>
<%
int beginPage = pagination.getBeginPage(); // 시작 페이지번호
int endPage = pagination.getEndPage(); // 끝 페이지번호
boolean isFirst = pagination.isFirst(); // 첫 페이지인지 여부, 이전 버튼의 비활성화에서 사용
boolean isLast = pagination.isLast(); // 마지막 페이지인지 여부, 다음 버튼의 비활성화에서 사용
int prevPage = pagination.getPrevPage(); // 이전 페이지번호, 이전 버튼에서 사용
int nextPage = pagination.getNextPage(); // 다음 페이지번호, 다음 버튼에서 사용
%>
<div aria-label="navigation">
<ul class="pagination justify-content-center">
<li class="page-item">
<a class="page-link <%=isFirst ? "disabled" : "" %>"
href="list.jsp?page=<%=prevPage %>"
onclick="changePage(event, <%=prevPage %>)">이전</a>
</li>
<%
for (int number = beginPage; number <= endPage; number++) {
%>
<li class="page-item">
<a class="page-link <%=currentPage == number ? "active" : "" %>"
href="list.jsp?page=<%=number %>"
onclick="changePage(event, <%=number %>)"><%=number %></a>
</li>
<%
}
%>
<li class="page-item">
<a class="page-link <%=isLast ? "disabled" : "" %>"
href="list.jsp?page=<%=nextPage %>"
onclick="changePage(event, <%=nextPage %>)">다음</a>
</li>
</ul>
</div>
<div>
<a href="form.jsp" class="btn btn-primary btn-sm float-end">새 글 등록</a>
</div>
</div>
<script type="text/javascript">
// 표시할 행 개수를 클릭했을 때 실행되는 이벤트 핸들러 함수다.
function changeRows(event, rows) {
event.preventDefault(); // 링크의 기본동작(클릭한 페이지로 이동)이 일어나지 않게 한다.
var rowsField = document.querySelector("[name=rows]"); // <input type="hidden" name="rows" /> input 엘리먼트를 조회한다.
rowsField.value = rows; // 위에서 조회한 input 엘리먼트의 값을 변경한다. rows 값이 변경된다.
submitForm(1); // 폼 입력값을 서버로 제출하는 함수를 실행한다. 한번에 표시할 행의 갯수를 변경했기 때문에 페이지번호는 1이 되어야 한다.
}
// 정렬방식을 클릭했을 때 실행되는 이벤트 핸들러 함수다.
function changeSort(event, sort) {
event.preventDefault();
var sortField = document.querySelector("[name=sort]"); // <input type="hidden" name="sort" /> input 엘리먼트를 조회한다.
sortField.value = sort; // 위에서 조회한 input 엘리먼트의 값을 변경한다. sort 값이 변경된다.
submitForm(1); // 폼 입력값을 서버로 제출하는 함수를 실행한다. 정렬방식을 변경했기 때문에 페이지번호는 1이 되어야 한다.
}
// 페이지번호를 클릭했을 때 실행되는 이벤트 핸들러 함수다.
function changePage(event, page) {
event.preventDefault(); // 링크의 기본동작이 일어나지 않게 한다.
submitForm(page); // 폼 입력값을 서버로 제출하는 함수를 실행한다.
}
// 검색버튼을 클릭했을 때 실행되는 이벤트 핸들러 함수다.
function submitForm(page) {
var pageField = document.querySelector("[name=page]"); // <input type="hidden" name="page" /> input 엘리먼트를 조회한다.
pageField.value = page; // 위에서 조회한 input 엘리먼트의 값을 변경한다. page 번호가 변경된다.
var form = document.querySelector("form"); // <form /> 엘리먼트를 조회한다.
form.submit(); // 폼 입력값을 서버로 제출한다. rows, page, keyboard가 한번에 서버로 제출된다.
}
</script>
</body>
</html>
- board.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="boards">
<insert id="insertBoard" parameterClass="com.sample.vo.Board">
insert into sample_boards
(board_no, board_title, board_writer, board_content, board_file_name)
values
(sample_boards_seq.nextval, #title#, #writer#, #content#, #fileName#)
</insert>
<select id="getBoards" parameterClass="map" resultClass="com.sample.vo.Board">
select
board_no as no,
board_title as title,
board_writer as writer,
board_read_count as readCount,
board_review_count as reviewCount,
board_content as content,
board_deleted as deleted,
board_created_date as createdDate,
board_updated_date as updatedDate
from (select
<dynamic>
<isEqual property="sort" compareValue="date">
row_number() over (order by board_no desc) row_numbers,
</isEqual>
<isEqual property="sort" compareValue="title">
row_number() over (order by board_title asc) row_numbers,
</isEqual>
<isEqual property="sort" compareValue="read">
row_number() over (order by board_read_count desc) row_numbers,
</isEqual>
</dynamic>
board_no,
board_title,
board_writer,
board_read_count,
board_review_count,
board_content,
board_deleted,
board_created_date,
board_updated_date
from
sample_boards
where
board_deleted = 'N'
<dynamic>
<isNotNull property="opt">
<isEqual property="opt" compareValue="title">
and board_title like '%' || #keyword# || '%'
</isEqual>
<isEqual property="opt" compareValue="writer">
and board_writer like '%' || #keyword# || '%'
</isEqual>
<isEqual property="opt" compareValue="content">
and board_content like '%' || #keyword# || '%'
</isEqual>
</isNotNull>
</dynamic>
)
where
row_numbers between #begin# and #end#
</select>
<select id="getBoardByNo" parameterClass="int" resultClass="com.sample.vo.Board">
select
board_no as no,
board_title as title,
board_writer as writer,
board_read_count as readCount,
board_review_count as reviewCount,
board_content as content,
board_deleted as deleted,
board_created_date as createdDate,
board_updated_date as updatedDate,
board_file_name as fileName
from
sample_boards
where
board_no = #value#
</select>
<select id="getTotalRows" parameterClass="map" resultClass="int">
select
count(*)
from
sample_boards
where
board_deleted = 'N'
<dynamic>
<isNotNull property="opt">
<isEqual property="opt" compareValue="title">
and board_title like '%' || #keyword# || '%'
</isEqual>
<isEqual property="opt" compareValue="writer">
and board_writer like '%' || #keyword# || '%'
</isEqual>
<isEqual property="opt" compareValue="content">
and board_content like '%' || #keyword# || '%'
</isEqual>
</isNotNull>
</dynamic>
</select>
<update id="updateBoard" parameterClass="com.sample.vo.Board">
update
sample_boards
set
board_title = #title#,
board_writer = #writer#,
board_read_count = #readCount#,
board_review_count = #reviewCount#,
board_content = #content#,
board_deleted = #deleted#,
board_file_name = #fileName#,
board_updated_date = sysdate
where
board_no = #no#
</update>
</sqlMap>
- BoardDao
package com.sample.dao;
import java.util.List;
import java.util.Map;
import com.sample.util.SqlMapper;
import com.sample.vo.Board;
public class BoardDao {
public void insertBoard(Board board) {
SqlMapper.insert("boards.insertBoard", board);
}
@SuppressWarnings("unchecked")
public List<Board> getBoards(Map<String, Object> param) {
return (List<Board>)SqlMapper.selectList("boards.getBoards", param);
}
public int getTotalRows(Map<String, Object> param) {
return (Integer) SqlMapper.selectOne("boards.getTotalRows", param);
}
public Board getBoardByNo(int boardNo) {
return (Board) SqlMapper.selectOne("boards.getBoardByNo", boardNo);
}
public void updateBoard(Board board) {
SqlMapper.update("boards.updateBoard", board);
}
}
'수업내용 > Javascript & jQuery' 카테고리의 다른 글
| [2022.11.30.수] jQuery 이벤트 (0) | 2022.11.30 |
|---|---|
| [2022.11.29.화] jQuery 선택자 (0) | 2022.11.29 |
| [2022.11.25.금] 자바스크립트3 - 이벤트 (0) | 2022.11.25 |
| [2022.11.24.목] 자바스크립트3 - 값 조회, 변경 (0) | 2022.11.24 |
| [2022.11.23.수] 자바스크립트2 (0) | 2022.11.23 |