Spring

채상혁·2022년 2월 21일
0

Spring

목록 보기
18/18
post-custom-banner

스프링 snsList 마무리.

<script>
	
	$(function() {
		
		//등록하기 버튼 클릭 이벤트
		$('#uploadBtn').click(function() {
			regist();
		});
		
		//등록을 담당하는 함수
		function regist() {
			//세션에서 현재 로그인 중인 사용자 정보(아이디)를 얻어오자
			const user_id = '${sessionScope.login.userId}';
			//자바스크립트의 파일 확장자 체크 검색.
			let file = $('#file').val();
			
			console.log(user_id);
			console.log(file);
			//.을 제거한 확장자만 얻어낸 후 그것을 소문자로 일괄 변경
			file = file.slice(file.indexOf('.') + 1).toLowerCase();
			console.log(file);
			if(file !== 'jpg' && file !== 'png' && file !== 'jpeg' && file !== 'bmp') {
				alert('이미지 파일(jpg, png, jpeg, bmp)만 등록이 가능합니다.');
				$('#file').val('');
				return;
			} else if(user_id === '') { //세션 데이터가 없다 -> 로그인 x
				alert('로그인이 필요한 서비스입니다.');
				return;
			}
			
			//ajax 폼 전송의 핵심 FormData 객체.
			const formData = new FormData();
			const data = $('#file');
			
			console.log('폼 데이터: ' + formData);
			console.log('data: ' + data);
			console.log(data[0]);
			console.log(data[0].files); //파일 태그에 담긴 파일 정보를 확인하는 키값.
			console.log(data[0].files[0]);
			
			//data[index] -> 파일 업로드 버튼이 여러 개 존재할 경우 요소의 인덱스를 지목해서 가져오는 법.
			//우리는 요소를 id로 취득했기 때문에 하나만 찍히지만, class이름 같은거로 지목하면 여러개가 취득되겠죠?
			//files[index] -> 파일이 여러개 전송되는 경우, 몇 번째 파일인지를 지목.
			//우리는 multiple 속성을 주지 않았기 때문에 0번 인덱스 밖에 없는 겁니다.
			
			//FormData 객체에 사용자가 업로드한 파일의 정보들이 들어있는 객체를 전달.
			formData.append('file', data[0].files[0]);
			//content(글 내용) 값을 얻어와서 폼 데이터에 추가
			const content = $('#content').val();
			formData.append('content', content);
			
			//비동기 방식으로 파일 업로드 및 게시글 등록을 진행.
			$.ajax({
				url: '<c:url value="/snsBoard/upload" />',
				type: 'post',
				data: formData, //폼데이터 객체를 넘깁니다.
				contentType: false, //ajax 방식에서 파일을 넘길때는 반드시 false로 처리 -> "multipart/form-data"로 선언됨.
				processData: false, //폼 데이터를 &변수=값&변수=값... 형식으로 변경되는 것을 막는 요소.
				success: function(result) {
					if(result === 'success') {
						$('#file').val(''); //파일선택지 비우기
						$('#content').val(''); //글 영역 비우기
						$('.fileDiv').css('display', 'none'); //미리보기 감추기
						getList(1, true); //글 목록을 호출
					} else {
						alert('업로드에 실패했습니다. 관리자에게 문의해 주세요.');
					}
				},
				error: function(request, status, error) {
					console.log('code: ' + request + '\n' + 'message: ' + request.responseText + '\n' + 'error: ' + error);
					alert('업로드에 실패했습니다. 관리자에게 문의해 주세요.');
				}
				
			}); //end ajax
					
		} //end regist()
		
		//리스트 작업
		let str = '';
		let page = 1;
		getList(1, true);
		
		function getList(page, reset) {
			if(reset === true) {
				str = ''; //화면 리셋 여부가 true라면 str변수를 초기화.
			}
			
			$.getJSON(
				'<c:url value="/snsBoard/getList?pageNum=' + page + '" />',
				function(list) {
					console.log(list);
					
					for(let i=0; i<list.length; i++) {
						str += "<div class='title-inner'>";
	                     str += "<div class='profile'>";
	                     str += "<img src='../resources/img/profile.png' >";    
	                     str += "</div>";
	                     str += "<div class='title'>";
	                     str += "<p>"+ list[i].writer +"</p>";
	                     str += "<small>"+ timeStamp(list[i].regdate) +"</small> &nbsp;&nbsp;";
	                     
	                     //파일다운로드
	                     str += "<a href='download?fileLoca=" + list[i].fileloca +  "&fileName=" + list[i].filename + "'>이미지 다운로드</a>";
	                     //파일다운로드끝
	                     
	                     str += "</div>";
	                     str += "<div class='content-inner'>"
	                     str += "<p>"+ (list[i].content === null ? '' : list[i].content) +"</p>";
	                     str += "</div>";
	                     /* 이미지 영역 */
	                     str += "<div class='image-inner'>";
	                     str += "<a href='" + list[i].bno + "'>"; ///////추가
	                     str += "<img src='display?fileLoca=" + list[i].fileloca + "&fileName=" + list[i].filename +"'>";
	                     str += "</a>" ////////추가
	                     str += "</div>";
	                     str += "<div class='like-inner'>";                   
	                     str += "<img src='../resources/img/like.png'><span>522</span>";                  
	                     str += "</div>";
	                     str += "<div class='link-inner'>";                     
	                     str += "<a href='##'><i class='glyphicon glyphicon-thumbs-up'></i>좋아요</a>";
	                     str += "<a href='##'><i class='glyphicon glyphicon-comment'></i>댓글달기</a>";
	                     str += "<a href='" + list[i].bno + "'><i class='glyphicon glyphicon-remove'></i>삭제하기</a>";
	                     str += "</div>";
	                     $('#contentDiv').html(str);
					}
					
				}
					
			); //end getJSON
			
		} //end getList()
		
		
		//상세보기 처리 (모달창 열어줄 겁니다.)
		$('#contentDiv').on('click', '.image-inner a', function(e) {
			e.preventDefault();
			
			//글 번호 얻어오기
			const bno = $(this).attr('href');
			
			$.getJSON(
				"<c:url value='/snsBoard/getDetail/' />" + bno,
				function(data) {
					console.log(data);
					
					const img = 'display?fileLoca=' + data.fileloca + '&fileName=' + data.filename;
					$('#snsImg').attr('src', img); //이미지 경로 처리
					$('#snsWriter').html(data.writer); //작성자 처리
					$('#snsRegdate').html(timeStamp(data.regdate)); //날짜 처리
					$('#snsContent').html(data.content); //내용 처리
					$('#snsModal').modal('show'); //모달 열기
				}
			);
			
		}); //상세보기 이벤트 끝.
		
		//삭제 처리
		//삭제하기 링크를 클릭했을 때 이벤트를 발생 시켜서
		//비동기 방식으로 삭제를 진행해 주세요. (삭제 버튼은 한 화면에 여러개 겠죠?)
		//서버쪽에서 권한을 확인 해 주세요. (작성자와 로그인 중인 사용자의 id를 비교해서)
		//일치하지 않으면 문자열 "noAuth" 리턴, 성공하면 "Success" 리턴.
		// url: /snsBoard/delete, method: post
		$('#contentDiv').on('click', '.link-inner a', function(e) {
			e.preventDefault();
			
			const bno = $(this).attr('href');
			
			$.ajax({
				type: "post",
				url: "<c:url value='/snsBoard/delete' />",
				data: bno,
				contentType: 'application/json',
				success: function(result) {
					if(result === 'noAuth') {
						alert('권한이 없습니다.');
					} else if(result === 'fail') {
						alert('삭제에 실패했습니다. 관리자에게 문의하세요.');
					} else {
						alert('게시물이 정상적으로 삭제되었습니다.');
						getList(1, true); //삭제가 반영된 글 목록을 새롭게 보여줘야 하기 때문에 str을 초기화. 
					}
				},
				error: function() {
					alert('삭제에 실패했습니다. 다시 시도하세요.');
				}
			});
			
		});
		
		
		//무한 스크롤
		
		$(window).scroll(function() {
			//윈도우(device)의 높이와 현재 스크롤 위치 값을 더한 뒤, 문서(컨턴츠) 높이와 비교해서 같다면 로직을 수행.
			//문서 높이 - 브라우저 창 높이 = 스크롤 창의 끝 높이와 같다면 -> 새로운 내용을 불러오자.
			if(Math.round($(window).scrollTop()) === $(document).height() - $(window).height()) {
				//console.log(++page);
				//$('#contentDiv').append("<h1> Page: " + page + "</h1>");
				//$('#contentDiv').append("<br>무한<br>페이징<br>로드<br>중입니다~~~<br><br>무한<br>페이징<br>로드<br>중입니다~~~<br><br>무한<br>페이징<br>로드<br>중입니다~~~<br><br>무한<br>페이징<br>로드<br>중입니다~~~<br>");
			
				//목록 불러오기의 sql문을 페이징 쿼리를 사용해서 작성을 해 주시는 겁니다.
				//사용자의 스크롤이 바닥에 닿았을 때, 페이지 변수의 값을 하나 올리고
				//getList(false)를 주셔서 누적해서 계속 열어 주시면 됩니다.
				//게시글을 몇 개씩 불러 올지는 페이징 알고리즘에서 알아서 정해 주시면 됩니다.
				getList(++page, false);
			
			}
			
		});
		
		
		
		
	}); //end jQuery
	
	
	// 날짜 처리 함수
	function timeStamp(millis) {
		
		const date = new Date(); //현재 날짜
		//현재 날짜를 밀리초로 변환 - 등록일 밀리초 -> 시간차
		const gap = date.getTime() - millis;
		
		let time; //리턴할 시간
		if(gap < 60 * 60 * 24 * 1000) { //1일 미만인 경우
			if(gap < 60 * 60 * 1000) { //1시간 미만일 경우
				time = '방금 전';
			} else { //1시간 이상일 경우
				time = parseInt(gap / (1000 * 60 * 60)) + '시간 전';
			}
		} else { //1일 이상일 경우
			const today = new Date(millis);
			const year = today.getFullYear(); //년
			const month = today.getMonth() + 1; //월
			const day = today.getDate(); //일
			const hour = today.getHours(); //시
			const minute = today.getMinutes(); //분
			
			time = year + '년 ' + month + '월 ' + day + '일 ' + hour + '시 ' + minute + '분'; 
			
		}
		return time;
	}
	
	
	
		//자바 스크립트 파일 미리보기 기능
		function readURL(input) {
        	if (input.files && input.files[0]) {
        		
            	var reader = new FileReader(); //비동기처리를 위한 파읽을 읽는 자바스크립트 객체
            	//readAsDataURL 메서드는 컨텐츠를 특정 Blob 이나 File에서 읽어 오는 역할 (MDN참조)
	        	reader.readAsDataURL(input.files[0]); 
            	//파일업로드시 화면에 숨겨져있는 클래스fileDiv를 보이게한다
	            $(".fileDiv").css("display", "block");
            	
            	reader.onload = function(event) { //읽기 동작이 성공적으로 완료 되었을 때 실행되는 익명함수
                	$('#fileImg').attr("src", event.target.result); 
                	console.log(event.target)//event.target은 이벤트로 선택된 요소를 의미
	        	}
        	}
	    }
		$("#file").change(function() {
	        readURL(this); //this는 #file자신 태그를 의미
	        
	    });
		
		
		
		
		
		
		
		
		
		
		
		
		
		
	</script>
post-custom-banner

0개의 댓글