일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- Android
- 맥
- spring
- jsp
- 반복문
- 객체지향
- 이클립스
- ddit
- Java
- Error
- Mac
- FastAPI
- 생활코딩
- 자바
- JDBC
- 배열
- 컬렉션프레임워크
- 단축키
- 대덕인재개발원
- crud
- nodejs
- pyqt
- ibatis
- API
- 자바문제
- html
- Homebrew
- Oracle
- python
- servlet
- Today
- Total
romworld
Spring 19 - EMP 테이블 (직원) 등록, 상세보기 , 수정,삭제,목록, 검색Toast, Merge_Into 본문
EMP(직원) 테이블 컬럼 수정
- 관리번호(매니저)
<aside.jsp>
- 고객관리 밑에 직원관리 카데고리를 만들어준다.
<!-- 직원관리 -->
<li class="nav-item">
<a class="nav-link collapsed" href="#" data-toggle="collapse" data-target="#collapseEmp"
aria-expanded="true" aria-controls="collapseEmp">
<i class="fas fa-fw fa-check"></i>
<span>직원관리</span>
</a>
<div id="collapseEmp" class="collapse" aria-labelledby="headingUtilities"
data-parent="#accordionSidebar">
<div class="bg-white py-2 collapse-inner rounded">
<h6 class="collapse-header">직원정보관리:</h6>
<a class="collapse-item" href="/emp/create">직원등록</a>
<a class="collapse-item" href="/emp/list">직원목록</a>
</div>
</div>
</li>
<EmpVO.java>
- private String empMjNum;
- emppay는 @NotNull
package kr.or.ddit.vo;
import java.util.List;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.NotBlank;
import lombok.Data;
//직원
@Data
public class EmpVO {
//직원 번호
@NotBlank
private String empNum;
//주소
private String empAddr;
//연락처
@NotBlank
private String empPne;
//직원 명
@NotBlank
private String empNm;
//급여
@NotNull
private int empPay;
//매니저
private String empMjNum;
//직원(EMP) : 서비스(SER) = 1 : N
private List<SerVO> serVOList;
}
<EmpController.java>
package kr.or.ddit.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import kr.or.ddit.vo.EmpVO;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Controller
@RequestMapping("/emp")
public class EmpController {
// 요청 URI : /emp/create
// 요청방식 : get
@GetMapping("/create")
public String create(@ModelAttribute("empVO") EmpVO empVO) {
//forwarding
return "emp/create";
}
}
<create.jsp>
부트스트랩 적용해서 create 꾸며주자
https://getbootstrap.com/docs/5.3/forms/layout/
Layout
Give your forms some structure—from inline to horizontal to custom grid implementations—with our form layout options.
getbootstrap.com
<form class="row g-3">
<div class="col-md-6">
<label for="inputEmail4" class="form-label">Email</label>
<input type="email" class="form-control" id="inputEmail4">
</div>
<div class="col-md-6">
<label for="inputPassword4" class="form-label">Password</label>
<input type="password" class="form-control" id="inputPassword4">
</div>
<div class="col-12">
<label for="inputAddress" class="form-label">Address</label>
<input type="text" class="form-control" id="inputAddress" placeholder="1234 Main St">
</div>
<div class="col-12">
<label for="inputAddress2" class="form-label">Address 2</label>
<input type="text" class="form-control" id="inputAddress2" placeholder="Apartment, studio, or floor">
</div>
<div class="col-md-6">
<label for="inputCity" class="form-label">City</label>
<input type="text" class="form-control" id="inputCity">
</div>
<div class="col-md-4">
<label for="inputState" class="form-label">State</label>
<select id="inputState" class="form-select">
<option selected>Choose...</option>
<option>...</option>
</select>
</div>
<div class="col-md-2">
<label for="inputZip" class="form-label">Zip</label>
<input type="text" class="form-control" id="inputZip">
</div>
<div class="col-12">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="gridCheck">
<label class="form-check-label" for="gridCheck">
Check me out
</label>
</div>
</div>
<div class="col-12">
<button type="submit" class="btn btn-primary">Sign in</button>
</div>
</form>
<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<link rel="stylesheet" href="/resources/css/bootstrap.min.css" />
<script src="https://ssl.daumcdn.net/dmaps/map_js_init/postcode.v2.js"></script>
<script type="text/javascript" src="/resources/js/jquery-3.6.0.js"></script>
<script type="text/javascript">
$(function(){
//다음 우편번호 검색
$("#btnPostno").on("click",function(){
new daum.Postcode({
//다음 창에서 검색이 완료되면 콜백함수에 의해 결과 데이터가 data 객체로 들어옴
oncomplete:function(data){
//우편번호
$("#zipCode").val(data.zonecode);
$("#address").val(data.address);
$("#detAddress").val(data.buildingName);
}
}).open();
});
});
</script>
<form:form modelAttribute="empVO" action="/emp/createPost" method="post"
class="row g-3">
<!-- 직원번호 시작 -->
<div class="col-md-6" style="clear:both;">
<label for="empNum" class="form-label">직원번호</label>
<input type="text" name="empNum" class="form-control" id="empNum"
placeholder="직원번호를 입력해주세요" />
</div>
<!-- 직원번호 끝 -->
<!-- 주소 시작 -->
<div class="col-md-2">
<label for="zipCode" class="form-label">우편번호</label>
<input type="text" name="zipCode" class="form-control" id="zipCode"
placeholder="우편번호를 검색해주세요" />
<button type="button" class="btn btn-primary" id="btnPostno">검색</button>
</div>
<div class="col-12">
<label for="address" class="form-label">주소</label>
<input type="text" name="address" class="form-control" id="address"
placeholder="주소를 검색해주세요">
</div>
<div class="col-12">
<label for="detAddress" class="form-label">상세주소</label>
<input type="text" name="detAddress" class="form-control" id="detAddress"
placeholder="상세주소를 입력해주세요">
</div>
<!-- 주소 끝 -->
<!-- 연락처 시작 -->
<div class="col-md-6">
<label for="empPne" class="form-label">연락처</label>
<input type="text" name="empPne" class="form-control" id="empPne"
placeholder="연락처를 입력해주세요" />
</div>
<!-- 연락처 끝 -->
<!-- 직원명 시작 -->
<div class="col-md-6">
<label for="empNm" class="form-label">직원명</label>
<input type="text" name="empNm" class="form-control" id="empNm"
placeholder="직원명을 입력해주세요" />
</div>
<!-- 직원명 끝 -->
<!-- 급여 시작 -->
<div class="col-md-6">
<label for="empPay" class="form-label">급여</label>
<input type="number" name="empPay" class="form-control" id="empPay"
placeholder="급여를 입력해주세요" />
</div>
<!-- 급여 끝 -->
<div class="col-12">
<button type="submit" class="btn btn-primary">Sign in</button>
</div>
</form:form>
직원번호 자동생성, 등록
쿼리문
SELECT NVL(SUBSTR(MAX(EMP_NUM),1,3),'EMP')
|| TRIM(TO_CHAR(NVL(SUBSTR(MAX(EMP_NUM),4),0) + 1,'000'))
FROM EMP;
<EmpMapper.java>
package kr.or.ddit.mapper;
import kr.or.ddit.vo.EmpVO;
public interface EmpMapper {
// 다음 직원번호를 가져옴
public String getEmpNum();
}
<emp.SQL.xml>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace : xml 파일이 여러개일 수 있으므로
이를 구별하기 위한 식별 용도로 사용 -->
<mapper namespace="kr.or.ddit.mapper.EmpMapper">
<!-- 직원테이블(EMP)의 기본키 데이터 생성 -->
<select id="getEmpNum" resultType="String">
SELECT NVL(SUBSTR(MAX(EMP_NUM),1,3),'EMP')
|| TRIM(TO_CHAR(NVL(SUBSTR(MAX(EMP_NUM),4),0)+1,'000'))
FROM EMP
</select>
</mapper>
<EmpService.java>
package kr.or.ddit.service;
import kr.or.ddit.vo.EmpVO;
public interface EmpService {
// 직원테이블(EMP) 직원번호 자동생성
public String getEmpNum();
}
<EmpServiceImple.java>
package kr.or.ddit.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import kr.or.ddit.mapper.EmpMapper;
import kr.or.ddit.service.EmpService;
import kr.or.ddit.vo.EmpVO;
@Service
public class EmpServiceImpl implements EmpService {
@Autowired
EmpMapper empMapper;
// 직원테이블(EMP)의 기본키 데이터 생성
@Override
public String getEmpNum() {
return this.empMapper.getEmpNum();
}
}
<EmpController.java>
package kr.or.ddit.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import kr.or.ddit.service.EmpService;
import kr.or.ddit.vo.EmpVO;
@RequestMapping("/emp")
@Controller
public class EmpController {
@Autowired
EmpService empService;
//요청URI : /emp/create
//요청방식 : get
@GetMapping("/create")
public String create(@ModelAttribute("empVO") EmpVO empVO
, Model model) {
//다음 직원번호를 가져옴
//서비스의 메서드 호출
String empNum = this.empService.getEmpNum();
//1. <form:form modelAttribute="empVO"
empVO.setEmpNum(empNum);
//2. ${empNum} 를 사용하는 경우
model.addAttribute("empNum", empNum);
//forwarding
return "emp/create";
}
}
<create.jsp>
- ajax 사용해서 신규 직원번호 가져와보기
<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<link rel="stylesheet" href="/resources/css/bootstrap.min.css" />
<script src="https://ssl.daumcdn.net/dmaps/map_js_init/postcode.v2.js"></script>
<script type="text/javascript" src="/resources/js/jquery-3.6.0.js"></script>
<script type="text/javascript">
$(function(){
//다음 우편번호 검색
$("#btnPostno").on("click",function(){
new daum.Postcode({
//다음 창에서 검색이 완료되면 콜백함수에 의해 결과 데이터가 data 객체로 들어옴
oncomplete:function(data){
//우편번호
$("#zipCode").val(data.zonecode);
$("#address").val(data.address);
$("#detAddress").val(data.buildingName);
}
}).open();
});
// 직원번호 자동등록
// processType : false는 파일업로드 시 사용(let formData = new formData())
// contentType : "application/json;charset:utf-8"(보내는 타입)
// data : JSON.stringify(data);
// type : "post"
// success : function(){}
$.ajax({
url : "/emp/getEmpNum",
type : "post",
success: function(result){
console.log("result : " + result);
$("#empNumAjax").val(result);
}
});
});
</script>
<form:form modelAttribute="empVO" action="/emp/createPost" method="post"
class="row g-3">
<!-- 직원번호 시작 -->
<div class="col-md-6" style="clear:both;">
<label for="empNum" class="form-label">직원번호</label>
<input type="text" name="empNum" class="form-control" id="empNum"
value="${empNum}" placeholder="직원번호를 입력해주세요" />
<form:input path="empNum" class="form-control" placeholder="직원번호를 입력해주세요" />
<input type="text" name="empNum" class="form-control" id="empNumAjax"
value="" placeholder="직원번호를 입력해주세요" />
</div>
<!-- 직원번호 끝 -->
<!-- 주소 시작 -->
<div class="col-md-2">
<label for="zipCode" class="form-label">우편번호</label>
<input type="text" name="zipCode" class="form-control" id="zipCode"
placeholder="우편번호를 검색해주세요" />
<button type="button" class="btn btn-primary" id="btnPostno">검색</button>
</div>
<div class="col-12">
<label for="address" class="form-label">주소</label>
<input type="text" name="address" class="form-control" id="address"
placeholder="주소를 검색해주세요">
</div>
<div class="col-12">
<label for="detAddress" class="form-label">상세주소</label>
<input type="text" name="detAddress" class="form-control" id="detAddress"
placeholder="상세주소를 입력해주세요">
</div>
<!-- 주소 끝 -->
<!-- 연락처 시작 -->
<div class="col-md-6">
<label for="empPne" class="form-label">연락처</label>
<input type="text" name="empPne" class="form-control" id="empPne"
placeholder="연락처를 입력해주세요" />
</div>
<!-- 연락처 끝 -->
<!-- 직원명 시작 -->
<div class="col-md-6">
<label for="empNm" class="form-label">직원명</label>
<input type="text" name="empNm" class="form-control" id="empNm"
placeholder="직원명을 입력해주세요" />
</div>
<!-- 직원명 끝 -->
<!-- 급여 시작 -->
<div class="col-md-6">
<label for="empPay" class="form-label">급여</label>
<input type="number" name="empPay" class="form-control" id="empPay"
placeholder="급여를 입력해주세요" />
</div>
<!-- 급여 끝 -->
<div class="col-12">
<button type="submit" class="btn btn-primary">Sign in</button>
</div>
</form:form>
<EmpController.java>
//신규 직원번호 가져오기
//요청URI : /emp/getEmpNum
//요청방법 : post
//ResponseBody : JSON데이터로 리턴
@ResponseBody
@PostMapping("/getEmpNum")
public String getEmpNum() {
String empNum = this.empService.getEmpNum();
return empNum;
}
package kr.or.ddit.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import kr.or.ddit.service.EmpService;
import kr.or.ddit.vo.EmpVO;
@RequestMapping("/emp")
@Controller
public class EmpController {
@Autowired
EmpService empService;
//요청URI : /emp/create
//요청방식 : get
@GetMapping("/create")
public String create(@ModelAttribute("empVO") EmpVO empVO
, Model model) {
//다음 직원번호를 가져옴
//서비스의 메서드 호출
String empNum = this.empService.getEmpNum();
//1. <form:form modelAttribute="empVO"
empVO.setEmpNum(empNum);
//2. ${empNum} 를 사용하는 경우 ( value="${empNum}")
model.addAttribute("empNum", empNum);
//forwarding
return "emp/create";
}
//신규 직원번호 가져오기
//요청URI : /emp/getEmpNum
//요청방법 : post
//ResponseBody : JSON데이터로 리턴
@ResponseBody
@PostMapping("/getEmpNum")
public String getEmpNum() {
String empNum = this.empService.getEmpNum();
return empNum;
}
}
매니저 등록
- 모달창 사용하기
https://getbootstrap.kr/docs/5.2/components/modal/
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
<create.jsp>
<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<link rel="stylesheet" href="/resources/css/bootstrap.min.css" />
<script src="https://ssl.daumcdn.net/dmaps/map_js_init/postcode.v2.js"></script>
<script type="text/javascript" src="/resources/js/jquery-3.6.0.js"></script>
<script type="text/javascript">
$(function(){
//다음 우편번호 검색
$("#btnPostno").on("click",function(){
new daum.Postcode({
//다음 창에서 검색이 완료되면 콜백함수에 의해 결과 데이터가 data 객체로 들어옴
oncomplete:function(data){
//우편번호
$("#zipCode").val(data.zonecode);
$("#address").val(data.address);
$("#detAddress").val(data.buildingName);
}
}).open();
});
// 직원번호 자동등록
// processType:false는 파일업로드 시 사용(let formData = new formData())
// contentType:"application/json;charset:utf-8"(보내는 타입)
// data:JSON.stringify(data);
// type:"post"
// success:function(){}
$.ajax({
url:"/emp/getEmpNum",
type:"post",
success:function(result){
console.log("result : " + result);
$("#empNumAjax").val(result);
}
});
});
</script>
<form:form modelAttribute="empVO" action="/emp/createPost" method="post"
class="row g-3">
<!-- 직원번호 시작 -->
<div class="col-md-6" style="clear:both;">
<label for="empNum" class="form-label">직원번호</label>
<!-- <input type="text" name="empNum" class="form-control" id="empNum" -->
<%-- value="${empNum}" placeholder="직원번호를 입력해주세요" /> --%>
<%-- <form:input path="empNum" class="form-control" placeholder="직원번호를 입력해주세요" /> --%>
<input type="text" name="empNum" class="form-control" id="empNumAjax"
value="" placeholder="직원번호를 입력해주세요" />
</div>
<!-- 직원번호 끝 -->
<!-- 주소 시작 -->
<div class="col-md-2">
<label for="zipCode" class="form-label">우편번호</label>
<input type="text" name="zipCode" class="form-control" id="zipCode"
placeholder="우편번호를 검색해주세요" />
<button type="button" class="btn btn-primary" id="btnPostno">검색</button>
</div>
<div class="col-12">
<label for="address" class="form-label">주소</label>
<input type="text" name="address" class="form-control" id="address"
placeholder="주소를 검색해주세요">
</div>
<div class="col-12">
<label for="detAddress" class="form-label">상세주소</label>
<input type="text" name="detAddress" class="form-control" id="detAddress"
placeholder="상세주소를 입력해주세요">
</div>
<!-- 주소 끝 -->
<!-- 연락처 시작 -->
<div class="col-md-6">
<label for="empPne" class="form-label">연락처</label>
<input type="text" name="empPne" class="form-control" id="empPne"
placeholder="연락처를 입력해주세요" />
</div>
<!-- 연락처 끝 -->
<!-- 직원명 시작 -->
<div class="col-md-6">
<label for="empNm" class="form-label">직원명</label>
<input type="text" name="empNm" class="form-control" id="empNm"
placeholder="직원명을 입력해주세요" />
</div>
<!-- 직원명 끝 -->
<!-- 급여 시작 -->
<div class="col-md-6">
<label for="empPay" class="form-label">급여</label>
<input type="number" name="empPay" class="form-control" id="empPay"
placeholder="급여를 입력해주세요" />
</div>
<!-- 급여 끝 -->
<!-- 매니저 등록 시작 -->
<div class="col-md-6">
<label for="empMjNm" class="form-label">매니저명</label>
<input type="text" name="empMjNum" class="form-control" id="empMjNum" />
<input type="text" class="form-control" id="empMjNm"
placeholder="직원명을 입력해주세요" />
<button type="button" class="btn btn-primary" id="btnEmpMjNum"
data-toggle="modal" data-target="#exampleModal"
>검색</button>
</div>
<!-- 매니저 등록 끝 -->
<div class="col-12">
<button type="submit" class="btn btn-primary">Sign in</button>
</div>
</form:form>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1>
<button type="button" class="btn-close" data-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
이제 모달창에 직원이 나오게
등록을 해보자 !
<EmpController.java>
- createPost 매서드 생성
- @valid 를 쓰면 @에 대한 유효성 검사를 해주고 errors라는 태그를 통해 에러를 확인할 수 있다.
- errors를 쓰는경우 forwarding을 써준다.
// 신규 직원 등록하기
/*
요청URI : /emp/createPost
요청파라미터 : {empNum=EMP001,zipCode=12345,address=대전...,empMjNum=}
요청방식 : post
empMjNum=null => 일반직원
*/
@PostMapping("/createPost")
public String createPost(@Valid @ModelAttribute EmpVO empVO,
Errors errors) {
log.info("empVO :" + empVO);
if(errors.hasErrors()) {
//forwarding
return "emp/create";
}
//forwarding
return "emp/detail";
}
<emp_SQL.xml>
1. 첫번째 방식
<!-- 신규 직원 등록 -->
<insert id="createPost" parameterType="empVO">
<selectKey resultType="String" order="BEFORE" keyProperty="empNum">
SELECT NVL(SUBSTR(MAX(EMP_NUM),1,3),'EMP')
|| TRIM(TO_CHAR(NVL(SUBSTR(MAX(EMP_NUM),4),0)+1,'000'))
FROM EMP
</selectKey>
INSERT INTO EMP(EMP_NUM, EMP_ADDR, EMP_PNE, EMP_NM, EMP_PAY
, EMP_MJ_NUM)
VALUES(#{empNum},#{empAddr},#{empPne},#{empNm},#{empPay},#{empMjNum})
</insert>
2. 두번째 방식(이걸로 선택함)
<!-- 신규 직원 등록 -->
<insert id="createPost" parameterType="empVO">
<selectKey resultType="String" order="BEFORE" keyProperty="empNum">
SELECT NVL(SUBSTR(MAX(EMP_NUM),1,3),'EMP')
|| TRIM(TO_CHAR(NVL(SUBSTR(MAX(EMP_NUM),4),0) + 1,'000'))
FROM EMP
</selectKey>
INSERT INTO EMP(EMP_NUM, EMP_ADDR, EMP_PNE, EMP_NM, EMP_PAY
<if test="empMjNum!=null and empMjNum!=''">
, EMP_MJ_NUM
</if>
)
VALUES(#{empNum},#{empAddr}, #{empPne}, #{empNm}, #{empPay}
<if test="empMjNum!=null and empMjNum!=''">
, #{empMjNum}
</if>
)
</insert>
<EmpMapper.java>
// 신규 직원 등록
public int createPost(EmpVO empVO);
<EmpService.java>
// 신규 직원 등록
public int createPost(EmpVO empVO);
<EmpServiceImpl.java>
// 신규 직원 등록
@Override
public int createPost(EmpVO empVO) {
return this.empMapper.createPost(empVO);
}
<EmpController.java>
- 우편번호 + 주소 + 상세주소
// 신규 직원 등록하기
/*
요청URI : /emp/createPost
요청파라미터 : {empNum=EMP001,zipCode=12345,address=대전...,empMjNum=}
요청방식 : post
empMjNum=null => 일반직원
String zipCode, String address, String detAddress => 멤버변수에 없으므로 파라미터로 직접 받음
*/
@PostMapping("/createPost")
public String createPost(@Valid @ModelAttribute EmpVO empVO,
String zipCode, String address, String detAddress,
Errors errors) {
log.info("empVO :" + empVO);
if(errors.hasErrors()) {
//forwarding
return "emp/create";
}
// 우편번호 + 주소 + 상세주소 => empVO의 enpAddr 멤버변수에 setting 하기
String empAddr = zipCode + " " + address + " " + detAddress;
empVO.setEmpAddr(empAddr);
int result = this.empService.createPost(empVO);
return "redirect:/emp/detail?empNum="+empVO.getEmpNum();
}
<create.jsp>
- form:error를 넣어준다.
<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<link rel="stylesheet" href="/resources/css/bootstrap.min.css" />
<script src="https://ssl.daumcdn.net/dmaps/map_js_init/postcode.v2.js"></script>
<script type="text/javascript" src="/resources/js/jquery-3.6.0.js"></script>
<script type="text/javascript">
$(function(){
//다음 우편번호 검색
$("#btnPostno").on("click",function(){
new daum.Postcode({
//다음 창에서 검색이 완료되면 콜백함수에 의해 결과 데이터가 data 객체로 들어옴
oncomplete:function(data){
//우편번호
$("#zipCode").val(data.zonecode);
$("#address").val(data.address);
$("#detAddress").val(data.buildingName);
}
}).open();
});
// 직원번호 자동등록
// processType:false는 파일업로드 시 사용(let formData = new formData())
// contentType:"application/json;charset:utf-8"(보내는 타입)
// data:JSON.stringify(data);
// type:"post"
// success:function(){}
$.ajax({
url:"/emp/getEmpNum",
type:"post",
success:function(result){
console.log("result : " + result);
$("#empNumAjax").val(result);
}
});
});
</script>
<!-- 요청URI : /emp/createPost
요청파라미터 : {empNum=EMP001,zipCode=12345,address=대전...,empMjNum=}
요청방식 : post
-->
<form:form modelAttribute="empVO" action="/emp/createPost" method="post"
class="row g-3">
<!-- 직원번호 시작 -->
<div class="col-md-6" style="clear:both;">
<label for="empNum" class="form-label">직원번호</label>
<!-- <input type="text" name="empNum" class="form-control" id="empNum" -->
<%-- value="${empNum}" placeholder="직원번호를 입력해주세요" /> --%>
<%-- <form:input path="empNum" class="form-control" placeholder="직원번호를 입력해주세요" /> --%>
<input type="text" name="empNum" class="form-control" id="empNumAjax"
value="" placeholder="직원번호를 입력해주세요" />
</div>
<!-- 직원번호 끝 -->
<!-- 주소 시작 -->
<div class="col-md-2">
<label for="zipCode" class="form-label">우편번호</label>
<input type="text" name="zipCode" class="form-control" id="zipCode"
placeholder="우편번호를 검색해주세요" />
<button type="button" class="btn btn-primary" id="btnPostno">검색</button>
</div>
<div class="col-12">
<label for="address" class="form-label">주소</label>
<input type="text" name="address" class="form-control" id="address"
placeholder="주소를 검색해주세요">
</div>
<div class="col-12">
<label for="detAddress" class="form-label">상세주소</label>
<input type="text" name="detAddress" class="form-control" id="detAddress"
placeholder="상세주소를 입력해주세요">
</div>
<!-- 주소 끝 -->
<!-- 연락처 시작 -->
<div class="col-md-6">
<label for="empPne" class="form-label">연락처</label>
<input type="text" name="empPne" class="form-control" id="empPne"
placeholder="연락처를 입력해주세요" required />
<form:errors path="empPne" />
</div>
<!-- 연락처 끝 -->
<!-- 직원명 시작 -->
<div class="col-md-6">
<label for="empNm" class="form-label">직원명</label>
<input type="text" name="empNm" class="form-control" id="empNm"
placeholder="직원명을 입력해주세요" required />
<form:errors path="empNm" />
</div>
<!-- 직원명 끝 -->
<!-- 급여 시작 -->
<div class="col-md-6">
<label for="empPay" class="form-label">급여</label>
<input type="number" name="empPay" class="form-control" id="empPay"
placeholder="급여를 입력해주세요" required />
<form:errors path="empPay" />
</div>
<!-- 급여 끝 -->
<!-- 매니저 등록 시작 -->
<div class="col-md-6">
<label for="empMjNm" class="form-label">매니저명</label>
<input type="text" name="empMjNum" class="form-control" id="empMjNum" />
<input type="text" class="form-control" id="empMjNm"
placeholder="직원명을 입력해주세요" />
<button type="button" class="btn btn-primary" id="btnEmpMjNum"
data-toggle="modal" data-target="#exampleModal"
>검색</button>
</div>
<!-- 매니저 등록 끝 -->
<div class="col-12">
<button type="submit" class="btn btn-primary">등록</button>
</div>
</form:form>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1>
<button type="button" class="btn-close" data-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
모든 직원 정보 가져오기 (모달창 출력)
<emp_SQL.xml>
<!-- 모든 직원 정보 가져오기 -->
<select id="getEmpAll" resultType="empVO">
SELECT EMP_NUM, EMP_ADDR, EMP_PNE, EMP_NM, EMP_PAY, EMP_MJ_NUM
FROM EMP
ORDER BY EMP_NUM
</select>
<EmpMapper.java>
// 모든 직원 정보 가져오기
public List<EmpVO> getEmpAll();
<EmpService.java>
// 모든 직원 정보 가져오기
public List<EmpVO> getEmpAll();
<EmpServiceImpl.java>
// 모든 직원 정보 가져오기
@Override
public List<EmpVO> getEmpAll(){
return this.empMapper.getEmpAll();
}
<EmpController.java>
- 직원목록을 json으로 받아보자
/*
모든 직원 정보 가져오기
요청URI : /emp/getEmpAll
요청방식 : post
dataType : json
*/
@ResponseBody
@PostMapping("/getEmpAll")
public List<EmpVO> getEmpALl(){
// 모든 직원 정보 가져오기
List<EmpVO> empVOList = this.empService.getEmpAll();
log.info("empVOList : " + empVOList);
return empVOList;
}
- 부트스트랩 적용하기 (모달창 안에 목록)
- outer HTML 로 복사해서 가져오기
<create.jsp>
- 매니저 선택하기 위한 ajax 식 작성
우선 콘솔로 찍어보자
<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<link rel="stylesheet" href="/resources/css/bootstrap.min.css" />
<script src="https://ssl.daumcdn.net/dmaps/map_js_init/postcode.v2.js"></script>
<script type="text/javascript" src="/resources/js/jquery-3.6.0.js"></script>
<script type="text/javascript">
$(function(){
//다음 우편번호 검색
$("#btnPostno").on("click",function(){
new daum.Postcode({
//다음 창에서 검색이 완료되면 콜백함수에 의해 결과 데이터가 data 객체로 들어옴
oncomplete:function(data){
//우편번호
$("#zipCode").val(data.zonecode);
$("#address").val(data.address);
$("#detAddress").val(data.buildingName);
}
}).open();
});
// 직원번호 자동등록
// processType:false는 파일업로드 시 사용(let formData = new formData())
// contentType:"application/json;charset:utf-8"(보내는 타입)
// data:JSON.stringify(data);
// type:"post"
// success:function(){}
$.ajax({
url:"/emp/getEmpNum",
type:"post",
success:function(result){
console.log("result : " + result);
$("#empNumAjax").val(result);
}
});
// 매니저 선택하기
$("#btnEmpMjNum").on("click",function(){
$.ajax({
url:"/emp/getEmpAll",
type:"post",
success:function(result){
//result : List<EmpVO> empVOList
$.each(result, function(index, empVO){
console.log("empVO.empNum :" + empVO.empNum);
console.log("empVO.empNm :" + empVO.empNm);
});
}
});
});
});
</script>
<!-- 요청URI : /emp/createPost
요청파라미터 : {empNum=EMP001,zipCode=12345,address=대전...,empMjNum=}
요청방식 : post
-->
<form:form modelAttribute="empVO" action="/emp/createPost" method="post"
class="row g-3">
<!-- 직원번호 시작 -->
<div class="col-md-6" style="clear:both;">
<label for="empNum" class="form-label">직원번호</label>
<!-- <input type="text" name="empNum" class="form-control" id="empNum" -->
<%-- value="${empNum}" placeholder="직원번호를 입력해주세요" /> --%>
<%-- <form:input path="empNum" class="form-control" placeholder="직원번호를 입력해주세요" /> --%>
<input type="text" name="empNum" class="form-control" id="empNumAjax"
value="" placeholder="직원번호를 입력해주세요" />
</div>
<!-- 직원번호 끝 -->
<!-- 주소 시작 -->
<div class="col-md-2">
<label for="zipCode" class="form-label">우편번호</label>
<input type="text" name="zipCode" class="form-control" id="zipCode"
placeholder="우편번호를 검색해주세요" />
<button type="button" class="btn btn-primary" id="btnPostno">검색</button>
</div>
<div class="col-12">
<label for="address" class="form-label">주소</label>
<input type="text" name="address" class="form-control" id="address"
placeholder="주소를 검색해주세요">
</div>
<div class="col-12">
<label for="detAddress" class="form-label">상세주소</label>
<input type="text" name="detAddress" class="form-control" id="detAddress"
placeholder="상세주소를 입력해주세요">
</div>
<!-- 주소 끝 -->
<!-- 연락처 시작 -->
<div class="col-md-6">
<label for="empPne" class="form-label">연락처</label>
<input type="text" name="empPne" class="form-control" id="empPne"
placeholder="연락처를 입력해주세요" required />
<form:errors path="empPne" />
</div>
<!-- 연락처 끝 -->
<!-- 직원명 시작 -->
<div class="col-md-6">
<label for="empNm" class="form-label">직원명</label>
<input type="text" name="empNm" class="form-control" id="empNm"
placeholder="직원명을 입력해주세요" required />
<form:errors path="empNm" />
</div>
<!-- 직원명 끝 -->
<!-- 급여 시작 -->
<div class="col-md-6">
<label for="empPay" class="form-label">급여</label>
<input type="number" name="empPay" class="form-control" id="empPay"
placeholder="급여를 입력해주세요" required />
<form:errors path="empPay" />
</div>
<!-- 급여 끝 -->
<!-- 매니저 등록 시작 -->
<div class="col-md-6">
<label for="empMjNm" class="form-label">매니저명</label>
<input type="text" name="empMjNum" class="form-control" id="empMjNum" />
<input type="text" class="form-control" id="empMjNm"
placeholder="직원명을 입력해주세요" />
<button type="button" class="btn btn-primary" id="btnEmpMjNum"
data-toggle="modal" data-target="#exampleModal"
>검색</button>
</div>
<!-- 매니저 등록 끝 -->
<div class="col-12">
<button type="submit" class="btn btn-primary">등록</button>
</div>
</form:form>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1>
<button type="button" class="btn-close" data-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<!-- -------- 직원 목록 시작 ------------- -->
<div class="bd-example">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">직원번호</th>
<th scope="col">이름</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
</tr>
</tbody>
</table>
</div>
<!-- -------- 직원 목록 끝 ------------- -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
<create.jsp> 추가
// 매니저 선택하기
$("#btnEmpMjNum").on("click",function(){
$.ajax({
url:"/emp/getEmpAll",
type:"post",
success:function(result){
//result : List<EmpVO> empVOList
let str = "";
$.each(result, function(index, empVO){
console.log("empVO.empNum :" + empVO.empNum);
console.log("empVO.empNm :" + empVO.empNm);
str += "<tr><th scope='row'>"+(index+1)+"</th>";
str += "<td>"+empVO.empNum+"</td><td>"+empVO.empNm+"</td></tr>";
});
console.log("str :" + str);
//.html() : 새로고침 / .append() : 누적
$("#trAdd").html(str); // 초기화
//$("#trAdd").append(str);
}
});
});
동적 요소 이벤트 처리
<create.jsp> 추가
// 동적으로 생성된 요소의 이벤트 처리
// $(".trSelect").on("click",function(){})은 작동을 안할것임
$(document).on("click",".trSelect",function(){
//this : tr이 여러개인데 그 중 클릭한 바로 그 tr
//td들을 가져옴. 그 안에 데이터를 가져와보자
let resultStr = $(this).children().map(function(){
return $(this).text();}).get().join(",");
console.log("resultStr : " + resultStr);
});
<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<link rel="stylesheet" href="/resources/css/bootstrap.min.css" />
<script src="https://ssl.daumcdn.net/dmaps/map_js_init/postcode.v2.js"></script>
<script type="text/javascript" src="/resources/js/jquery-3.6.0.js"></script>
<script type="text/javascript">
$(function(){
//다음 우편번호 검색
$("#btnPostno").on("click",function(){
new daum.Postcode({
//다음 창에서 검색이 완료되면 콜백함수에 의해 결과 데이터가 data 객체로 들어옴
oncomplete:function(data){
//우편번호
$("#zipCode").val(data.zonecode);
$("#address").val(data.address);
$("#detAddress").val(data.buildingName);
}
}).open();
});
// 직원번호 자동등록
// processType:false는 파일업로드 시 사용(let formData = new formData())
// contentType:"application/json;charset:utf-8"(보내는 타입)
// data:JSON.stringify(data);
// type:"post"
// success:function(){}
$.ajax({
url:"/emp/getEmpNum",
type:"post",
success:function(result){
console.log("result : " + result);
$("#empNumAjax").val(result);
}
});
// 매니저 선택하기
$("#btnEmpMjNum").on("click",function(){
$.ajax({
url:"/emp/getEmpAll",
type:"post",
success:function(result){
//result : List<EmpVO> empVOList
let str = "";
$.each(result, function(index, empVO){
console.log("empVO.empNum :" + empVO.empNum);
console.log("empVO.empNm :" + empVO.empNm);
str += "<tr class='trSelect'><th scope='row'>"+(index+1)+"</th>";
str += "<td>"+empVO.empNum+"</td><td>"+empVO.empNm+"</td></tr>";
});
console.log("str :" + str);
//.html() : 새로고침 / .append() : 누적
$("#trAdd").html(str); // 초기화
//$("#trAdd").append(str);
}
});
});
// 동적으로 생성된 요소의 이벤트 처리
// $(".trSelect").on("click",function(){})은 작동을 안할것임
$(document).on("click",".trSelect",function(){
//this : tr이 여러개인데 그 중 클릭한 바로 그 tr
//td들을 가져옴. 그 안에 데이터를 가져와보자
let resultStr = $(this).children().map(function(){
return $(this).text();}).get().join(",");
console.log("resultStr : " + resultStr);
});
});
</script>
<!-- 요청URI : /emp/createPost
요청파라미터 : {empNum=EMP001,zipCode=12345,address=대전...,empMjNum=}
요청방식 : post
-->
<form:form modelAttribute="empVO" action="/emp/createPost" method="post"
class="row g-3">
<!-- 직원번호 시작 -->
<div class="col-md-6" style="clear:both;">
<label for="empNum" class="form-label">직원번호</label>
<!-- <input type="text" name="empNum" class="form-control" id="empNum" -->
<%-- value="${empNum}" placeholder="직원번호를 입력해주세요" /> --%>
<%-- <form:input path="empNum" class="form-control" placeholder="직원번호를 입력해주세요" /> --%>
<input type="text" name="empNum" class="form-control" id="empNumAjax"
value="" placeholder="직원번호를 입력해주세요" />
</div>
<!-- 직원번호 끝 -->
<!-- 주소 시작 -->
<div class="col-md-2">
<label for="zipCode" class="form-label">우편번호</label>
<input type="text" name="zipCode" class="form-control" id="zipCode"
placeholder="우편번호를 검색해주세요" />
<button type="button" class="btn btn-primary" id="btnPostno">검색</button>
</div>
<div class="col-12">
<label for="address" class="form-label">주소</label>
<input type="text" name="address" class="form-control" id="address"
placeholder="주소를 검색해주세요">
</div>
<div class="col-12">
<label for="detAddress" class="form-label">상세주소</label>
<input type="text" name="detAddress" class="form-control" id="detAddress"
placeholder="상세주소를 입력해주세요">
</div>
<!-- 주소 끝 -->
<!-- 연락처 시작 -->
<div class="col-md-6">
<label for="empPne" class="form-label">연락처</label>
<input type="text" name="empPne" class="form-control" id="empPne"
placeholder="연락처를 입력해주세요" required />
<form:errors path="empPne" />
</div>
<!-- 연락처 끝 -->
<!-- 직원명 시작 -->
<div class="col-md-6">
<label for="empNm" class="form-label">직원명</label>
<input type="text" name="empNm" class="form-control" id="empNm"
placeholder="직원명을 입력해주세요" required />
<form:errors path="empNm" />
</div>
<!-- 직원명 끝 -->
<!-- 급여 시작 -->
<div class="col-md-6">
<label for="empPay" class="form-label">급여</label>
<input type="number" name="empPay" class="form-control" id="empPay"
placeholder="급여를 입력해주세요" required />
<form:errors path="empPay" />
</div>
<!-- 급여 끝 -->
<!-- 매니저 등록 시작 -->
<div class="col-md-6">
<label for="empMjNm" class="form-label">매니저명</label>
<input type="text" name="empMjNum" class="form-control" id="empMjNum" />
<input type="text" class="form-control" id="empMjNm"
placeholder="직원명을 입력해주세요" />
<button type="button" class="btn btn-primary" id="btnEmpMjNum"
data-toggle="modal" data-target="#exampleModal"
>검색</button>
</div>
<!-- 매니저 등록 끝 -->
<div class="col-12">
<button type="submit" class="btn btn-primary">등록</button>
</div>
</form:form>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1>
<button type="button" class="btn-close" data-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<!-- -------- 직원 목록 시작 ------------- -->
<div class="bd-example">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">직원번호</th>
<th scope="col">이름</th>
</tr>
</thead>
<tbody id="trAdd">
<tr>
<th scope="row">1</th>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</div>
<!-- -------- 직원 목록 끝 ------------- -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
// 동적으로 생성된 요소의 이벤트 처리
// $(".trSelect").on("click",function(){})은 작동을 안할것임
$(document).on("click",".trSelect",function(){
//this : tr이 여러개인데 그 중 클릭한 바로 그 tr
//td들을 가져옴. 그 안에 데이터를 가져와보자
let resultStr = $(this).children().map(function(){
return $(this).text();}).get().join(",");
console.log("resultStr : " + resultStr);
//resultStr : 4, EMP004, 훈이 => split(",")을 사용해서 배열로 만들고
// [1]는 매니저번호(empMjNum)로 입력, [2]는 매 니저명(empMjNm)으로 입력
// arr[0] : 4 / arr[1] : EMP004 /arr[2] : 훈이
let arr = resultStr.split(",");
$("#empMjNum").val(arr[1]);
$("#empMjNm").val(arr[2]);
});
그 다음
- 직원번호, 우편번호, 주소, 매니저명 readonly 속성 추가
- 매니저명은 input type="hidden"을 준다.
<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<link rel="stylesheet" href="/resources/css/bootstrap.min.css" />
<script src="https://ssl.daumcdn.net/dmaps/map_js_init/postcode.v2.js"></script>
<script type="text/javascript" src="/resources/js/jquery-3.6.0.js"></script>
<script type="text/javascript">
$(function(){
//다음 우편번호 검색
$("#btnPostno").on("click",function(){
new daum.Postcode({
//다음 창에서 검색이 완료되면 콜백함수에 의해 결과 데이터가 data 객체로 들어옴
oncomplete:function(data){
//우편번호
$("#zipCode").val(data.zonecode);
$("#address").val(data.address);
$("#detAddress").val(data.buildingName);
}
}).open();
});
// 직원번호 자동등록
// processType:false는 파일업로드 시 사용(let formData = new formData())
// contentType:"application/json;charset:utf-8"(보내는 타입)
// data:JSON.stringify(data);
// type:"post"
// success:function(){}
$.ajax({
url:"/emp/getEmpNum",
type:"post",
success:function(result){
console.log("result : " + result);
$("#empNumAjax").val(result);
}
});
// 매니저 선택하기
$("#btnEmpMjNum").on("click",function(){
$.ajax({
url:"/emp/getEmpAll",
type:"post",
success:function(result){
//result : List<EmpVO> empVOList
let str = "";
$.each(result, function(index, empVO){
console.log("empVO.empNum :" + empVO.empNum);
console.log("empVO.empNm :" + empVO.empNm);
str += "<tr class='trSelect'><th scope='row'>"+(index+1)+"</th>";
str += "<td>"+empVO.empNum+"</td><td>"+empVO.empNm+"</td></tr>";
});
console.log("str :" + str);
//.html() : 새로고침 / .append() : 누적
$("#trAdd").html(str); // 초기화
//$("#trAdd").append(str);
}
});
});
// 동적으로 생성된 요소의 이벤트 처리
// $(".trSelect").on("click",function(){})은 작동을 안할것임
$(document).on("click",".trSelect",function(){
//this : tr이 여러개인데 그 중 클릭한 바로 그 tr
//td들을 가져옴. 그 안에 데이터를 가져와보자
let resultStr = $(this).children().map(function(){
return $(this).text();}).get().join(",");
console.log("resultStr : " + resultStr);
//resultStr : 4, EMP004, 훈이 => split(",")을 사용해서 배열로 만들고
// [1]는 매니저번호(empMjNum)로 입력, [2]는 매 니저명(empMjNm)으로 입력
// arr[0] : 4 / arr[1] : EMP004 /arr[2] : 훈이
let arr = resultStr.split(",");
$("#empMjNum").val(arr[1]);
$("#empMjNm").val(arr[2]);
});
});
</script>
<!-- 요청URI : /emp/createPost
요청파라미터 : {empNum=EMP001,zipCode=12345,address=대전...,empMjNum=}
요청방식 : post
-->
<form:form modelAttribute="empVO" action="/emp/createPost" method="post"
class="row g-3">
<!-- 직원번호 시작 -->
<div class="col-md-6" style="clear:both;">
<label for="empNum" class="form-label">직원번호</label>
<!-- <input type="text" name="empNum" class="form-control" id="empNum" -->
<%-- value="${empNum}" placeholder="직원번호를 입력해주세요" /> --%>
<%-- <form:input path="empNum" class="form-control" placeholder="직원번호를 입력해주세요" /> --%>
<input type="text" name="empNum" class="form-control" id="empNumAjax"
value="" placeholder="직원번호를 입력해주세요" readonly/>
</div>
<!-- 직원번호 끝 -->
<!-- 주소 시작 -->
<div class="col-md-2">
<label for="zipCode" class="form-label">우편번호</label>
<input type="text" name="zipCode" class="form-control" id="zipCode"
placeholder="우편번호를 검색해주세요" readonly/>
<button type="button" class="btn btn-primary" id="btnPostno">검색</button>
</div>
<div class="col-12">
<label for="address" class="form-label">주소</label>
<input type="text" name="address" class="form-control" id="address"
placeholder="주소를 검색해주세요" readonly>
</div>
<div class="col-12">
<label for="detAddress" class="form-label">상세주소</label>
<input type="text" name="detAddress" class="form-control" id="detAddress"
placeholder="상세주소를 입력해주세요">
</div>
<!-- 주소 끝 -->
<!-- 연락처 시작 -->
<div class="col-md-6">
<label for="empPne" class="form-label">연락처</label>
<input type="text" name="empPne" class="form-control" id="empPne"
placeholder="연락처를 입력해주세요" required />
<form:errors path="empPne" />
</div>
<!-- 연락처 끝 -->
<!-- 직원명 시작 -->
<div class="col-md-6">
<label for="empNm" class="form-label">직원명</label>
<input type="text" name="empNm" class="form-control" id="empNm"
placeholder="직원명을 입력해주세요" required />
<form:errors path="empNm" />
</div>
<!-- 직원명 끝 -->
<!-- 급여 시작 -->
<div class="col-md-6">
<label for="empPay" class="form-label">급여</label>
<input type="number" name="empPay" class="form-control" id="empPay"
placeholder="급여를 입력해주세요" required />
<form:errors path="empPay" />
</div>
<!-- 급여 끝 -->
<!-- 매니저 등록 시작 -->
<div class="col-md-6">
<label for="empMjNm" class="form-label">매니저명</label>
<input type="hidden" name="empMjNum" class="form-control" id="empMjNum" />
<input type="text" class="form-control" id="empMjNm"
placeholder="직원명을 입력해주세요" readonly />
<button type="button" class="btn btn-primary" id="btnEmpMjNum"
data-toggle="modal" data-target="#exampleModal"
>검색</button>
</div>
<!-- 매니저 등록 끝 -->
<div class="col-12">
<button type="submit" class="btn btn-primary">등록</button>
</div>
</form:form>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1>
<button type="button" class="btn-close" data-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<!-- -------- 직원 목록 시작 ------------- -->
<div class="bd-example">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">직원번호</th>
<th scope="col">이름</th>
</tr>
</thead>
<tbody id="trAdd">
<tr>
<th scope="row">1</th>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</div>
<!-- -------- 직원 목록 끝 ------------- -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
detail 만들기
<EmpController.java>
//직원 상세보기
/*
요청URI : /emp/detail?empNum=EMP006
요청파라미터 : empNum=EMP007
요청방식 :get
*/
@GetMapping("/detail")
public String detail(@RequestParam String empNum
, @ModelAttribute EmpVO empVO) {
log.info("empNum : " + empNum);
log.info("empVO : " + empVO);
// 상세화면은 등록화면과 동일 + empVO데이터로 채우면 됨
// emp 폴더의 detail.jsp를 forwarding
return "emp/detail";
}
직원 상세 보기 <쿼리문>
SELECT A.EMP_NUM, A.EMP_ADDR, A.EMP_PNE, A.EMP_NM, A.EMP_PAY, A.EMP_MJ_NUM
FROM EMP A
WHERE A.EMP_NUM = 'EMP006'
OR A.EMP_NUM = (
SELECT B.EMP_MJ_NUM FROM EMP B WHERE B.EMP_NUM = 'EMP006'
);
<emp_SQL.xml>
<!-- 직원 상세 보기 (관리자가 있으면 관리자 정보도 포함)
empVO[empNum:EMP006, empAddr:null, empPne:null....]
==> 들어올 땐 empNum만 들어오고 나갈땐 리스트가 채워져서 나간다.
-->
<select id="detail" parameterType="empVO" resultType="empVO">
SELECT A.EMP_NUM, A.EMP_ADDR, A.EMP_PNE, A.EMP_NM, A.EMP_PAY, A.EMP_MJ_NUM
FROM EMP A
WHERE A.EMP_NUM = #{empNum}
OR A.EMP_NUM = (
SELECT B.EMP_MJ_NUM FROM EMP B WHERE B.EMP_NUM = #{empNum}
)
</select>
<EmpMapper.java>
// 직원 상세 보기 (관리자가 있으면 관리자 정보도 포함)
public List<EmpVO> detail(EmpVO empVO);
<EmpServiceImpl.java>
// 직원 상세 보기 (관리자가 있으면 관리자 정보도 포함)
@Override
public List<EmpVO> detail(EmpVO empVO){
return this.empMapper.detail(empVO);
}
<EmpService.java>
// 직원 상세 보기 (관리자가 있으면 관리자 정보도 포함)
public List<EmpVO> detail(EmpVO empVO);
<EmpController.java>
//직원 상세보기
/*
요청URI : /emp/detail?empNum=EMP006
요청파라미터 : empNum=EMP007
요청방식 :get
*/
@GetMapping("/detail")
public String detail(@RequestParam String empNum
, @ModelAttribute EmpVO empVO, Model model) {
log.info("empNum : " + empNum);
log.info("empVO : " + empVO);
// 상세화면은 등록화면과 동일 + empVO데이터로 채우면 됨
List<EmpVO> empVOList = this.empService.detail(empVO);
log.info("empVOList : " + empVOList);
model.addAttribute("data", empVOList);
// emp 폴더의 detail.jsp를 forwarding
return "emp/detail";
}
detail.jsp 생성 (create.jsp복사)
- 부트스트랩 적용
https://getbootstrap.kr/docs/5.2/components/navs-tabs/
-컴포넌트=-> 네비게이션탭
<ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Active</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item">
<a class="nav-link disabled">Disabled</a>
</li>
</ul>
복사해서
form 태그 위에 복붙
- <script type="text/javascript" src="/resources/js/bootstrap.min.js"></script> 상단에 추가
직원 , 관리자 탭을 클릭했을 때 active
- toggleClass() 메서드는 해당 클래스를 토글함
- removeAttr(): 선택한 요소에서 하나 이상의 특성을 제거함
- attr() : 선택한 요소의 속성을 추가
$(".nav-link").on("click",function(){
// toggleClass() 메서드는 해당 클래스를 토글함
$(".link").toggleClass("active");
// removeAttr(): 선택한 요소에서 하나 이상의 특성을 제거함
$(".link").removeAttr("aria=current");
// attr() : 선택한 요소의 속성을 추가
$(this).attr("aria-current","page");
});
});
</script>
<!-- 요청URI : /emp/createPost
요청파라미터 : {empNum=EMP001,zipCode=12345,address=대전...,empMjNum=}
요청방식 : post
-->
<ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link link active" aria-current="page" href="#">직원</a>
</li>
<li class="nav-item">
<a class="nav-link link" href="#">관리자</a>
</li>
</ul>
- 직원과 관리자에 div를 주고 스크립트 작성
$(".nav-link").on("click",function(){
//toggleClass() 메서드는 해당 클래스를 토글함
$(".link").toggleClass("active");
//removeAttr() : 선택한 요소에서 하나 이상의 특성을 제거함
$(".link").removeAttr("aria-current");
//attr() : 선택한 요소의 속성을 추가함
$(this).attr("aria-current","page");
//this : link 클래스는 2개. 그 중에서 클릭한 바로 그 요소
let id = $(this).data("id"); //employee 또는 manager
if(id=="employee"){ // 직원 탭의 경우 직원 div를 보여주고, 관리자 div는 hidden처리함
$("#employee").css("display","block");
$("#manager").css("display","none");
}else{ //관리자의 탭의 경우 관리자 div를 보여주고, 직원 div는 hidden처리함
$("#employee").css("display","none");
$("#manager").css("display","block");
}
});
<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<link rel="stylesheet" href="/resources/css/bootstrap.min.css" />
<script type="text/javascript" src="/resources/js/bootstrap.min.js"></script>
<script src="https://ssl.daumcdn.net/dmaps/map_js_init/postcode.v2.js"></script>
<script type="text/javascript" src="/resources/js/jquery-3.6.0.js"></script>
<script type="text/javascript">
$(function(){
//다음 우편번호 검색
$("#btnPostno").on("click",function(){
new daum.Postcode({
//다음 창에서 검색이 완료되면 콜백함수에 의해 결과 데이터가 data 객체로 들어옴
oncomplete:function(data){
//우편번호
$("#zipCode").val(data.zonecode);
$("#address").val(data.address);
$("#detAddress").val(data.buildingName);
}
}).open();
});
//직원번호 자동등록
// processType:false는 파일업로드 시 사용(let formData = new formData())
// contentType:"application/json;charset:utf-8"(보내는 타입)
// data:JSON.stringify(data);
// type:"post"
// success:function(){}
$.ajax({
url:"/emp/getEmpNum",
type:"post",
success:function(result){
console.log("result : " + result);
$("#empNumAjax").val(result);
}
});
//매니저 선택하기
$("#btnEmpMjNum").on("click",function(){
$.ajax({
url:"/emp/getEmpAll",
type:"post",
success:function(result){
//result : List<EmpVO> empVOList
let str = "";
$.each(result,function(index, empVO){
console.log("empVO.empNum : " + empVO.empNum);
console.log("empVO.empNm : " + empVO.empNm);
//<th scope="row"> : 해당 셀이 행(row)을 위한 헤더 셀임을 명시함.
str += "<tr class='trSelect'><th scope='col'>"+(index+1)+"</th>";
str += "<td>"+empVO.empNum+"</td><td>"+empVO.empNm+"</td></tr>";
});
console.log("str : " + str);
//.html() : 새로고침 / .append() : 누적
$("#trAdd").html(str); //초기화
// $("#trAdd").append(str);
}
});
});
//동적으로 생성된 요소의 이벤트 처리
// 달러(".trSelect").on("click",function(){})은 작동을 안할것임
$(document).on("click",".trSelect",function(){
//this : tr이 여러개인데 그 중 클릭한 바로 그 tr
//td들을 가져옴. 그 안에 데이터를 가져와보자
let resultStr = $(this).children().map(function(){
return $(this).text();}).get().join(",");
console.log("resultStr : " + resultStr);
//resultStr : 5,EMP005,이정재 => split(",")을 해서 배열로 만들고
//[1]는 매니저번호(empMjNum)로 입력, [2]는 매니저명(empMjNm)으로 입력
//arr[0] : 5 / arr[1] : EMP005 / arr[2] : 이정재
let arr = resultStr.split(",");
$("#empMjNum").val(arr[1]);
$("#empMjNm").val(arr[2]);
});
$(".nav-link").on("click",function(){
//toggleClass() 메서드는 해당 클래스를 토글함
$(".link").toggleClass("active");
//removeAttr() : 선택한 요소에서 하나 이상의 특성을 제거함
$(".link").removeAttr("aria-current");
//attr() : 선택한 요소의 속성을 추가함
$(this).attr("aria-current","page");
//this : link 클래스는 2개. 그 중에서 클릭한 바로 그 요소
let id = $(this).data("id"); //employee 또는 manager
if(id=="employee"){ // 직원 탭의 경우 직원 div를 보여주고, 관리자 div는 hidden처리함
$("#employee").css("display","block");
$("#manager").css("display","none");
}else{ //관리자의 탭의 경우 관리자 div를 보여주고, 직원 div는 hidden처리함
$("#employee").css("display","none");
$("#manager").css("display","block");
}
});
});
</script>
<!-- 요청URI : /emp/createPost
요청파라미터 : {empNum=EMP001,zipCode=12345,address=대전...,empMjNum=}
요청방식 : post
-->
<ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link link active" data-id="employee" aria-current="page" href="#">직원</a>
</li>
<li class="nav-item">
<a class="nav-link link" data-id="manager" href="#">관리자</a>
</li>
</ul>
<div class="bd-example" id="employee">
<form:form modelAttribute="empVO" action="/emp/createPost" method="post"
class="row g-3">
<!-- 직원번호 시작 -->
<div class="col-md-6" style="clear:both;">
<label for="empNum" class="form-label">직원번호</label>
<!-- <input type="text" name="empNum" class="form-control" id="empNum" -->
<%-- value="${empNum}" placeholder="직원번호를 입력해주세요" /> --%>
<%-- <form:input path="empNum" class="form-control" placeholder="직원번호를 입력해주세요" /> --%>
<input type="text" name="empNum" class="form-control" id="empNumAjax"
value="" placeholder="직원번호를 입력해주세요" readonly />
</div>
<!-- 직원번호 끝 -->
<!-- 주소 시작 -->
<div class="col-md-2">
<label for="zipCode" class="form-label">우편번호</label>
<input type="text" name="zipCode" class="form-control" id="zipCode"
placeholder="우편번호를 검색해주세요" readonly />
<button type="button" class="btn btn-primary" id="btnPostno">검색</button>
</div>
<div class="col-12">
<label for="address" class="form-label">주소</label>
<input type="text" name="address" class="form-control" id="address"
placeholder="주소를 검색해주세요" readonly />
</div>
<div class="col-12">
<label for="detAddress" class="form-label">상세주소</label>
<input type="text" name="detAddress" class="form-control" id="detAddress"
placeholder="상세주소를 입력해주세요">
</div>
<!-- 주소 끝 -->
<!-- 연락처 시작 -->
<div class="col-md-6">
<label for="empPne" class="form-label">연락처</label>
<input type="text" name="empPne" class="form-control" id="empPne"
placeholder="연락처를 입력해주세요" required />
<form:errors path="empPne" />
</div>
<!-- 연락처 끝 -->
<!-- 직원명 시작 -->
<div class="col-md-6">
<label for="empNm" class="form-label">직원명</label>
<input type="text" name="empNm" class="form-control" id="empNm"
placeholder="직원명을 입력해주세요" required />
<form:errors path="empNm" />
</div>
<!-- 직원명 끝 -->
<!-- 급여 시작 -->
<div class="col-md-6">
<label for="empPay" class="form-label">급여</label>
<input type="number" name="empPay" class="form-control" id="empPay"
placeholder="급여를 입력해주세요" required />
<form:errors path="empPay" />
</div>
<!-- 급여 끝 -->
<!-- 매니저 등록 시작 -->
<div class="col-md-6">
<label for="empMjNm" class="form-label">매니저명</label>
<input type="hidden" name="empMjNum" class="form-control" id="empMjNum" />
<input type="text" class="form-control" id="empMjNm"
placeholder="직원명을 입력해주세요" readonly />
<button type="button" class="btn btn-primary" id="btnEmpMjNum"
data-toggle="modal" data-target="#exampleModal"
>검색</button>
</div>
<!-- 매니저 등록 끝 -->
<div class="col-12">
<button type="submit" class="btn btn-primary">등록</button>
</div>
</form:form>
</div>
<div class="bd-example" id="manager" style="display:none;">
<form:form modelAttribute="empVO" action="/emp/createPost" method="post"
class="row g-3">
<!-- 직원번호 시작 -->
<div class="col-md-6" style="clear:both;">
<label for="empNum" class="form-label">직원번호</label>
<!-- <input type="text" name="empNum" class="form-control" id="empNum" -->
<%-- value="${empNum}" placeholder="직원번호를 입력해주세요" /> --%>
<%-- <form:input path="empNum" class="form-control" placeholder="직원번호를 입력해주세요" /> --%>
<input type="text" name="empNum" class="form-control" id="empNumAjax"
value="" placeholder="직원번호를 입력해주세요" readonly />
</div>
<!-- 직원번호 끝 -->
<!-- 주소 시작 -->
<div class="col-md-2">
<label for="zipCode" class="form-label">우편번호</label>
<input type="text" name="zipCode" class="form-control" id="zipCode"
placeholder="우편번호를 검색해주세요" readonly />
<button type="button" class="btn btn-primary" id="btnPostno">검색</button>
</div>
<div class="col-12">
<label for="address" class="form-label">주소</label>
<input type="text" name="address" class="form-control" id="address"
placeholder="주소를 검색해주세요" readonly />
</div>
<div class="col-12">
<label for="detAddress" class="form-label">상세주소</label>
<input type="text" name="detAddress" class="form-control" id="detAddress"
placeholder="상세주소를 입력해주세요">
</div>
<!-- 주소 끝 -->
<!-- 연락처 시작 -->
<div class="col-md-6">
<label for="empPne" class="form-label">연락처</label>
<input type="text" name="empPne" class="form-control" id="empPne"
placeholder="연락처를 입력해주세요" required />
<form:errors path="empPne" />
</div>
<!-- 연락처 끝 -->
<!-- 직원명 시작 -->
<div class="col-md-6">
<label for="empNm" class="form-label">직원명</label>
<input type="text" name="empNm" class="form-control" id="empNm"
placeholder="직원명을 입력해주세요" required />
<form:errors path="empNm" />
</div>
<!-- 직원명 끝 -->
<!-- 급여 시작 -->
<div class="col-md-6">
<label for="empPay" class="form-label">급여</label>
<input type="number" name="empPay" class="form-control" id="empPay"
placeholder="급여를 입력해주세요" required />
<form:errors path="empPay" />
</div>
<!-- 급여 끝 -->
<!-- 매니저 등록 시작 -->
<div class="col-md-6">
<label for="empMjNm" class="form-label">매니저명</label>
<input type="hidden" name="empMjNum" class="form-control" id="empMjNum" />
<input type="text" class="form-control" id="empMjNm"
placeholder="직원명을 입력해주세요" readonly />
<button type="button" class="btn btn-primary" id="btnEmpMjNum"
data-toggle="modal" data-target="#exampleModal"
>검색</button>
</div>
<!-- 매니저 등록 끝 -->
<div class="col-12">
<button type="submit" class="btn btn-primary">등록</button>
</div>
</form:form>
</div>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1>
<button type="button" class="btn-close" data-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<!-- -------- 직원 목록 시작 ------------- -->
<div class="bd-example">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">직원번호</th>
<th scope="col">이름</th>
</tr>
</thead>
<tbody id="trAdd">
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
</tr>
</tbody>
</table>
</div>
<!-- -------- 직원 목록 끝 ------------- -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
detail을 수정하자
- c:forEach문 사용
- scope
- value="${employee.empNum } ... value에 값을 전부 셋팅
- 관리자 input type hidden 을 text로 바꿈
<detail.jsp>
<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<link rel="stylesheet" href="/resources/css/bootstrap.min.css" />
<script type="text/javascript" src="/resources/js/bootstrap.min.js"></script>
<script src="https://ssl.daumcdn.net/dmaps/map_js_init/postcode.v2.js"></script>
<script type="text/javascript" src="/resources/js/jquery-3.6.0.js"></script>
<script type="text/javascript">
$(function(){
//다음 우편번호 검색
$("#btnPostno").on("click",function(){
new daum.Postcode({
//다음 창에서 검색이 완료되면 콜백함수에 의해 결과 데이터가 data 객체로 들어옴
oncomplete:function(data){
//우편번호
$("#zipCode").val(data.zonecode);
$("#address").val(data.address);
$("#detAddress").val(data.buildingName);
}
}).open();
});
//직원번호 자동등록
// processType:false는 파일업로드 시 사용(let formData = new formData())
// contentType:"application/json;charset:utf-8"(보내는 타입)
// data:JSON.stringify(data);
// type:"post"
// success:function(){}
$.ajax({
url:"/emp/getEmpNum",
type:"post",
success:function(result){
console.log("result : " + result);
$("#empNumAjax").val(result);
}
});
//매니저 선택하기
$("#btnEmpMjNum").on("click",function(){
$.ajax({
url:"/emp/getEmpAll",
type:"post",
success:function(result){
//result : List<EmpVO> empVOList
let str = "";
$.each(result,function(index, empVO){
console.log("empVO.empNum : " + empVO.empNum);
console.log("empVO.empNm : " + empVO.empNm);
//<th scope="row"> : 해당 셀이 행(row)을 위한 헤더 셀임을 명시함.
str += "<tr class='trSelect'><th scope='col'>"+(index+1)+"</th>";
str += "<td>"+empVO.empNum+"</td><td>"+empVO.empNm+"</td></tr>";
});
console.log("str : " + str);
//.html() : 새로고침 / .append() : 누적
$("#trAdd").html(str); //초기화
// $("#trAdd").append(str);
}
});
});
//동적으로 생성된 요소의 이벤트 처리
// 달러(".trSelect").on("click",function(){})은 작동을 안할것임
$(document).on("click",".trSelect",function(){
//this : tr이 여러개인데 그 중 클릭한 바로 그 tr
//td들을 가져옴. 그 안에 데이터를 가져와보자
let resultStr = $(this).children().map(function(){
return $(this).text();}).get().join(",");
console.log("resultStr : " + resultStr);
//resultStr : 5,EMP005,이정재 => split(",")을 해서 배열로 만들고
//[1]는 매니저번호(empMjNum)로 입력, [2]는 매니저명(empMjNm)으로 입력
//arr[0] : 5 / arr[1] : EMP005 / arr[2] : 이정재
let arr = resultStr.split(",");
$("#empMjNum").val(arr[1]);
$("#empMjNm").val(arr[2]);
});
$(".nav-link").on("click",function(){
//toggleClass() 메서드는 해당 클래스를 토글함
$(".link").toggleClass("active");
//removeAttr() : 선택한 요소에서 하나 이상의 특성을 제거함
$(".link").removeAttr("aria-current");
//attr() : 선택한 요소의 속성을 추가함
$(this).attr("aria-current","page");
//this : link 클래스는 2개. 그 중에서 클릭한 바로 그 요소
let id = $(this).data("id"); //employee 또는 manager
if(id=="employee"){ // 직원 탭의 경우 직원 div를 보여주고, 관리자 div는 hidden처리함
$("#employee").css("display","block");
$("#manager").css("display","none");
}else{ //관리자의 탭의 경우 관리자 div를 보여주고, 직원 div는 hidden처리함
$("#employee").css("display","none");
$("#manager").css("display","block");
}
});
});
</script>
<!-- 요청URI : /emp/createPost
요청파라미터 : {empNum=EMP001,zipCode=12345,address=대전...,empMjNum=}
요청방식 : post
-->
<!-- data : List<EmpVO> empVOList
stat.index : 0부터
stat.count : 1부터
empVO : EmpVO(empNum=EMP006, empAddr=대전, empPne=010-, empNm=뷔, empPay=0, empMjNum=EMP006, serVOList=null)
param : empNum=EMP006
scope : page(동일 jsp), request(동일 요청), session(동일 웹브라우저), applicateion(웹브라우저)
scope 기본은 page라 page일 경우 생략 가능
-->
<c:forEach var="empVO" items="${data}" varStatus="stat" >
${empVO.empNum}, ${param.empNum}<br />
<c:choose>
<c:when test="${empVO.empNum==param.empNum}"> <!-- 직원 -->
<c:set var="employee" value="${empVO}" scope="page" />
</c:when>
<c:otherwise> <!-- 관리자 -->
<c:set var="manager" value="${empVO}"/>
</c:otherwise>
</c:choose>
</c:forEach>
<ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link link active" data-id="employee" aria-current="page" href="#">직원</a>
</li>
<li class="nav-item">
<a class="nav-link link" data-id="manager" href="#">관리자</a>
</li>
</ul>
<div class="bd-example" id="employee">
<form:form modelAttribute="empVO" action="/emp/createPost" method="post"
class="row g-3">
<!-- 직원번호 시작 -->
<div class="col-md-6" style="clear:both;">
<label for="empNum" class="form-label">직원번호</label>
<!-- <input type="text" name="empNum" class="form-control" id="empNum" -->
<%-- value="${empNum}" placeholder="직원번호를 입력해주세요" /> --%>
<%-- <form:input path="empNum" class="form-control" placeholder="직원번호를 입력해주세요" /> --%>
<input type="text" name="empNum" class="form-control" id="empNumAjax"
value="${employee.empNum }" placeholder="직원번호를 입력해주세요" readonly />
</div>
<!-- 직원번호 끝 -->
<!-- 주소 시작 -->
<div class="col-md-2">
<label for="zipCode" class="form-label">우편번호</label>
<input type="text" name="zipCode" class="form-control" id="zipCode"
placeholder="우편번호를 검색해주세요" readonly />
<button type="button" class="btn btn-primary" id="btnPostno">검색</button>
</div>
<div class="col-12">
<label for="address" class="form-label">주소</label>
<input type="text" name="address" class="form-control" id="address"
placeholder="주소를 검색해주세요" readonly />
</div>
<div class="col-12">
<label for="detAddress" class="form-label">상세주소</label>
<input type="text" name="detAddress" class="form-control" id="detAddress"
placeholder="상세주소를 입력해주세요" value="${employee.empAddr}">
</div>
<!-- 주소 끝 -->
<!-- 연락처 시작 -->
<div class="col-md-6">
<label for="empPne" class="form-label">연락처</label>
<input type="text" name="empPne" class="form-control" id="empPne"
placeholder="연락처를 입력해주세요" value="${employee.empPne}" required />
<form:errors path="empPne" />
</div>
<!-- 연락처 끝 -->
<!-- 직원명 시작 -->
<div class="col-md-6">
<label for="empNm" class="form-label">직원명</label>
<input type="text" name="empNm" class="form-control" id="empNm"
placeholder="직원명을 입력해주세요" value="${employee.empNm}" required />
<form:errors path="empNm" />
</div>
<!-- 직원명 끝 -->
<!-- 급여 시작 -->
<div class="col-md-6">
<label for="empPay" class="form-label">급여</label>
<input type="number" name="empPay" class="form-control" id="empPay"
placeholder="급여를 입력해주세요" value="${employee.empPay}" required />
<form:errors path="empPay" />
</div>
<!-- 급여 끝 -->
<!-- 매니저 등록 시작 -->
<div class="col-md-6">
<label for="empMjNm" class="form-label">매니저명</label>
<input type="text" name="empMjNum" class="form-control"
id="empMjNum" value="${employee.empMjNum}" />
<input type="text" class="form-control" id="empMjNm"
placeholder="직원명을 입력해주세요" readonly />
<button type="button" class="btn btn-primary" id="btnEmpMjNum"
data-toggle="modal" data-target="#exampleModal"
>검색</button>
</div>
<!-- 매니저 등록 끝 -->
<div class="col-12">
<button type="submit" class="btn btn-primary">등록</button>
</div>
</form:form>
</div>
<div class="bd-example" id="manager" style="display:none;">
<form:form modelAttribute="empVO" action="/emp/createPost" method="post"
class="row g-3">
<!-- 직원번호 시작 -->
<div class="col-md-6" style="clear:both;">
<label for="empNum" class="form-label">직원번호</label>
<!-- <input type="text" name="empNum" class="form-control" id="empNum" -->
<%-- value="${empNum}" placeholder="직원번호를 입력해주세요" /> --%>
<%-- <form:input path="empNum" class="form-control" placeholder="직원번호를 입력해주세요" /> --%>
<input type="text" name="empNum" value="${manager.empNum}" class="form-control" id="empNumAjax"
value="" placeholder="직원번호를 입력해주세요" readonly />
</div>
<!-- 직원번호 끝 -->
<!-- 주소 시작 -->
<div class="col-md-2">
<label for="zipCode" class="form-label">우편번호</label>
<input type="text" name="zipCode" class="form-control" id="zipCode"
placeholder="우편번호를 검색해주세요" readonly />
<button type="button" class="btn btn-primary" id="btnPostno">검색</button>
</div>
<div class="col-12">
<label for="address" class="form-label">주소</label>
<input type="text" name="address" class="form-control" id="address"
placeholder="주소를 검색해주세요" readonly />
</div>
<div class="col-12">
<label for="detAddress" class="form-label">상세주소</label>
<input type="text" name="detAddress" class="form-control" id="detAddress"
placeholder="상세주소를 입력해주세요" value="${manager.empAddr}">
</div>
<!-- 주소 끝 -->
<!-- 연락처 시작 -->
<div class="col-md-6">
<label for="empPne" class="form-label">연락처</label>
<input type="text" name="empPne" class="form-control" id="empPne"
placeholder="연락처를 입력해주세요" value="${manager.empPne}" required />
<form:errors path="empPne" />
</div>
<!-- 연락처 끝 -->
<!-- 직원명 시작 -->
<div class="col-md-6">
<label for="empNm" class="form-label">직원명</label>
<input type="text" name="empNm" class="form-control" id="empNm"
placeholder="직원명을 입력해주세요" value="${manager.empNm}" required />
<form:errors path="empNm" />
</div>
<!-- 직원명 끝 -->
<!-- 급여 시작 -->
<div class="col-md-6">
<label for="empPay" class="form-label">급여</label>
<input type="number" name="empPay" class="form-control" id="empPay"
placeholder="급여를 입력해주세요" value="${manager.empPay}" required />
<form:errors path="empPay" />
</div>
<!-- 급여 끝 -->
<!-- 매니저 등록 시작 -->
<div class="col-md-6">
<label for="empMjNm" class="form-label">매니저명</label>
<input type="hidden" name="empMjNum" class="form-control"
id="empMjNum" value="${manager.empMjNum}" />
<input type="text" class="form-control" id="empMjNm"
placeholder="직원명을 입력해주세요" readonly />
<button type="button" class="btn btn-primary" id="btnEmpMjNum"
data-toggle="modal" data-target="#exampleModal"
>검색</button>
</div>
<!-- 매니저 등록 끝 -->
<div class="col-12">
<button type="submit" class="btn btn-primary">등록</button>
</div>
</form:form>
</div>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1>
<button type="button" class="btn-close" data-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<!-- -------- 직원 목록 시작 ------------- -->
<div class="bd-example">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">직원번호</th>
<th scope="col">이름</th>
</tr>
</thead>
<tbody id="trAdd">
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
</tr>
</tbody>
</table>
</div>
<!-- -------- 직원 목록 끝 ------------- -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
- 부트스트랩 가져오자
https://startbootstrap.com/previews/sb-admin-2
text-center 의 outer HTML로 소스 가져오자
그러고 div 밑에 붙혀넣기
<c:if test="${manager!=null}"> 는 form태그를 감싸준다.
<div class="bd-example" id="manager" style="display:none;">
<c:if test="${manager==null}"> <!-- 이 직원은 매니저가 없음 -->
<div class="text-center">
<div class="error mx-auto" data-text="관리자가 없습니다." style="font-size:17px;">관리자가 없습니다. </div>
</div>
</c:if>
<c:if test="${manager!=null}">
관리자가 없는 경우 출력 잘됨
sweetalert2 로 Toast 띄우자
- <link rel="stylesheet" href="/resources/css/sweetalert2.min.css" />
- <script type="text/javascript" src="/resources/js/sweetalert2.min.js"></script>
추가
<tiles -> index.jsp>
- body에 class 를 주고
- html 태그에도 class를 줌
<body id="page-top class="sidebar-mini sidebar-closed sidebar-collapse"">
<html class>
Toast를 써보자
<detail.jsp>
$(".nav-link").on("click",function(){
//toggleClass() 메서드는 해당 클래스를 토글함
$(".link").toggleClass("active");
//removeAttr() : 선택한 요소에서 하나 이상의 특성을 제거함
$(".link").removeAttr("aria-current");
//attr() : 선택한 요소의 속성을 추가함
$(this).attr("aria-current","page");
//this : link 클래스는 2개. 그 중에서 클릭한 바로 그 요소
let id = $(this).data("id"); //employee 또는 manager
if(id=="employee"){ // 직원 탭의 경우 직원 div를 보여주고, 관리자 div는 hidden처리함
$("#employee").css("display","block");
$("#manager").css("display","none");
}else{ //관리자의 탭의 경우 관리자 div를 보여주고, 직원 div는 hidden처리함
$("#employee").css("display","none");
$("#manager").css("display","block");
}
Toast.fire({
icon:'success',
title:'새롬이'
});
});
let Toast = Swal.mixin({
toast:true,
position:'top-end',
showConfirmButton:false,
timer:3000
});
스크립트를 추가해주면
- readonly 처리
- 등록버튼 수정
- 수정 모드 추가
- 검색버튼 disabled
- 스크립트 작성
//수정버튼 클릭 -> spn1:none / spn2:block
$("#edit").on("click",function(){
$("#spn1").css("display","none");
$("#spn2").css("display","block");
//읽기전용 해제
$(".form-control").removeAttr("readOnly");
//검색버튼 사용
$("#btnPostno").removeAttr("disabled");
$("#btnEmpMjNum").removeAttr("disabled");
});
//취소버튼 클릭 -> spn1:block / spn2:none
$("#cancel").on("click",function(){
$("#spn1").css("display","block");
$("#spn2").css("display","none");
//읽기전용
$(".form-control").attr("readOnly",true);
//검색버튼 비활성
$("#btnPostno").attr("disabled",true);
$("#btnEmpMjNum").attr("disabled",true);
});
수정버튼 눌렀을 때
검색버튼은 전부 disabled
<detail.jsp>
<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<link rel="stylesheet" href="/resources/css/bootstrap.min.css" />
<link rel="stylesheet" href="/resources/css/sweetalert2.min.css" />
<script type="text/javascript" src="/resources/js/bootstrap.min.js"></script>
<script type="text/javascript" src="/resources/js/sweetalert2.min.js"></script>
<script src="https://ssl.daumcdn.net/dmaps/map_js_init/postcode.v2.js"></script>
<script type="text/javascript" src="/resources/js/jquery-3.6.0.js"></script>
<script type="text/javascript">
$(function(){
//다음 우편번호 검색
$("#btnPostno").on("click",function(){
new daum.Postcode({
//다음 창에서 검색이 완료되면 콜백함수에 의해 결과 데이터가 data 객체로 들어옴
oncomplete:function(data){
//우편번호
$("#zipCode").val(data.zonecode);
$("#address").val(data.address);
$("#detAddress").val(data.buildingName);
}
}).open();
});
//직원번호 자동등록
// processType:false는 파일업로드 시 사용(let formData = new formData())
// contentType:"application/json;charset:utf-8"(보내는 타입)
// data:JSON.stringify(data);
// type:"post"
// success:function(){}
$.ajax({
url:"/emp/getEmpNum",
type:"post",
success:function(result){
console.log("result : " + result);
$("#empNumAjax").val(result);
}
});
//매니저 선택하기
$("#btnEmpMjNum").on("click",function(){
$.ajax({
url:"/emp/getEmpAll",
type:"post",
success:function(result){
//result : List<EmpVO> empVOList
let str = "";
$.each(result,function(index, empVO){
console.log("empVO.empNum : " + empVO.empNum);
console.log("empVO.empNm : " + empVO.empNm);
//<th scope="row"> : 해당 셀이 행(row)을 위한 헤더 셀임을 명시함.
str += "<tr class='trSelect'><th scope='col'>"+(index+1)+"</th>";
str += "<td>"+empVO.empNum+"</td><td>"+empVO.empNm+"</td></tr>";
});
console.log("str : " + str);
//.html() : 새로고침 / .append() : 누적
$("#trAdd").html(str); //초기화
// $("#trAdd").append(str);
}
});
});
//동적으로 생성된 요소의 이벤트 처리
// 달러(".trSelect").on("click",function(){})은 작동을 안할것임
$(document).on("click",".trSelect",function(){
//this : tr이 여러개인데 그 중 클릭한 바로 그 tr
//td들을 가져옴. 그 안에 데이터를 가져와보자
let resultStr = $(this).children().map(function(){
return $(this).text();}).get().join(",");
console.log("resultStr : " + resultStr);
//resultStr : 5,EMP005,이정재 => split(",")을 해서 배열로 만들고
//[1]는 매니저번호(empMjNum)로 입력, [2]는 매니저명(empMjNm)으로 입력
//arr[0] : 5 / arr[1] : EMP005 / arr[2] : 이정재
let arr = resultStr.split(",");
$("#empMjNum").val(arr[1]);
$("#empMjNm").val(arr[2]);
});
$(".nav-link").on("click",function(){
//toggleClass() 메서드는 해당 클래스를 토글함
$(".link").toggleClass("active");
//removeAttr() : 선택한 요소에서 하나 이상의 특성을 제거함
$(".link").removeAttr("aria-current");
//attr() : 선택한 요소의 속성을 추가함
$(this).attr("aria-current","page");
//this : link 클래스는 2개. 그 중에서 클릭한 바로 그 요소
let id = $(this).data("id"); //employee 또는 manager
if(id=="employee"){ // 직원 탭의 경우 직원 div를 보여주고, 관리자 div는 hidden처리함
$("#employee").css("display","block");
$("#manager").css("display","none");
}else{ //관리자의 탭의 경우 관리자 div를 보여주고, 직원 div는 hidden처리함
$("#employee").css("display","none");
$("#manager").css("display","block");
}
Toast.fire({
icon:'success',
title:'새롬이'
});
});
let Toast = Swal.mixin({
toast:true,
position:'top-end',
showConfirmButton:false,
timer:3000
});
//수정버튼 클릭 -> spn1:none / spn2:block
$("#edit").on("click",function(){
$("#spn1").css("display","none");
$("#spn2").css("display","block");
//읽기전용 해제
$(".form-control").removeAttr("readOnly");
//검색버튼 사용
$("#btnPostno").removeAttr("disabled");
$("#btnEmpMjNum").removeAttr("disabled");
});
//취소버튼 클릭 -> spn1:block / spn2:none
$("#cancel").on("click",function(){
$("#spn1").css("display","block");
$("#spn2").css("display","none");
//읽기전용
$(".form-control").attr("readOnly",true);
//검색버튼 비활성
$("#btnPostno").attr("disabled",true);
$("#btnEmpMjNum").attr("disabled",true);
});
});
</script>
<!-- 요청URI : /emp/createPost
요청파라미터 : {empNum=EMP001,zipCode=12345,address=대전...,empMjNum=}
요청방식 : post
-->
<!-- data : List<EmpVO> empVOList
stat.index : 0부터
stat.count : 1부터
empVO : EmpVO(empNum=EMP006, empAddr=대전, empPne=010-, empNm=뷔, empPay=0, empMjNum=EMP006, serVOList=null)
param : empNum=EMP006
scope : page(동일 jsp), request(동일 요청), session(동일 웹브라우저), applicateion(웹브라우저)
scope 기본은 page라 page일 경우 생략 가능
-->
<c:forEach var="empVO" items="${data}" varStatus="stat" >
<c:choose>
<c:when test="${empVO.empNum==param.empNum}"> <!-- 직원 -->
<c:set var="employee" value="${empVO}" scope="page" />
</c:when>
<c:otherwise> <!-- 관리자 -->
<c:set var="manager" value="${empVO}"/>
</c:otherwise>
</c:choose>
</c:forEach>
<ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link link active" data-id="employee" aria-current="page" href="#">직원</a>
</li>
<li class="nav-item">
<a class="nav-link link" data-id="manager" href="#">관리자</a>
</li>
</ul>
<div class="bd-example" id="employee">
<form:form modelAttribute="empVO" action="/emp/createPost" method="post"
class="row g-3">
<!-- 직원번호 시작 -->
<div class="col-md-6" style="clear:both;">
<label for="empNum" class="form-label">직원번호</label>
<!-- <input type="text" name="empNum" class="form-control" id="empNum" -->
<%-- value="${empNum}" placeholder="직원번호를 입력해주세요" /> --%>
<%-- <form:input path="empNum" class="form-control" placeholder="직원번호를 입력해주세요" /> --%>
<input type="text" name="empNum" class="form-control" id="empNumAjax"
value="${employee.empNum }" placeholder="직원번호를 입력해주세요" readonly />
</div>
<!-- 직원번호 끝 -->
<!-- 주소 시작 -->
<div class="col-md-2">
<label for="zipCode" class="form-label">우편번호</label>
<input type="text" name="zipCode" class="form-control" id="zipCode"
placeholder="우편번호를 검색해주세요" readonly />
<button type="button" class="btn btn-primary" id="btnPostno" disabled >검색</button>
</div>
<div class="col-12">
<label for="address" class="form-label">주소</label>
<input type="text" name="address" class="form-control" id="address"
placeholder="주소를 검색해주세요" readonly />
</div>
<div class="col-12">
<label for="detAddress" class="form-label">상세주소</label>
<input type="text" name="detAddress" class="form-control" id="detAddress"
placeholder="상세주소를 입력해주세요" value="${employee.empAddr}" readonly>
</div>
<!-- 주소 끝 -->
<!-- 연락처 시작 -->
<div class="col-md-6">
<label for="empPne" class="form-label">연락처</label>
<input type="text" name="empPne" class="form-control" id="empPne"
placeholder="연락처를 입력해주세요" value="${employee.empPne}" required readonly />
<form:errors path="empPne" />
</div>
<!-- 연락처 끝 -->
<!-- 직원명 시작 -->
<div class="col-md-6">
<label for="empNm" class="form-label">직원명</label>
<input type="text" name="empNm" class="form-control" id="empNm"
placeholder="직원명을 입력해주세요" value="${employee.empNm}" required readonly />
<form:errors path="empNm" />
</div>
<!-- 직원명 끝 -->
<!-- 급여 시작 -->
<div class="col-md-6">
<label for="empPay" class="form-label">급여</label>
<input type="number" name="empPay" class="form-control" id="empPay"
placeholder="급여를 입력해주세요" value="${employee.empPay}" required readonly />
<form:errors path="empPay" />
</div>
<!-- 급여 끝 -->
<!-- 매니저 등록 시작 -->
<div class="col-md-6">
<label for="empMjNm" class="form-label">매니저명</label>
<input type="text" name="empMjNum" class="form-control"
id="empMjNum" value="${employee.empMjNum}" />
<input type="text" class="form-control" id="empMjNm"
placeholder="직원명을 입력해주세요" readonly />
<button type="button" class="btn btn-primary" id="btnEmpMjNum"
data-toggle="modal" data-target="#exampleModal" disabled
>검색</button>
</div>
<!-- 매니저 등록 끝 -->
<div class="col-12">
<!-- 일반모드 시작 -->
<span id="spn1">
<button type="button" id="edit" class="btn btn-primary">수정</button>
<button type="button" id="delete" class="btn btn-danger">삭제</button>
</span>
<!-- 수정모드 시작 -->
<span id="spn2" style="display:none;">
<button type="button" id="ok" class="btn btn-success">확인</button>
<button type="button" id="cancel" class="btn btn-warning">취소</button>
</span>
</div>
</form:form>
</div>
<div class="bd-example" id="manager" style="display:none;">
<c:if test="${manager==null}"> <!-- 이 직원은 매니저가 없음 -->
<div class="text-center">
<div class="error mx-auto" data-text="관리자가 없습니다." style="font-size:17px;">관리자가 없습니다. </div>
</div>
</c:if>
<c:if test="${manager!=null}">
<form:form modelAttribute="empVO" action="/emp/createPost" method="post"
class="row g-3">
<!-- 직원번호 시작 -->
<div class="col-md-6" style="clear:both;">
<label for="empNum" class="form-label">직원번호</label>
<!-- <input type="text" name="empNum" class="form-control" id="empNum" -->
<%-- value="${empNum}" placeholder="직원번호를 입력해주세요" /> --%>
<%-- <form:input path="empNum" class="form-control" placeholder="직원번호를 입력해주세요" /> --%>
<input type="text" name="empNum" value="${manager.empNum}" class="form-control" id="empNumAjax"
value="" placeholder="직원번호를 입력해주세요" readonly />
</div>
<!-- 직원번호 끝 -->
<!-- 주소 시작 -->
<div class="col-md-2">
<label for="zipCode" class="form-label">우편번호</label>
<input type="text" name="zipCode" class="form-control" id="zipCode"
placeholder="우편번호를 검색해주세요" readonly />
<button type="button" class="btn btn-primary" id="btnPostno">검색</button>
</div>
<div class="col-12">
<label for="address" class="form-label">주소</label>
<input type="text" name="address" class="form-control" id="address"
placeholder="주소를 검색해주세요" readonly />
</div>
<div class="col-12">
<label for="detAddress" class="form-label">상세주소</label>
<input type="text" name="detAddress" class="form-control" id="detAddress"
placeholder="상세주소를 입력해주세요" value="${manager.empAddr}">
</div>
<!-- 주소 끝 -->
<!-- 연락처 시작 -->
<div class="col-md-6">
<label for="empPne" class="form-label">연락처</label>
<input type="text" name="empPne" class="form-control" id="empPne"
placeholder="연락처를 입력해주세요" value="${manager.empPne}" required />
<form:errors path="empPne" />
</div>
<!-- 연락처 끝 -->
<!-- 직원명 시작 -->
<div class="col-md-6">
<label for="empNm" class="form-label">직원명</label>
<input type="text" name="empNm" class="form-control" id="empNm"
placeholder="직원명을 입력해주세요" value="${manager.empNm}" required />
<form:errors path="empNm" />
</div>
<!-- 직원명 끝 -->
<!-- 급여 시작 -->
<div class="col-md-6">
<label for="empPay" class="form-label">급여</label>
<input type="number" name="empPay" class="form-control" id="empPay"
placeholder="급여를 입력해주세요" value="${manager.empPay}" required />
<form:errors path="empPay" />
</div>
<!-- 급여 끝 -->
<!-- 매니저 등록 시작 -->
<div class="col-md-6">
<label for="empMjNm" class="form-label">매니저명</label>
<input type="hidden" name="empMjNum" class="form-control"
id="empMjNum" value="${manager.empMjNum}" />
<input type="text" class="form-control" id="empMjNm"
placeholder="직원명을 입력해주세요" readonly />
<button type="button" class="btn btn-primary" id="btnEmpMjNum"
data-toggle="modal" data-target="#exampleModal"
>검색</button>
</div>
<!-- 매니저 등록 끝 -->
<div class="col-12">
<button type="submit" class="btn btn-primary">등록</button>
</div>
</form:form>
</c:if>
</div>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1>
<button type="button" class="btn-close" data-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<!-- -------- 직원 목록 시작 ------------- -->
<div class="bd-example">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">직원번호</th>
<th scope="col">이름</th>
</tr>
</thead>
<tbody id="trAdd">
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
</tr>
</tbody>
</table>
</div>
<!-- -------- 직원 목록 끝 ------------- -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
Merge_Into
- INSERT와 UPDATE를 동시에 처리
쿼리문 연습
MERGE INTO EMP A --대상 테이블
USING DUAL
ON(A.EMP_NUM = 'EMP001') --조건절(주로 기본키 데이터)
WHEN MATCHED THEN --조건절에 해당하는 데이터가 있으면 실행
UPDATE SET EMP_NM = '새롬이연습', EMP_ADDR = '안드로메다'
WHEN NOT MATCHED THEN --조건절에 해당하는 데이터가 없으면 실행
INSERT (EMP_NUM, EMP_ADDR, EMP_PNE, EMP_NM, EMP_PAY, EMP_MJ_NUM)
VALUES('EMP999','대전 중구','010-','강해린',12345,'')
;
<emp_SQL.xml>
- 신규 직원 등록 (createPost) 수정
<!-- 신규 직원 등록 및 수정 처리 -->
<insert id="createPost" parameterType="empVO">
<selectKey resultType="String" order="AFTER" keyProperty="empNum">
SELECT MAX(EMP_NUM)
FROM EMP
</selectKey>
MERGE INTO EMP A
USING DUAL
ON(A.EMP_NUM = #{empNum})
WHEN MATCHED THEN
UPDATE SET EMP_ADDR = #{empAddr}, EMP_PNE=#{empPne},
EMP_NM = #{empNm}, EMP_PAY=#{empPay}, EMP_MJ_NUM=#{empMjNum}
WHEN NOT MATCHED THEN
INSERT(EMP_NUM, EMP_ADDR, EMP_PNE, EMP_NM, EMP_PAY, EMP_MJ_NUM)
VALUES((
SELECT NVL(SUBSTR(MAX(EMP_NUM),1,3),'EMP')
|| TRIM(TO_CHAR(NVL(SUBSTR(MAX(EMP_NUM),4),0) + 1,'000'))
FROM EMP
)
,#{empAddr},#{empPne},#{empNm},#{empPay},#{empMjNum})
</insert>
<detail.jsp>
- <input type="text" name="mode" id="mode" value="update" /> 추가
<EmpController.java>
- createPost 매서드 수정
- 파라미터에 @RequestParam(required=false,defaultValue="new") String mode 추가
@PostMapping("/createPost")
public String createPost(@Valid @ModelAttribute EmpVO empVO,
String zipCode, String address, String detAddress,
@RequestParam(required=false,defaultValue="new") String mode,
Errors errors) {
//mode
//- create에서 오면 new
//- detail에서 오면 update
log.info("mode :" + mode);
String oldEmpNum = "";
// update를 실행한다면..
if(mode.equals("update")) {
oldEmpNum = empVO.getEmpNum(); // 기본키 데이터 백업
}
if(errors.hasErrors()) {
//forwarding
return "emp/create";
}
// 우편번호 + 주소 + 상세주소 => empVO의 enpAddr 멤버변수에 setting 하기
String empAddr = zipCode + " " + address + " " + detAddress;
empVO.setEmpAddr(empAddr);
log.info("empVO :" + empVO);
int result = this.empService.createPost(empVO);
// mode가 update
if(mode.equals("update")) {
return "redirect:/emp/detail?empNum="+oldEmpNum;
}else {
// insert일 경우
return "redirect:/emp/detail?empNum="+empVO.getEmpNum();
}
}
<detail.jsp>
- <button type="submit" id="ok" class="btn btn-success">확인</button>
- 확인 버튼 타입을 submit으로 바꾼다.
- 자동등록 부분 ajax 주석처리한다.
수정해보면 데이터가 바뀌는 걸 볼 수 있다 ~
delete
- id="employeeEmpNum" 아이디 설정
- 스크립트
// 삭제버튼 클릭
$("#delete").on("click",function(){
// 파라미터를 javascript 변수에 저장하고자 한다면..
let empNumJs = "${param.empNum}"; // 이렇게는 안쓴다.(보안에 취약할 수 있음) 이 방식은 DB를 거쳐오지 않았음
let empNum = $("#employeeEmpNum").val();
//세션스토리지에 변수값을 넣고자 한다면..
sessionStorage.setItem("empNum", empNum);
console.log("empNumJs : " + empNumJs + ", empNum :" + empNum);
//true(1) / false(0)
let cfm = confirm("삭제하시겠습니까?");
console.log("cfm: " + cfm);
if(cfm>0){ //삭제 수행
//json 오브젝트
let data = {"empNum":empNum};
// contentType : 보내는 타입
// dataType : 응답 데이터 타입
$.ajax({
url:"/emp/deletePost",
contentType:"application/json;charset=utf-8",
data:JSON.stringify(data),
dataType:"json",
type:"post",
success:function(result){
//controller에서 map.put("result",1); / ResponseBody
console.log("result : "+ JSON.stringify(result));
//result : {"result":"1"}
let str = result.result; //1 또는 0
//str이 0보다 크면 성공, 아니면 실패
//성공 시 /emp/list로 이동/ 실패 시 실패 메시지를 보여줌
if(str>0){
location.href="list";
}else{
Toast.fire({
icon:'success',
title:'삭제가 실패되었습니다.'
});
}
}
});
}else{ // 삭제 취소
Toast.fire({
icon:'success',
title:'삭제가 취소되었습니다.'
});
}
});
<emp_SQL.xml>
<!-- 직원 삭제 -->
<delete id="deletePost" parameterType="empVO">
DELETE FORM EMP
WHERE EMP_NUM = #{empNum}
</delete>
<EmpMapper.xml>
// 직원 삭제
public int deletePost(EmpVO empVO);
<EmpService.java>
// 직원 삭제
public int deletePost(EmpVO empVO);
<EmpServiceImpl.java>
// 직원 삭제
@Override
public int deletePost(EmpVO empVO) {
return this.empMapper.deletePost(empVO);
}
<EmpController.java>
/*
요청 URI : /emp/deletePost
요청파라미터 : let data = {"empNum":empNum}
요청방식 : post
*/
@ResponseBody
@PostMapping("/deletePost")
public Map<String, String> deletePost(@RequestBody EmpVO empVO) {
int result = this.empService.deletePost(empVO);
Map<String, String> map = new HashMap<String, String>();
map.put("result", result+"");
log.info("map : " + map);
return map;
}
LIST 목록 출력
<emp_SQL.xml>
<!-- 직원 목록 -->
<select id="list" resultType="empVO">
SELECT EMP_NUM, EMP_ADDR, EMP_PNE, EMP_NM, EMP_PAY, EMP_MJ_NUM
FROM EMP
START WITH EMP_MJ_NUM IS NULL
CONNECT BY PRIOR EMP_NUM = EMP_MJ_NUM
</select>
<EmpMapper.java>
// 직원 목록
public List<EmpVO> list();
<EmpService.java>
// 직원 목록
public List<EmpVO> list();
<EmpServiceImpl.java>
// 직원 목록
@Override
public List<EmpVO> list() {
return this.empMapper.list();
}
<EmpController.java>
/*
요청URI : /emp/list
요청방식: get
*/
@GetMapping("/list")
public String list(Model model){
List<EmpVO> empVOList = this.empService.list();
log.info("empVOList : " + empVOList);
model.addAttribute("data", empVOList);
//forwarding
return "emp/list";
}
- 테이블 부트스트랩 적용
https://startbootstrap.com/previews/sb-admin-2
<list.jsp>
- 부트스트랩 수정 후
- forEach문을 통해 리스트를 출력한다.
<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">직원목록</h6>
</div>
<div class="card-body">
<div class="table-responsive">
<div id="dataTable_wrapper" class="dataTables_wrapper dt-bootstrap4">
<div class="row">
<div class="col-sm-12 col-md-6">
<div class="dataTables_length" id="dataTable_length">
<label>Show <select name="dataTable_length"
aria-controls="dataTable"
class="custom-select custom-select-sm form-control form-control-sm"><option
value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option></select> entries
</label>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div id="dataTable_filter" class="dataTables_filter">
<label>Search:<input type="search"
class="form-control form-control-sm" placeholder=""
aria-controls="dataTable"></label>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<table class="table table-bordered dataTable" id="dataTable"
width="100%" cellspacing="0" role="grid"
aria-describedby="dataTable_info" style="width: 100%;">
<thead>
<tr role="row">
<th class="sorting sorting_asc" tabindex="0"
aria-controls="dataTable" rowspan="1" colspan="1"
aria-sort="ascending"
aria-label="Name: activate to sort column descending"
style="width: 66px;">번호</th>
<th class="sorting" tabindex="0" aria-controls="dataTable"
rowspan="1" colspan="1"
aria-label="Position: activate to sort column ascending"
style="width: 79px;">직원번호</th>
<th class="sorting" tabindex="0" aria-controls="dataTable"
rowspan="1" colspan="1"
aria-label="Office: activate to sort column ascending"
style="width: 54px;">직원명</th>
<th class="sorting" tabindex="0" aria-controls="dataTable"
rowspan="1" colspan="1"
aria-label="Age: activate to sort column ascending"
style="width: 31px;">급여</th>
<th class="sorting" tabindex="0" aria-controls="dataTable"
rowspan="1" colspan="1"
aria-label="Start date: activate to sort column ascending"
style="width: 69px;">매니저</th>
</tr>
</thead>
<tbody>
<c:forEach var="empVO" items="${data}" varStatus="stat">
<tr class="odd">
<td class="sorting_1">${stat.count}</td>
<td>${empVO.empNum}</td>
<td>${empVO.empNm}</td>
<td>${empVO.empPay}</td>
<td>${empVO.empMjNum}</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
<div class="row">
<div class="col-sm-12 col-md-5">
<div class="dataTables_info" id="dataTable_info" role="status"
aria-live="polite">Showing 1 to 10 of 57 entries</div>
</div>
<div class="col-sm-12 col-md-7">
<div class="dataTables_paginate paging_simple_numbers"
id="dataTable_paginate">
<ul class="pagination">
<li class="paginate_button page-item previous disabled"
id="dataTable_previous"><a href="#"
aria-controls="dataTable" data-dt-idx="0" tabindex="0"
class="page-link">Previous</a></li>
<li class="paginate_button page-item active"><a href="#"
aria-controls="dataTable" data-dt-idx="1" tabindex="0"
class="page-link">1</a></li>
<li class="paginate_button page-item "><a href="#"
aria-controls="dataTable" data-dt-idx="2" tabindex="0"
class="page-link">2</a></li>
<li class="paginate_button page-item "><a href="#"
aria-controls="dataTable" data-dt-idx="3" tabindex="0"
class="page-link">3</a></li>
<li class="paginate_button page-item "><a href="#"
aria-controls="dataTable" data-dt-idx="4" tabindex="0"
class="page-link">4</a></li>
<li class="paginate_button page-item "><a href="#"
aria-controls="dataTable" data-dt-idx="5" tabindex="0"
class="page-link">5</a></li>
<li class="paginate_button page-item "><a href="#"
aria-controls="dataTable" data-dt-idx="6" tabindex="0"
class="page-link">6</a></li>
<li class="paginate_button page-item next" id="dataTable_next"><a
href="#" aria-controls="dataTable" data-dt-idx="7" tabindex="0"
class="page-link">Next</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
쿼리문
<emp_SQL.xml>
- 직원 목록 수정
- 매니저 번호가 아니라 매니저 이름이 출력되게 바꾸자
!-- 직원 목록 -->
<select id="list" resultType="empVO">
SELECT A.EMP_NUM, A.EMP_ADDR, A.EMP_PNE, A.EMP_NM, A.EMP_PAY
, A.EMP_MJ_NUM
, (SELECT B.EMP_NM FROM EMP B WHERE B.EMP_NUM = A.EMP_MJ_NUM) EMP_MJ_NM
FROM EMP A
START WITH A.EMP_MJ_NUM IS NULL
CONNECT BY PRIOR A.EMP_NUM = A.EMP_MJ_NUM
</select>
매니저 번호와 매니저명을 같이 설정해야 모달창 띄울 때 오류가 안나므로
멤버변수 추가해준다.
<EmpVO.jav>
- //매니저명(EMP_MJ_NM)
private String empMjNm;
package kr.or.ddit.vo;
import java.util.List;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.NotBlank;
import lombok.Data;
//직원
@Data
public class EmpVO {
//직원 번호
@NotBlank
private String empNum;
//주소
private String empAddr;
//연락처
@NotBlank
private String empPne;
//직원 명
@NotBlank
private String empNm;
//급여
@NotNull
private int empPay;
//매니저 번호
private String empMjNum;
//매니저명(EMP_MJ_NM)
private String empMjNm;
//직원(EMP) : 서비스(SER) = 1 : N
private List<SerVO> serVOList;
}
<list.jsp>
- 모달 추가
<td data-bs-toggle="modal" data-bs-target="#exampleModal"> <a data-bs-toggle="modal" href="#exampleModal">${empVO.empMjNum}</a>
여기서 td에다가 모달과 같은 토글과 아이디값을 넣어주거나
a태그에 모달과 같은 토글값을 넣어주면 모달창이 실행 된다
둘 중 하나 써주면 됨
<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<link rel="stylesheet" href="/resources/css/bootstrap.min.css" />
<link rel="stylesheet" href="/resources/css/sweetalert2.min.css" />
<script type="text/javascript" src="/resources/js/bootstrap.min.js"></script>
<script src="https://ssl.daumcdn.net/dmaps/map_js_init/postcode.v2.js"></script>
<script type="text/javascript" src="/resources/js/jquery-3.6.0.js"></script>
<script type="text/javascript" src="/resources/js/sweetalert2.min.js"></script>
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">직원목록</h6>
</div>
<div class="card-body">
<div class="table-responsive">
<div id="dataTable_wrapper" class="dataTables_wrapper dt-bootstrap4">
<div class="row">
<div class="col-sm-12 col-md-6">
<div class="dataTables_length" id="dataTable_length">
<label>Show <select name="dataTable_length"
aria-controls="dataTable"
class="custom-select custom-select-sm form-control form-control-sm"><option
value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option></select> entries
</label>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div id="dataTable_filter" class="dataTables_filter">
<label>Search:<input type="search"
class="form-control form-control-sm" placeholder=""
aria-controls="dataTable"></label>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<table class="table table-bordered dataTable" id="dataTable"
width="100%" cellspacing="0" role="grid"
aria-describedby="dataTable_info" style="width: 100%;">
<thead>
<tr role="row">
<th class="sorting sorting_asc" tabindex="0"
aria-controls="dataTable" rowspan="1" colspan="1"
aria-sort="ascending"
aria-label="Name: activate to sort column descending"
style="width: 66px;">번호</th>
<th class="sorting" tabindex="0" aria-controls="dataTable"
rowspan="1" colspan="1"
aria-label="Position: activate to sort column ascending"
style="width: 79px;">직원번호</th>
<th class="sorting" tabindex="0" aria-controls="dataTable"
rowspan="1" colspan="1"
aria-label="Office: activate to sort column ascending"
style="width: 54px;">직원명</th>
<th class="sorting" tabindex="0" aria-controls="dataTable"
rowspan="1" colspan="1"
aria-label="Age: activate to sort column ascending"
style="width: 31px;">급여</th>
<th class="sorting" tabindex="0" aria-controls="dataTable"
rowspan="1" colspan="1"
aria-label="Start date: activate to sort column ascending"
style="width: 69px;">매니저</th>
</tr>
</thead>
<tbody>
<!-- data : List<EmpVO> empVOList
empVO : EmpVO
stat.index : 0부터 시작
stat.count : 1부터 시작
-->
<c:forEach var="empVO" items="${data}" varStatus="stat">
<tr class="odd">
<td class="sorting_1">${stat.count}</td>
<td>${empVO.empNum}</td>
<td>${empVO.empNm}</td>
<td>${empVO.empPay}</td>
<td data-bs-toggle="modal" data-bs-target="#exampleModal">
<a class="showMj" data-empMjNum="${empVO.empMjNum}"
data-bs-toggle="modal" href="#exampleModal">${empVO.empMjNm}</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
<div class="row">
<div class="col-sm-12 col-md-5">
<div class="dataTables_info" id="dataTable_info" role="status"
aria-live="polite">Showing 1 to 10 of 57 entries</div>
</div>
<div class="col-sm-12 col-md-7">
<div class="dataTables_paginate paging_simple_numbers"
id="dataTable_paginate">
<ul class="pagination">
<li class="paginate_button page-item previous disabled"
id="dataTable_previous"><a href="#"
aria-controls="dataTable" data-dt-idx="0" tabindex="0"
class="page-link">Previous</a></li>
<li class="paginate_button page-item active"><a href="#"
aria-controls="dataTable" data-dt-idx="1" tabindex="0"
class="page-link">1</a></li>
<li class="paginate_button page-item "><a href="#"
aria-controls="dataTable" data-dt-idx="2" tabindex="0"
class="page-link">2</a></li>
<li class="paginate_button page-item "><a href="#"
aria-controls="dataTable" data-dt-idx="3" tabindex="0"
class="page-link">3</a></li>
<li class="paginate_button page-item "><a href="#"
aria-controls="dataTable" data-dt-idx="4" tabindex="0"
class="page-link">4</a></li>
<li class="paginate_button page-item "><a href="#"
aria-controls="dataTable" data-dt-idx="5" tabindex="0"
class="page-link">5</a></li>
<li class="paginate_button page-item "><a href="#"
aria-controls="dataTable" data-dt-idx="6" tabindex="0"
class="page-link">6</a></li>
<li class="paginate_button page-item next" id="dataTable_next"><a
href="#" aria-controls="dataTable" data-dt-idx="7" tabindex="0"
class="page-link">Next</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">매니저정보</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<!-- 내용 시작 -->
<div class="mb-3 row">
<label for="staticEmail" class="col-sm-2 col-form-label">직원 번호</label>
<div class="col-sm-10">
<input type="text" readonly class="form-control-plaintext" id="empNum" value="">
</div>
</div>
<div class="mb-3 row">
<label for="staticEmail" class="col-sm-2 col-form-label">직원 명</label>
<div class="col-sm-10">
<input type="text" readonly class="form-control-plaintext" id="empNm" value="">
</div>
</div>
<div class="mb-3 row">
<label for="staticEmail" class="col-sm-2 col-form-label">연락처</label>
<div class="col-sm-10">
<input type="text" readonly class="form-control-plaintext" id="empPne" value="">
</div>
</div>
<div class="mb-3 row">
<label for="staticEmail" class="col-sm-2 col-form-label">주소</label>
<div class="col-sm-10">
<input type="text" readonly class="form-control-plaintext" id="empAddr" value="">
</div>
</div>
<div class="mb-3 row">
<label for="staticEmail" class="col-sm-2 col-form-label">급여</label>
<div class="col-sm-10">
<input type="text" readonly class="form-control-plaintext" id="empPay" value="">
</div>
</div>
<div class="mb-3 row">
<label for="staticEmail" class="col-sm-2 col-form-label">매니저</label>
<div class="col-sm-10">
<input type="text" readonly class="form-control-plaintext" id="empMjNm" value="">
</div>
</div>
<!-- 내용 끝 -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$(function(){
$(document).on("click",".showMj",function(){
// $("#showMj").on("click",function(){
console.log("ajax로 매니저 정보 가져와보자");
console.log("요청URI : /emp/showMj");
console.log("요청파라미터(json) : {'empNum':'EMP006'}");
console.log("요청방식 : post");
});
});
</script>
이제 모달창에 리스트 출력 되게 해보자
-부트스트랩
https://getbootstrap.com/docs/5.3/forms/form-control/
Form controls
Give textual form controls like <input>s and <textarea>s an upgrade with custom styles, sizing, focus states, and more.
getbootstrap.com
<div class="mb-3 row">
<label for="staticEmail" class="col-sm-2 col-form-label">Email</label>
<div class="col-sm-10">
<input type="text" readonly class="form-control-plaintext" id="staticEmail" value="email@example.com">
</div>
</div>
<div class="mb-3 row">
<label for="inputPassword" class="col-sm-2 col-form-label">Password</label>
<div class="col-sm-10">
<input type="password" class="form-control" id="inputPassword">
</div>
</div>
<list.jsp>
- 스크립트 추가
<script type="text/javascript">
$(function(){
// $(document).on("click",".showMj",function(){
$(".showMj").on("click",function(){
console.log("ajax로 매니저 정보 가져와보자");
console.log("요청URI : /emp/showMj");
console.log("요청파라미터(json) : {'empNum':'EMP006'}");
console.log("요청방식 : post");
//this : class="showMj"이 여러개이고, 이 중에서 하나를 클릭한 바로 그 요소
//data-emp-mj-num="EMP006"
let empMjNum = $(this).data("empMjNum");
console.log("empMjNum : " + empMjNum);
//json object
let data = {"empMjNum":empMjNum};
$.ajax({
url:"/emp/showMj",
contentType:"application/json;charset:utf-8",
data:JSON.stringify(data),//마샬링,일렬화(serialization)
type:"post",
dataType:"json",
success:function(result){
console.log("result : " + JSON.stringify(result));
$("#empNum").val(result.empNum);
$("#empNm").val(result.empNm);
$("#empPne").val(result.empPne);
$("#empAddr").val(result.empAddr);
$("#empPay").val(result.empPay);
$("#empMjNm").val(result.empMjNm);
}
});
});
});
</script>
<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<link rel="stylesheet" href="/resources/css/bootstrap.min.css" />
<link rel="stylesheet" href="/resources/css/sweetalert2.min.css" />
<script type="text/javascript" src="/resources/js/bootstrap.min.js"></script>
<script src="https://ssl.daumcdn.net/dmaps/map_js_init/postcode.v2.js"></script>
<script type="text/javascript" src="/resources/js/jquery-3.6.0.js"></script>
<script type="text/javascript" src="/resources/js/sweetalert2.min.js"></script>
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">직원목록</h6>
</div>
<div class="card-body">
<div class="table-responsive">
<div id="dataTable_wrapper" class="dataTables_wrapper dt-bootstrap4">
<div class="row">
<div class="col-sm-12 col-md-6">
<div class="dataTables_length" id="dataTable_length">
<label>Show <select name="dataTable_length"
aria-controls="dataTable"
class="custom-select custom-select-sm form-control form-control-sm"><option
value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option></select> entries
</label>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div id="dataTable_filter" class="dataTables_filter">
<label>Search:<input type="search"
class="form-control form-control-sm" placeholder=""
aria-controls="dataTable"></label>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<table class="table table-bordered dataTable" id="dataTable"
width="100%" cellspacing="0" role="grid"
aria-describedby="dataTable_info" style="width: 100%;">
<thead>
<tr role="row">
<th class="sorting sorting_asc" tabindex="0"
aria-controls="dataTable" rowspan="1" colspan="1"
aria-sort="ascending"
aria-label="Name: activate to sort column descending"
style="width: 66px;">번호</th>
<th class="sorting" tabindex="0" aria-controls="dataTable"
rowspan="1" colspan="1"
aria-label="Position: activate to sort column ascending"
style="width: 79px;">직원번호</th>
<th class="sorting" tabindex="0" aria-controls="dataTable"
rowspan="1" colspan="1"
aria-label="Office: activate to sort column ascending"
style="width: 54px;">직원명</th>
<th class="sorting" tabindex="0" aria-controls="dataTable"
rowspan="1" colspan="1"
aria-label="Age: activate to sort column ascending"
style="width: 31px;">급여</th>
<th class="sorting" tabindex="0" aria-controls="dataTable"
rowspan="1" colspan="1"
aria-label="Start date: activate to sort column ascending"
style="width: 69px;">매니저</th>
</tr>
</thead>
<tbody>
<!-- data : List<EmpVO> empVOList
empVO : EmpVO
stat.index : 0부터 시작
stat.count : 1부터 시작
-->
<c:forEach var="empVO" items="${data}" varStatus="stat">
<tr class="odd">
<td class="sorting_1">${stat.count}</td>
<td>${empVO.empNum}</td>
<td>${empVO.empNm}</td>
<td>${empVO.empPay}</td>
<td data-bs-toggle="modal" data-bs-target="#exampleModal">
<a class="showMj" data-emp-mj-num="${empVO.empMjNum}"
data-bs-toggle="modal" href="#exampleModal">${empVO.empMjNm}</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
<div class="row">
<div class="col-sm-12 col-md-5">
<div class="dataTables_info" id="dataTable_info" role="status"
aria-live="polite">Showing 1 to 10 of 57 entries</div>
</div>
<div class="col-sm-12 col-md-7">
<div class="dataTables_paginate paging_simple_numbers"
id="dataTable_paginate">
<ul class="pagination">
<li class="paginate_button page-item previous disabled"
id="dataTable_previous"><a href="#"
aria-controls="dataTable" data-dt-idx="0" tabindex="0"
class="page-link">Previous</a></li>
<li class="paginate_button page-item active"><a href="#"
aria-controls="dataTable" data-dt-idx="1" tabindex="0"
class="page-link">1</a></li>
<li class="paginate_button page-item "><a href="#"
aria-controls="dataTable" data-dt-idx="2" tabindex="0"
class="page-link">2</a></li>
<li class="paginate_button page-item "><a href="#"
aria-controls="dataTable" data-dt-idx="3" tabindex="0"
class="page-link">3</a></li>
<li class="paginate_button page-item "><a href="#"
aria-controls="dataTable" data-dt-idx="4" tabindex="0"
class="page-link">4</a></li>
<li class="paginate_button page-item "><a href="#"
aria-controls="dataTable" data-dt-idx="5" tabindex="0"
class="page-link">5</a></li>
<li class="paginate_button page-item "><a href="#"
aria-controls="dataTable" data-dt-idx="6" tabindex="0"
class="page-link">6</a></li>
<li class="paginate_button page-item next" id="dataTable_next"><a
href="#" aria-controls="dataTable" data-dt-idx="7" tabindex="0"
class="page-link">Next</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">매니저정보</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<!-- 내용 시작 -->
<div class="mb-3 row">
<label for="staticEmail" class="col-sm-2 col-form-label">직원 번호</label>
<div class="col-sm-10">
<input type="text" readonly class="form-control-plaintext" id="empNum" value="">
</div>
</div>
<div class="mb-3 row">
<label for="staticEmail" class="col-sm-2 col-form-label">직원 명</label>
<div class="col-sm-10">
<input type="text" readonly class="form-control-plaintext" id="empNm" value="">
</div>
</div>
<div class="mb-3 row">
<label for="staticEmail" class="col-sm-2 col-form-label">연락처</label>
<div class="col-sm-10">
<input type="text" readonly class="form-control-plaintext" id="empPne" value="">
</div>
</div>
<div class="mb-3 row">
<label for="staticEmail" class="col-sm-2 col-form-label">주소</label>
<div class="col-sm-10">
<input type="text" readonly class="form-control-plaintext" id="empAddr" value="">
</div>
</div>
<div class="mb-3 row">
<label for="staticEmail" class="col-sm-2 col-form-label">급여</label>
<div class="col-sm-10">
<input type="text" readonly class="form-control-plaintext" id="empPay" value="">
</div>
</div>
<div class="mb-3 row">
<label for="staticEmail" class="col-sm-2 col-form-label">매니저</label>
<div class="col-sm-10">
<input type="text" readonly class="form-control-plaintext" id="empMjNm" value="">
</div>
</div>
<!-- 내용 끝 -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$(function(){
// $(document).on("click",".showMj",function(){
$(".showMj").on("click",function(){
console.log("ajax로 매니저 정보 가져와보자");
console.log("요청URI : /emp/showMj");
console.log("요청파라미터(json) : {'empNum':'EMP006'}");
console.log("요청방식 : post");
//this : class="showMj"이 여러개이고, 이 중에서 하나를 클릭한 바로 그 요소
//data-emp-mj-num="EMP006"
let empMjNum = $(this).data("empMjNum");
console.log("empMjNum : " + empMjNum);
//json object
let data = {"empMjNum":empMjNum};
$.ajax({
url:"/emp/showMj",
contentType:"application/json;charset:utf-8",
data:JSON.stringify(data),//마샬링,일렬화(serialization)
type:"post",
dataType:"json",
success:function(result){
console.log("result : " + JSON.stringify(result));
$("#empNum").val(result.empNum);
$("#empNm").val(result.empNm);
$("#empPne").val(result.empPne);
$("#empAddr").val(result.empAddr);
$("#empPay").val(result.empPay);
$("#empMjNm").val(result.empMjNm);
}
});
});
});
</script>
<emp_SQL.xml>
- showMj 쿼리문 추가
<!-- 직원 1명의 정보 리턴
empVO{empNum=0,empMjNum=EMP006,...}
-->
<select id="showMj" parameterType="empVO" resultType="empVO">
SELECT A.EMP_NUM, A.EMP_ADDR, A.EMP_PNE, A.EMP_NM, A.EMP_PAY, A.EMP_MJ_NUM
, (SELECT B.EMP_NM FROM EMP B WHERE B.EMP_NUM = A.EMP_MJ_NUM) EMP_MJ_NM
FROM EMP A
WHERE A.EMP_NUM = #{empMjNum}
</select>
<EmpMapper.java>
// 직원 1명의 정보를 리턴
public EmpVO showMj(EmpVO empVO);
<EmpService.java>
// 직원 1명의 정보를 리턴
public EmpVO showMj(EmpVO empVO);
<EmpServiceImpl.java>
// 직원 1명의 정보를 리턴
@Override
public EmpVO showMj(EmpVO empVO) {
// TODO Auto-generated method stub
return this.empMapper.showMj(empVO);
}
<EmpController.java>
- showMj 매서드
/** 직원 1명의 정보를 리턴
요청URI : /emp/showMj
요청파라미터 : let data = {"empMjNum":empMjNum};
요청방식 : post
응답데이터타입 : json
*/
@ResponseBody
@PostMapping("/showMj")
public EmpVO showMj(@RequestBody EmpVO empVO) {
log.info("empVO : " + empVO);
empVO = this.empService.showMj(empVO);
log.info("empVO : " + empVO);
return empVO;
}
<list.jsp>
- 직원번호 클릭시 상세보기 페이지
<detail.jsp>
- a태그에 클래스를 버튼 클래스로 주면 버튼모양의 a태그가 걸린다.
검색
- 우선 list 매서드를 수정 (파라미터에 map을 추가해준다,)
<EmpController.java>
/*
요청URI : /emp/list
요청방식: get
map은 RequestParam
vo는 ModelAttribute
json은 RequestBody
*/
@GetMapping("/list")
public String list(Model model
, @RequestParam Map<String, String> map){
//map으로 파라미터를 받아서 매퍼xml에서 검색 조건으로 사용
List<EmpVO> empVOList = this.empService.list(map);
log.info("empVOList : " + empVOList);
model.addAttribute("data", empVOList);
//forwarding
return "emp/list";
}
<emp.SQL_xml>
<!-- 직원 목록
드루와 : map{show=10,keyword=개똥이}
LIKE와 함게 사용한 퍼센트(여러글자), 언더바(한글자)를 와일드카드라고 함
-->
<select id="list" parameterType="hashMap" resultType="empVO">
WITH T AS(
SELECT A.EMP_NUM, A.EMP_ADDR, A.EMP_PNE, A.EMP_NM, A.EMP_PAY
, A.EMP_MJ_NUM
, (SELECT B.EMP_NM FROM EMP B WHERE B.EMP_NUM = A.EMP_MJ_NUM) EMP_MJ_NM
FROM EMP A
START WITH A.EMP_MJ_NUM IS NULL
CONNECT BY PRIOR A.EMP_NUM = A.EMP_MJ_NUM
)
SELECT *
FROM T
WHERE 1 = 1
<!-- 조건 검색 -->
<if test="keyword!=null and keyword!=''">
AND (T.EMP_NUM LIKE '%' || #{keyword} || '%'
OR T.EMP_NM LIKE '%' || #{keyword} || '%'
OR T.EMP_MJ_NUM LIKE '%' || #{keyword} || '%')
</if>
</select>
<EmpMapper.java>
// 직원 목록
public List<EmpVO> list(Map<String, String> map);
<EmpService.java>
// 직원 목록
public List<EmpVO> list(Map<String, String> map);
<EmpServiceImpl.java>
// 직원 목록
@Override
public List<EmpVO> list(Map<String,String> map) {
return this.empMapper.list(map);
}
페이징
<emp_SQL_xml>
- 겹치는 부분을 sql 태그로 빼줌
- getTotal
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace : xml파일이 여러개일 수 있으므로
이를 구별하기 위한 식별 용도로 사용
-->
<mapper namespace="kr.or.ddit.mapper.EmpMapper">
<sql id="where">
<!-- 조건 검색 -->
<if test="keyword!=null and keyword!=''">
AND (T.EMP_NUM LIKE '%' || #{keyword} || '%'
OR T.EMP_NM LIKE '%' || #{keyword} || '%'
OR T.EMP_MJ_NUM LIKE '%' || #{keyword} || '%')
</if>
</sql>
<!-- 다음 직원번호를 가져옴 -->
<select id="getEmpNum" resultType="String">
SELECT NVL(SUBSTR(MAX(EMP_NUM),1,3),'EMP')
|| TRIM(TO_CHAR(NVL(SUBSTR(MAX(EMP_NUM),4),0) + 1,'000'))
FROM EMP
</select>
<!-- 신규 직원 등록 및 수정 처리 -->
<insert id="createPost" parameterType="empVO">
<selectKey resultType="String" order="AFTER" keyProperty="empNum">
SELECT MAX(EMP_NUM)
FROM EMP
</selectKey>
MERGE INTO EMP A
USING DUAL
ON(A.EMP_NUM = #{empNum})
WHEN MATCHED THEN
UPDATE SET EMP_ADDR = #{empAddr}, EMP_PNE=#{empPne},
EMP_NM = #{empNm}, EMP_PAY=#{empPay}, EMP_MJ_NUM=#{empMjNum}
WHEN NOT MATCHED THEN
INSERT(EMP_NUM, EMP_ADDR, EMP_PNE, EMP_NM, EMP_PAY, EMP_MJ_NUM)
VALUES((
SELECT NVL(SUBSTR(MAX(EMP_NUM),1,3),'EMP')
|| TRIM(TO_CHAR(NVL(SUBSTR(MAX(EMP_NUM),4),0) + 1,'000'))
FROM EMP
)
,#{empAddr},#{empPne},#{empNm},#{empPay},#{empMjNum})
</insert>
<!-- 모든 직원 정보 가져오기 -->
<select id="getEmpAll" resultType="empVO">
SELECT EMP_NUM, EMP_ADDR, EMP_PNE, EMP_NM, EMP_PAY, EMP_MJ_NUM
FROM EMP
ORDER BY EMP_NUM
</select>
<!-- 직원 상세 보기(관리자가 있으면 관리자 정보도 포함) -->
<select id="detail" parameterType="empVO" resultType="empVO">
SELECT A.EMP_NUM, A.EMP_ADDR, A.EMP_PNE, A.EMP_NM, A.EMP_PAY, A.EMP_MJ_NUM
FROM EMP A
WHERE A.EMP_NUM = #{empNum}
OR A.EMP_NUM = (
SELECT B.EMP_MJ_NUM FROM EMP B WHERE B.EMP_NUM = #{empNum}
)
</select>
<!-- 직원 삭제
empVO : {empNum=EMP001,zipCode=null,address=null...,empMjNum=null}
-->
<delete id="deletePost" parameterType="empVO">
DELETE FROM EMP
WHERE EMP_NUM = #{empNum}
</delete>
<!-- 직원 목록
LIKE와 함게 사용한 퍼센트(여러글자), 언더바(한글자)를 와일드카드라고 함
-->
<select id="list" parameterType="hashMap" resultType="empVO">
WITH T AS(
SELECT A.EMP_NUM, A.EMP_ADDR, A.EMP_PNE, A.EMP_NM, A.EMP_PAY
, A.EMP_MJ_NUM
, (SELECT B.EMP_NM FROM EMP B WHERE B.EMP_NUM = A.EMP_MJ_NUM) EMP_MJ_NM
FROM EMP A
START WITH A.EMP_MJ_NUM IS NULL
CONNECT BY PRIOR A.EMP_NUM = A.EMP_MJ_NUM
)
SELECT *
FROM T
WHERE 1 = 1
<include refid="where"></include>
</select>
<!-- 직원 1명의 정보 리턴
empVO{empNum=0,empMjNum=EMP006,..
-->
<select id="showMj" parameterType="empVO" resultType="empVO">
SELECT A.EMP_NUM, A.EMP_ADDR, A.EMP_PNE, A.EMP_NM, A.EMP_PAY, A.EMP_MJ_NUM
, (SELECT B.EMP_NM FROM EMP B WHERE B.EMP_NUM = A.EMP_MJ_NUM) EMP_MJ_NM
FROM EMP A
WHERE A.EMP_NUM = #{empMjNum}
</select>
<!-- 목록의 행 수를 구함 -->
<select id="getTotal" parameterType="hashMap" resultType="int">
WITH T AS(
SELECT A.EMP_NUM, A.EMP_ADDR, A.EMP_PNE, A.EMP_NM, A.EMP_PAY
, A.EMP_MJ_NUM
, (SELECT B.EMP_NM FROM EMP B WHERE B.EMP_NUM = A.EMP_MJ_NUM) EMP_MJ_NM
FROM EMP A
START WITH A.EMP_MJ_NUM IS NULL
CONNECT BY PRIOR A.EMP_NUM = A.EMP_MJ_NUM
)
SELECT COUNT(*) TOTAL
FROM T
WHERE 1 = 1
<include refid="where"></include>
</select>
</mapper>
<EmMapper.java>
// 목록의 행의 수를 구함
public int getTotal(Map<String, String> map);
<EmpService.java>
// 목록의 행의 수를 구함
public int getTotal(Map<String, String> map);
<EmpServiceImpl.java>
@Override
public int getTotal(Map<String, String> map) {
return this.empMapper.getTotal(map);
<EmpController.java>
@GetMapping("/list")
public String list(Model model
, @RequestParam Map<String,String> map
, @RequestParam(value="currentPage",required=false,defaultValue="1") int currentPage
, @RequestParam(value="show",required=false,defaultValue="10") int size){
log.info("map : " + map);
log.info("currentPage : " + currentPage);
log.info("size : " + size);
//map으로 파라미터를 받아서 매퍼xml에서 검색 조건으로 사용
List<EmpVO> empVOList = this.empService.list(map);
log.info("empVOList : " + empVOList);
//total
int total = this.empService.getTotal(map);
log.info("total : " + total);
//size <- map.get("show")
// int size = Integer.parseInt(map.get("show"));
log.info("empVOList : " + empVOList);
//empVOList 객체를 페이징 처리해보자
//new ArticlePage<EmpVO>(total, currentPage, size, content)
model.addAttribute("data", new ArticlePage<EmpVO>(total, currentPage, size, empVOList));
//forwarding
return "emp/list";
}
<list.jsp>
- <c:forEach var="empVO" items="${data.content}" varStatus="stat">
- data.content로 바꿔준다.
- ROW_NUMBER 는 정렬이 필요하지만
- ROWNUM은 정렬 필요 없음
페이징 쿼리문
SELECT *
FROM
(
WITH T AS(
SELECT A.EMP_NUM, A.EMP_ADDR, A.EMP_PNE, A.EMP_NM, A.EMP_PAY
, A.EMP_MJ_NUM
, (SELECT B.EMP_NM FROM EMP B WHERE B.EMP_NUM = A.EMP_MJ_NUM) EMP_MJ_NM
FROM EMP A
START WITH A.EMP_MJ_NUM IS NULL
CONNECT BY PRIOR A.EMP_NUM = A.EMP_MJ_NUM
)
SELECT ROWNUM RNUM
, T.EMP_NUM, T.EMP_ADDR, T.EMP_PNE, T.EMP_NM, T.EMP_PAY
, T.EMP_MJ_NUM, T.EMP_MJ_NM
FROM T
WHERE 1 = 1
AND (T.EMP_NUM = 'EMP007'
OR T.EMP_NM = 'EMP007'
OR T.EMP_MJ_NUM = 'EMP007')
) U
WHERE U.RNUM BETWEEN (1 * 10)-(10-1) AND (1 * 10)
<emp_SQL.xml>
list 고쳐줌
<!-- 직원 목록 -->
<select id="list" parameterType="hashMap" resultType="empVO">
SELECT *
FROM
(
WITH T AS(
SELECT A.EMP_NUM, A.EMP_ADDR, A.EMP_PNE, A.EMP_NM, A.EMP_PAY
, A.EMP_MJ_NUM
, (SELECT B.EMP_NM FROM EMP B WHERE B.EMP_NUM = A.EMP_MJ_NUM) EMP_MJ_NM
FROM EMP A
START WITH A.EMP_MJ_NUM IS NULL
CONNECT BY PRIOR A.EMP_NUM = A.EMP_MJ_NUM
)
SELECT ROWNUM RNUM
, T.EMP_NUM, T.EMP_ADDR, T.EMP_PNE, T.EMP_NM, T.EMP_PAY
, T.EMP_MJ_NUM, T.EMP_MJ_NM
FROM T
WHERE 1 = 1
<include refid="where"></include>
) U
WHERE U.RNUM BETWEEN (#{currentPage} * #{show})-(#{show}-1) AND (#{currentPage} * #{show})
</select>
<EmpVO.java>
- //행번호
private int rnum; - 추가
package kr.or.ddit.vo;
import java.util.List;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.NotBlank;
import lombok.Data;
//직원
@Data
public class EmpVO {
//직원 번호
@NotBlank
private String empNum;
//주소
private String empAddr;
//연락처
@NotBlank
private String empPne;
//직원 명
@NotBlank
private String empNm;
//급여
@NotNull
private int empPay;
//매니저 번호
private String empMjNum;
//매니저명(EMP_MJ_NM)
private String empMjNm;
//행번호
private int rnum;
//직원(EMP) : 서비스(SER) = 1 : N
private List<SerVO> serVOList;
}
<EmpController.java>
- map에 currentPage, size를 추가해줘야함
- map.put("currentPage", currentPage+"");
- map.put("show", size+"");
- // 1) /emp/list : show가 null
// 2) /emp/list?show : show의 값이 없음
if(map.get("show")==null || map.get("show").length()<1) {
map.put("show", "10");
}
@GetMapping("/list")
public String list(Model model
, @RequestParam Map<String,String> map
, @RequestParam(value="currentPage",required=false,defaultValue="1") int currentPage
, @RequestParam(value="show",required=false,defaultValue="10") int size){
log.info("map : " + map);
log.info("currentPage : " + currentPage);
log.info("size : " + size);
map.put("currentPage", currentPage+"");
// 1) /emp/list : show가 null
// 2) /emp/list?show : show의 값이 없음
if(map.get("show")==null || map.get("show").length()<1) {
map.put("show", "10");
}
//map으로 파라미터를 받아서 매퍼xml에서 검색 조건으로 사용
List<EmpVO> empVOList = this.empService.list(map);
log.info("empVOList : " + empVOList);
//total
int total = this.empService.getTotal(map);
log.info("total : " + total);
//size <- map.get("show")
// int size = Integer.parseInt(map.get("show"));
log.info("empVOList : " + empVOList);
//empVOList 객체를 페이징 처리해보자
//new ArticlePage<EmpVO>(total, currentPage, size, content)
model.addAttribute("data", new ArticlePage<EmpVO>(total, currentPage, size, empVOList));
//forwarding
return "emp/list";
}
<list.jsp>
- 페이징처리를해주자.
<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<link rel="stylesheet" href="/resources/css/bootstrap.min.css" />
<link rel="stylesheet" href="/resources/css/sweetalert2.min.css" />
<script type="text/javascript" src="/resources/js/bootstrap.min.js"></script>
<script src="https://ssl.daumcdn.net/dmaps/map_js_init/postcode.v2.js"></script>
<script type="text/javascript" src="/resources/js/jquery-3.6.0.js"></script>
<script type="text/javascript" src="/resources/js/sweetalert2.min.js"></script>
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">직원목록</h6>
</div>
<div class="card-body">
<div class="table-responsive">
<div id="dataTable_wrapper" class="dataTables_wrapper dt-bootstrap4">
<!-- 검색 영역 시작 action을 생략하면 현재의 URI, method를 생략하면 기본이 get -->
<form name="frm" id="frm" action="/emp/list" method="get">
<div class="row">
<div class="col-sm-12 col-md-6">
<div class="dataTables_length" id="dataTable_length">
<label>Show
<!-- 한 화면에 보여질 행의 수 -->
<select
aria-controls="dataTable"
name="show" id="show"
class="custom-select custom-select-sm form-control form-control-sm"><option
value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option></select> entries
</label>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div id="dataTable_filter" class="dataTables_filter">
<label>Search:<input type="search" name="keyword"
class="form-control form-control-sm"
placeholder="검색어를 입력해주세요"
aria-controls="dataTable"
value="${param.keyword}">
</label>
<label>
<button type="submit" class="btn btn-primary btn-icon-split btn-sm">
<span class="icon text-white-50">
<i class="fas fa-flag"></i>
</span>
<span class="text">검색</span>
</button>
</label>
</div>
</div>
</div>
</form>
<!-- 검색 영역 끝 -->
<div class="row">
<div class="col-sm-12">
<table class="table table-bordered dataTable" id="dataTable"
width="100%" cellspacing="0" role="grid"
aria-describedby="dataTable_info" style="width: 100%;">
<thead>
<tr role="row">
<th class="sorting sorting_asc" tabindex="0"
aria-controls="dataTable" rowspan="1" colspan="1"
aria-sort="ascending"
aria-label="Name: activate to sort column descending"
style="width: 66px;">번호</th>
<th class="sorting" tabindex="0" aria-controls="dataTable"
rowspan="1" colspan="1"
aria-label="Position: activate to sort column ascending"
style="width: 79px;">직원번호</th>
<th class="sorting" tabindex="0" aria-controls="dataTable"
rowspan="1" colspan="1"
aria-label="Office: activate to sort column ascending"
style="width: 54px;">직원명</th>
<th class="sorting" tabindex="0" aria-controls="dataTable"
rowspan="1" colspan="1"
aria-label="Age: activate to sort column ascending"
style="width: 31px;">급여</th>
<th class="sorting" tabindex="0" aria-controls="dataTable"
rowspan="1" colspan="1"
aria-label="Start date: activate to sort column ascending"
style="width: 69px;">매니저</th>
</tr>
</thead>
<tbody>
<!-- data : List<EmpVO> empVOList
empVO : EmpVO
stat.index : 0부터 시작
stat.count : 1부터 시작
data : AtriclePage
data.content : ArticlePage의 content 멤버변수(List<EmpVO>)
-->
<c:forEach var="empVO" items="${data.content}" varStatus="stat">
<tr class="odd">
<td class="sorting_1">${empVO.rnum}</td>
<td><a href="/emp/detail?empNum=${empVO.empNum}">${empVO.empNum}</a></td>
<td>${empVO.empNm}</td>
<td>${empVO.empPay}</td>
<td data-bs-toggle="modal" data-bs-target="#exampleModal">
<a class="showMj" data-emp-mj-num="${empVO.empMjNum}"
data-bs-toggle="modal" href="#exampleModal">${empVO.empMjNm}</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
<div class="row">
<div class="col-sm-12 col-md-5">
<div class="dataTables_info" id="dataTable_info" role="status"
aria-live="polite">Showing 1 to 10 of 57 entries</div>
</div>
<div class="col-sm-12 col-md-7">
<div class="dataTables_paginate paging_simple_numbers"
id="dataTable_paginate">
<ul class="pagination">
<li class="paginate_button page-item previous
<c:if test='${data.startPage <6 }'>disabled</c:if>
"id="dataTable_previous">
<!-- keyword${param.keyword} -->
<a href="/emp/list?currentPage=${data.startPage-5}&keyword=${param.keyword}"
aria-controls="dataTable" data-dt-idx="0" tabindex="0"
class="page-link">Previous</a></li>
<c:forEach var="pNo" begin="${data.startPage}" end="${data.endPage}">
<li class="paginate_button page-item
<c:if test='${param.currentPage==pNo}'>active</c:if>
">
<a href="/emp/list?currentPage=${pNo}&keyword=${param.keyword}"
aria-controls="dataTable" data-dt-idx="1" tabindex="0"
class="page-link">${pNo}</a></li>
</c:forEach>
<li class="paginate_button page-item next
<c:if test='${data.endPage == data.totalPages}'>disabled</c:if>
" id="dataTable_next">
<a href="/emp/list?currentPage=${data.startPage+5}&keyword=${param.keyword}" aria-controls="dataTable" data-dt-idx="7" tabindex="0"
class="page-link">Next</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">매니저정보</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<!-- 내용 시작 -->
<div class="mb-3 row">
<label for="staticEmail" class="col-sm-2 col-form-label">직원 번호</label>
<div class="col-sm-10">
<input type="text" readonly class="form-control-plaintext" id="empNum" value="">
</div>
</div>
<div class="mb-3 row">
<label for="staticEmail" class="col-sm-2 col-form-label">직원 명</label>
<div class="col-sm-10">
<input type="text" readonly class="form-control-plaintext" id="empNm" value="">
</div>
</div>
<div class="mb-3 row">
<label for="staticEmail" class="col-sm-2 col-form-label">연락처</label>
<div class="col-sm-10">
<input type="text" readonly class="form-control-plaintext" id="empPne" value="">
</div>
</div>
<div class="mb-3 row">
<label for="staticEmail" class="col-sm-2 col-form-label">주소</label>
<div class="col-sm-10">
<input type="text" readonly class="form-control-plaintext" id="empAddr" value="">
</div>
</div>
<div class="mb-3 row">
<label for="staticEmail" class="col-sm-2 col-form-label">급여</label>
<div class="col-sm-10">
<input type="text" readonly class="form-control-plaintext" id="empPay" value="">
</div>
</div>
<div class="mb-3 row">
<label for="staticEmail" class="col-sm-2 col-form-label">매니저</label>
<div class="col-sm-10">
<input type="text" readonly class="form-control-plaintext" id="empMjNm" value="">
</div>
</div>
<!-- 내용 끝 -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$(function(){
// $(document).on("click",".showMj",function(){
$(".showMj").on("click",function(){
console.log("ajax로 매니저 정보 가져와보자");
console.log("요청URI : /emp/showMj");
console.log("요청파라미터(json) : {'empNum':'EMP006'}");
console.log("요청방식 : post");
//this : class="showMj"이 여러개이고, 이 중에서 하나를 클릭한 바로 그 요소
//data-emp-mj-num="EMP006"
let empMjNum = $(this).data("empMjNum");
console.log("empMjNum : " + empMjNum);
//json object
let data = {"empMjNum":empMjNum};
$.ajax({
url:"/emp/showMj",
contentType:"application/json;charset:utf-8",
data:JSON.stringify(data),//마샬링,일렬화(serialization)
type:"post",
dataType:"json",
success:function(result){
//result : {"empNum":"EMP006","empAddr":"12345 제주특별자치도 제주시 첨단로 242 개똥이빌딩 405"
// ,"empPne":"010-123-1234","empNm":"개똥이","empPay":12345,"empMjNum":"EMP002"
// ,"empMjNm":"김철수","serVOList":null}
console.log("result : " + JSON.stringify(result));
$("#empNum").val(result.empNum);
$("#empNm").val(result.empNm);
$("#empPne").val(result.empPne);
$("#empAddr").val(result.empAddr);
$("#empPay").val(result.empPay);
$("#empMjNm").val(result.empMjNm);
}
});
});
});
</script>
우선 DB에 데이터를 넣어보자
SET SERVEROUTPUT ON;
/
DECLARE
BEGIN
FOR I IN 1..123 LOOP
INSERT INTO EMP(EMP_NUM, EMP_ADDR, EMP_PNE, EMP_NM, EMP_PAY, EMP_MJ_NUM)
VALUES(
(SELECT NVL(SUBSTR(MAX(EMP_NUM),1,3),'EMP')
|| TRIM(TO_CHAR(NVL(SUBSTR(MAX(EMP_NUM),4),0) + 1,'000'))
FROM EMP),
'우리집'||I,'010-123-1234','새롬이'||I,100000,'');
END LOOP;
COMMIT;
DBMS_OUTPUT.PUT_LINE('완료');
END;
/
SHOW (화면에 보여질 목록수 변경) on change
<list.jsp>
<label>Show
<!-- 한 화면에 보여질 행의 수 -->
<select
aria-controls="dataTable"
name="show" id="show"
class="custom-select custom-select-sm form-control form-control-sm">
<option value="10" <c:if test="${param.show == 10}">selected</c:if>>10</option>
<option value="25" <c:if test="${param.show == 25}">selected</c:if>>25</option>
<option value="50" <c:if test="${param.show == 50}">selected</c:if>>50</option>
<option value="100" <c:if test="${param.show == 100}">selected</c:if>>100</option></select> entries
</label>
하단에 스크립트 생성
//show가 바뀜
$("#show").on("change",function(){
//currentPage=1&keyword=개똥이&show=10
let currentPage = "${param.currentPage}";
let keyword = "${param.keyword}";
console.log("currentPage : " + currentPage + ", keyword : " + keyword);
let show = $(this).val();
let show2 = $("#show option:selected").val();
let show3 = $("select[name='show']").val();
let show4 = $("#show option").index($("#show option:selected"));
console.log("show : " + show);
location.href="/emp/list?show="+show+"¤tPage=1&keyword="+keyword;
});
고정된다
++ tr의 class odd/even 으로 나누기
++ 화면 밑단에 게시글 개수 보이게 설정
<div class="row">
<div class="col-sm-12 col-md-5">
<div class="dataTables_info" id="dataTable_info" role="status"
aria-live="polite">
<c:if test="${param.show==null}">
<c:set var="show" value="1" />
</c:if>
<c:if test="${param.show!=null}">
<c:set var="show" value="${param.show}" />
</c:if>
<!-- scope(공유영역) : page(기본), request, session, application -->
<!-- 종료행 : currentPage * show -->
<c:set var="endRow" value="${data.currentPage * show}" />
<!-- 시작행 : 종료행 - (size-1) -->
<c:set var="startRow" value="${endRow - (show-1)}" />
<!-- 전체행수 : total -->
<c:if test="${endRow > data.total}">
<c:set var="endRow" value="${data.total}"/>
</c:if>
Showing ${startRow} to ${endRow} of ${data.total} entries
</div>
</div>
'Spring' 카테고리의 다른 글
Spring 21 - 구글차트 구현하기 (0) | 2023.02.10 |
---|---|
Spring 20 - 웹소켓(WebSocket) - 실시간 채팅 (0) | 2023.02.09 |
Spring 18 - Mapper 인터페이스, 스프링 폼 태그 라이브러리, 계층형 쿼리 (0) | 2023.02.06 |
Spring 17 - 데이터베이스 구축부터 CRUD까지 (다음 우편번호 api 활용) (0) | 2023.02.03 |
Spring 16 - LPROD에 파일 다운로드 하기 (0) | 2023.02.02 |