20220905_mon
AJAX
- 페이지 이동없이 디비작업할 때 사용한다.
- DB작업위해 페이지이동 필요시, 로그인 성공 후 alert 띄우고, 게시글 목록페이지로 이동 할 때, 자바스크립트,html 파일 필요한데 ajax 사용시 페이지이동 필요 없다.
<실습내용>
: stu_manamge.html 파일 하나로 ajax를 사용해 페이지이동없이 학생관리 페이지 만든다.
- 프로젝트 실행하면, stu_manage.html에서 학급목록과 학생목록 조회
- 학급별 학생조회
:각 셀렉트박스 해당 학급을 선택시, 해당 학급의 학생만 조회되도록 만든다.- 학생 상세 조회
- 점수 등록,수정,학생 삭제
@GetMapping("/dn")//localhost:8081/stu/dn public String deleteNode() {return "delete_node";}
- 학급이 변경 할 때(셀렉트박스) 진행되는 함수
- 페이지이동이 없는 대신, 조회된 데이터로 테이블을 다시 작성해야한다(ajax단점)
``
백팁 이용해서 문자열 연결
function changeClass() {
//classCode 값 가져오기
// 셀렉트 태그 선택한 것의 value값가져온 것이 classCode
const classCode = document.querySelector('select').value;
//ajax start
//$로시작하는 것은 제이쿼리 문법이다.
$.ajax({
url: '/stu/getStuListAjax', //요청경로
type: 'post',
data: {'classCode':classCode}, //필요한 데이터
//페이지이동이 없는 대신, 조회된 데이터로 테이블을 다시 작성해야한다(ajax단점)
success: function(result) {
//컨트롤러 내용 진행 후, 자동실행 구문
//테이블을 다시 그려야한다
//테이블 선택
//열려있는 html파일(document)에서 테이블 선택
const stuListTable = document.querySelector('.stuListTable');
// 테이블에서 티바디 선택
const tbody = stuListTable.querySelector('tbody');
// 위 코드와 동일 : const tbody = document.querySelector('.stuListTable > tbody');
stuListTable.removeChild(tbody);
/* //()test)
str += 'java';//str = str + 'java'
str += 'c++';//javac++ (문자열 연결)
alert(str);
*/
//(test)추가할 <tbody>태그 생성
let str = '';
str += '<tbody>';
//학생 수만큼만 tr태그 만든다
for(const stu of result){
//`` 백팁 이용해서 문자열 연결 ver.
str += '<tr>';
str += `<td>${stu.stuNum}</td>`;
str += `<td>`;
/* 타임리프 여기서는 해석 x th:text 사용불가 -> ${} 사용 */
str += `<span>${stu.stuName}</span>`;
str += `</td>`;
str += `<td>${stu.stuAge}</td>`;
str += `<td>${stu.className}</td>`;
str += '</tr>';
//'' 홀따옴표 이용 문자열 연결 ver.
/* str += '<tr>';
str += '<td>'+stu.stuNum+'</td>';//학번
str += '<td>'+stu.stuName+'</td>';//이름
str += '<td>'+stu.stuAge+'</td>';//나이
str += '<td>'+stu.className+'</td>';//학급명
str += '</tr>';*/
}
str += '</tbody>';
stuListTable.insertAdjacentHTML('beforeend', str);
},
error: function() {
alert('실패');
}
});
//ajax end
}
onchange 속성 사용
select 값이 바뀔 때마다 "" 실행 :
<select>
<select onchange="changeClass()">
<option value="0">전체</option>
<option th:each="classInfo : ${classList}" th:text="${classInfo.className}" th:value="${classInfo.classCode}"></option>
</select>
<테이블 추가/삭제 연습>
- delete_node.html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"><!-- jsp에서 foreach문 사용할때 lib태그 사용하는 것과 같다.앞으로 html 만들때는 사용해야한다. 원래 html만들때 next누르고 별도로 생성한 htnl_thymeleaf를 선택하면 자동생성된다--> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <!-- 자바스크립트에서는 태그 하나를 노드라고 한다 --> <body> <div> <!-- value값 클릭시 화면에 나타나지는 않지만 p태그가 추가된다 --> <input type="button" value="add_pTag" onclick="addP();"> <input type="button" value="add_pTag_01" onclick="addP2();"> <input type="button" value="remove_pTag" onclick="removeTag();"> </div> <div id="parentDiv"> <!-- <p>태그도 블록태그임(옆에x) --> <p>첫번째 p 태그</p> <p>두번째 p 태그</p> </div> <!-- 자바스크립트 파일 추가 --> <script type="text/javascript" th:src="@{/delete_node.js}"></script> </body> </html>
- delete_node.js
//p태그 추가 //: 버튼 클릭할 때마다 p태그가 하나씩 추가되는 메소드 function addP() { //추가할 p태그를 생성: createElement() const p = document.createElement('p');//<p></p>태그를 만들 뿐 화면에 나타나지는 않는다! //p태그에 정의할 속성 생성: createAttribute() const classAttr = document.createAttribute('class');//class=""까지만 속성 생성 classAttr.value = 'java';//class="java";까지 속성 생성 p.setAttributeNode(classAttr);//위 만든 속성을 p태그에 추가 (화면상 보이지않고 개발자모드로 확인가능) //p태그안에 내용을 적기(화면에 나타남) const text = document.createTextNode('추가된 pTag'); p.appendChild(text);//<p></p>태그 안에 text 값 들어온다 // 생성된 태그 추가 //1) 내가 추가하고 싶은 노드를 먼저 선택해야한다. const div = document.querySelector('#parentDiv');//부모요소 선택 div.appendChild(p);//부모태그의 마지막 자식태그로(p태그) 추가하겠다 } function addp2(){ //내가 만들 태그를 문자열로 만들기 const str = '<p class="java">추가된 p태그</p>'; const div = document.querySelector('#parentDiv');//부모태그 선택 //beforebegin : 선택한 태그(div) 앞에 str 붙이기 //afterbegin : 선택한 태그의 첫번째 자식에 //beforeend :선택한 태그의 마지막 자식에 //afterend :선택한 태그의 뒤에 //insertAdjacentHTML :문자열을 html코드로 자동 전환 div.insertAdjacentHTML('beforeend', str); } //태그 지우기 function removeTag(){ //우선, 부모태그 선택 const div = document.querySelector('#parentDiv'); //#parentDiv에 있는 가장 마지막 p태그를 선택 const lastP = document.querySelector('#parentDiv > p:last-child'); //(1) removeChild():선택한 태그의 자식 태그를 삭제 //div.removeChild(lastP); //(2) remove(): 선택한 태그 및 자식 태그까지 자체를 삭제 div.remove(); }
- 학생목록조회 (조인)
- 선택된 학급의 학생목록 조회하도록 수정한다.
: test="abc"값에 적으면, 넘어오는 매개변수.getAbc()(classCode.getAbc()); 자동호출
하지만 넘어오는 매개변수는 객체가 아니라 int 이기때문에 불가능하다
그래서 _parameter 값으로 코드를 적는다(그냥 넘어오는 데이터 하나의 값)- 컨트롤러에서 가장처음 화면 뜨자마자 실행될 때,
_parameter 가 0으로 들어오기 때문에(전체조회) if문에서 0 값이 아닐 때는 전체조회가 아닌
각 해당 학급별로 학생 목록을 조회한다.
<select id="getStuList" resultMap="stuInfo">
SELECT STU_NUM
, STU_NAME
, STU_AGE
, CLASS_NAME
FROM CLASS_INFO C,STUDENT_INFO S
WHERE C.CLASS_CODE = S.CLASS_CODE
<if test="_parameter != 0">
AND S.CLASS_CODE = #{classCode}
</if>
ORDER BY STU_NUM
</select>
<실습 내용>
- 학생 상세 조회
:좌측화면 학급목록 조회 시, 학생이름을 클릭 했을 때, 우측 화면에 해당 학생의 상세정보를 조회하라- 이름이 아닌 공백을 클릭했을 때도 이동하게 되는 td가 아니라 이름만 클릭했을 때 진행되도로고 span태그를 사용한다
- 이름에 마우스 올리면 커서 변경시키기(css)
- 학급명 변경 후에도 클릭하면 함수 실행안되도록 만들기
- 이름을 클릭하면 상세정보 메소드로 이동
- td태그 안에 말고 span태그안에 속성넣으면 글자만 클릭해야 상세조회 된다!(차이점)
<td><span th:text="${stuInfo.stuName}"></span>
- 손가락모양으로 커서변경
span:hover {cursor: pointer;}
- 우측화면 테이블 ID 값 부여(JS에 코딩)
<td id="detailTd">
- 학급명 변경하면 조회가 안되는 문제점 발생 -> js파일에서 td태그가 아닌 span태그로 문자열 str을 수정해야 학급명 변경시 해당 학급별 조회가능하다.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type="text/css">
.layoutTable{
width: 1000px;
margin: 0 auto;
border: 1px solid black;
border-collapse: collapse;
margin-top: 40px;
text-align: center;
}
.layoutTable > tbody >tr, .layoutTable > tbody > tr >td{
border: 1px solid black;
}
.layoutTable > tbody> tr{/* 자식 */
height: 500px;
}
.layoutTable > tbody> tr > td{/* 자식 */
vertical-align: top;
padding: 20px;
}
.stuListTable, .stuDetailTable{
width: 400px;
border: 1px solid gray;
border-collapse: collapse;
margin: 0 auto;
text-align: center;
}
.stuListTable tr,.stuListTable td{/* 자손 */
border: 1px solid gray;
}
.stuDetailTable tr,.stuDetailTable td{/* 자손 */
border: 1px solid gray;
}
span:hover {
cursor: pointer;/* 손가락모양으로 커서변경 */
}
</style>
</head>
<body>
<table class="layoutTable">
<colgroup>
<col width="50%">
<col width="50%">
</colgroup>
<tr>
<td>
<div style="margin-bottom: 10px;" align="center">
<!-- onchange : select 값이 바뀔 때마다 "" 실행 -->
<select onchange="changeClass()">
<option value="0">전체</option>
<option th:each="classInfo : ${classList}" th:text="${classInfo.className}" th:value="${classInfo.classCode}"></option>
</select>
</div>
<div>
<!-- 화면이 뜨자마자 이 테이블은 없다. 이름을 클릭해야만 화면에 보인다 -->
<table class="stuListTable">
<thead>
<tr>
<td>학번</td>
<td>이름</td>
<td>나이</td>
<td>학급명</td>
</tr>
</thead>
<tbody>
<th:block th:each="stuInfo : ${stuList}" >
<tr>
<td th:text="${stuInfo.stuNum}" ></td>
<!-- 이름을 클릭하면 상세정보 메소드로 이동 -->
<!-- td태그 안에 말고 span태그안에 속성넣으면 글자만 클릭해야 상세조회 된다!(차이점) -->
<td>
<span th:text="${stuInfo.stuName}" onclick="showDetail();"></span>
</td>
<td th:text="${stuInfo.stuAge}" ></td>
<td th:text="${stuInfo.ClassName}" ></td>
</tr>
</th:block>
</tbody>
</table>
</div>
</td>
<!-- 우측화면 테이블 ID 값 부여(JS에 코딩) -->
<td id="detailTd">
</td>
</tr>
</table>
<!-- jquery 문법 로딩 -->
<script src="https://code.jquery.com/jquery-latest.min.js"></script>
<!-- 자바스크립트 파일과연결 -->
<script type="text/javascript" th:src="@{/stu_manage.js}"></script>
</body>
</html>
//학급이 변경 할 때(셀렉트박스) 진행되는 함수
function changeClass() {
//classCode 값 가져오기
// 셀렉트 태그 선택한 것의 value값가져온 것이 classCode
const classCode = document.querySelector('select').value;
//ajax start
//$로시작하는 것은 제이쿼리 문법이다.
$.ajax({
url: '/stu/getStuListAjax', //요청경로
type: 'post',
data: {'classCode':classCode}, //필요한 데이터
//페이지이동이 없는 대신, 조회된 데이터로 테이블을 다시 작성해야한다(ajax단점)
success: function(result) {
//컨트롤러 내용 진행 후, 자동실행 구문
//테이블을 다시 그려야한다
//테이블 선택
//열려있는 html파일(document)에서 테이블 선택
const stuListTable = document.querySelector('.stuListTable');
// 테이블에서 티바디 선택
const tbody = stuListTable.querySelector('tbody');
// 위 코드와 동일 : const tbody = document.querySelector('.stuListTable > tbody');
stuListTable.removeChild(tbody);
/* //()test)
str += 'java';//str = str + 'java'
str += 'c++';//javac++ (문자열 연결)
alert(str);
*/
//(test)추가할 <tbody>태그 생성
let str = '';
str += '<tbody>';
//학생 수만큼만 tr태그 만든다
for(const stu of result){
//`` 백팁 이용해서 문자열 연결 ver.
str += '<tr>';
str += `<td>${stu.stuNum}</td>`;
str += `<td>`;
/* 타임리프 여기서는 해석 x th:text 사용불가 -> ${} 사용 */
str += `<span>${stu.stuName}</span>`;
str += `</td>`;
str += `<td>${stu.stuAge}</td>`;
str += `<td>${stu.className}</td>`;
str += '</tr>';
//'' 홀따옴표 이용 문자열 연결 ver.
/* str += '<tr>';
str += '<td>'+stu.stuNum+'</td>';//학번
str += '<td>'+stu.stuName+'</td>';//이름
str += '<td>'+stu.stuAge+'</td>';//나이
str += '<td>'+stu.className+'</td>';//학급명
str += '</tr>';*/
}
str += '</tbody>';
stuListTable.insertAdjacentHTML('beforeend', str);
},
error: function() {
alert('실패');
}
});
//ajax end
}
// 이름을 클릭했을 시, 학생 상세정보 조회
function showDetail() {
let str='';
/*html에서 나타날 코드 여기 작성 */
str += '<table class = "stuDetailTable">';
str += '<tr>';
str += '<td>학생번호</td>';
str += '<td>학생이름</td>';
str += '<td>소속 학급명</td>';
str += '</tr>';
str += '<tr>';
str += '<td>10</td>';
str += '<td>mark</td>';
str += '<td>java</td>';
str += '</tr>';
str += '<tr>';
str += '<td>국어점수</td>';
str += '<td>영어점수</td>';
str += '<td>수학점수</td>';
str += '</tr>';
str += '<tr>';
str += '<td>0</td>';
str += '<td>0</td>';
str += '<td>0</td>';
str += '</tr>';
str += '</table>';
const detailTd = document.querySelector('#detailTd');
//빈값으로 바꾸고 붙이기를 반복한다
//innerHTML : 선택한 태그에 빈문자를 주면 선택태그 안의 내용 모두 삭제
detailTd.innerHTML= '';
//insertAdjacentHTML('(위치)', 넣을 문자) : 뒤에 문자열을 어느 위치에 넣을지
detailTd.insertAdjacentHTML('beforeend',str);
}