D+50::Ajax_학생관리페이지만들기/자바스크립트_노드추가/삭제

Am.Vinch·2022년 9월 5일
0
post-thumbnail

20220905_mon

AJAX

  • 페이지 이동없이 디비작업할 때 사용한다.
  • DB작업위해 페이지이동 필요시, 로그인 성공 후 alert 띄우고, 게시글 목록페이지로 이동 할 때, 자바스크립트,html 파일 필요한데 ajax 사용시 페이지이동 필요 없다.

<실습내용>
: stu_manamge.html 파일 하나로 ajax를 사용해 페이지이동없이 학생관리 페이지 만든다.

  • 프로젝트 실행하면, stu_manage.html에서 학급목록과 학생목록 조회
  • 학급별 학생조회
    :각 셀렉트박스 해당 학급을 선택시, 해당 학급의 학생만 조회되도록 만든다.
  • 학생 상세 조회
  • 점수 등록,수정,학생 삭제

  • stu_controller
    :연습용 메소드를 하나 추가한다
    @GetMapping("/dn")//localhost:8081/stu/dn public String deleteNode() {return "delete_node";}

  • stu_manage.js 파일 생성(template 폴더)
    • 학급이 변경 할 때(셀렉트박스) 진행되는 함수
    • 페이지이동이 없는 대신, 조회된 데이터로 테이블을 다시 작성해야한다(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
}
  • stu_manage.html

    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();
}

  • student-mapper
  • 학생목록조회 (조인)
  • 선택된 학급의 학생목록 조회하도록 수정한다.
    : 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을 수정해야 학급명 변경시 해당 학급별 조회가능하다.

  • stu_manage.html
<!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>

  • stu_manage.js
//학급이 변경 할 때(셀렉트박스) 진행되는 함수
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);

}
profile
Dev.Vinch

0개의 댓글