AJAX - CRUD

sql문

테스트

1개의 데이터를 oracle로 insert하고 잘 들어갔는지 확인 -> Memolist.jsp에서 테스트

전체 목록 가져오기

Dao에 테이블 값 가져오는 메서드 작성 후 실행

List<MemoDto> list=dao.getAllMemos();

json형태 배열 변환

가져온 데이터를 json 형태의 배열로 만들어주기 위해 생성

JSONArray arr=new JSONArray();

size 확인

arr의 값을 확인해 sql문을 잘 가져왔는지 확인 작업

//arr에 먼저 size 보내보기
//sql에 적은 데이터 잘 들어갔는지 확인 하는 작업 1(테이블 안에 행 갯수)이 뜸
/*JSONObject size=new JSONObject();
size.put("size", list.size());
arr.add(size);*/

dto로 받아오기

모든 값들을 json형태로 변환해주기 위해 행 값을 하나씩 넣어주고 json형식의 배열로 만들어주기 위해 배열에 넣음

->Memolist에서 run as 해서 json형태의 배열로 잘 나왔는지 확인

for(MemoDto dto:list)
{
	JSONObject ob=new JSONObject();
	ob.put("num",dto.getNum());
	ob.put("writer",dto.getWriter());
	ob.put("story",dto.getStory());
	ob.put("avata",dto.getAvata());
	ob.put("writeday",sdf.format(dto.getWriteday()));
		
	//arr에 추가
	arr.add(ob);
}

sql문

create table memo(num number(5) primary key,
writer varchar2(50),
story varchar2(1000),
avata varchar2(50),
writeday date);


--list 잘 뜨는지 확인하기 위해 1개의 데이터를 넣어서 테스트해야한다
insert into memo values(seq_1.nextval,'최성현','잘 놀다 갑니다','../image/01.png',sysdate);


commit;

memolist.jsp

<%@page import="java.text.SimpleDateFormat"%>
<%@page import="org.json.simple.JSONObject"%>
<%@page import="org.json.simple.JSONArray"%>
<%@page import="db.memo.MemoDto"%>
<%@page import="java.util.List"%>
<%@page import="db.memo.MemoDao"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%-- json --%>
<%
	MemoDao dao=new MemoDao();

	//전체목록을 가져온다
	List<MemoDto> list=dao.getAllMemos();
	//json형태 배열로 만들어줌
	JSONArray arr=new JSONArray();
	//arr에 먼저 size 보내보기
	//sql에 적은 데이터 잘 들어갔는지 확인 하는 작업 1(테이블 안에 행 갯수)이 뜸
	/*JSONObject size=new JSONObject();
	size.put("size", list.size());
	arr.add(size);*/
	
	SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm");
	for(MemoDto dto:list)
	{
		JSONObject ob=new JSONObject();
		ob.put("num",dto.getNum());
		ob.put("writer",dto.getWriter());
		ob.put("story",dto.getStory());
		ob.put("avata",dto.getAvata());
		ob.put("writeday",sdf.format(dto.getWriteday()));
		
		//arr에 추가
		arr.add(ob);
	}
%>
<%-- 문자열변환 --%>
<%=arr.toString()%>

DBConnect 생략

MemoDto.java

package db.memo;

import java.sql.Timestamp;

public class MemoDto {
	
	private String num;
	private String writer;
	private String story;
	private String avata;
	private Timestamp writeday;
	
	
	public String getNum() {
		return num;
	}
	public void setNum(String num) {
		this.num = num;
	}
	public String getWriter() {
		return writer;
	}
	public void setWriter(String writer) {
		this.writer = writer;
	}
	public String getStory() {
		return story;
	}
	public void setStory(String story) {
		this.story = story;
	}
	public String getAvata() {
		return avata;
	}
	public void setAvata(String avata) {
		this.avata = avata;
	}
	public Timestamp getWriteday() {
		return writeday;
	}
	public void setWriteday(Timestamp writeday) {
		this.writeday = writeday;
	}	
}

MemoDao.java

package db.memo;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Vector;

import oracle_db.DBConnect;

public class MemoDao {

	DBConnect db=new DBConnect();
	
	//추가
	public void insertMemo(MemoDto dto)
	{
		Connection conn=db.getConnection();
		PreparedStatement pstmt=null;
		
		String sql="insert into memo values(seq_1.nextval,?,?,?,sysdate)";
		
		try {
			pstmt=conn.prepareStatement(sql);
			pstmt.setString(1, dto.getWriter());
			pstmt.setString(2, dto.getStory());
			pstmt.setString(3, dto.getAvata());
			pstmt.execute();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			db.dbClose(pstmt, conn);
		}
	}
	
	//조회
	public List<MemoDto> getAllMemos()
	{
		List<MemoDto> list=new Vector<MemoDto>();
		
		Connection conn=db.getConnection();
		PreparedStatement pstmt=null;
		ResultSet rs=null;
		
		String sql="select * from memo order by num desc";
		
		try {
			pstmt=conn.prepareStatement(sql);
			rs=pstmt.executeQuery();
			
			while(rs.next())
			{
				MemoDto dto=new MemoDto();
				
				dto.setNum(rs.getString("num"));
				dto.setWriter(rs.getString("writer"));
				dto.setStory(rs.getString("story"));
				dto.setAvata(rs.getString("avata"));
				dto.setWriteday(rs.getTimestamp("writeday"));
				
				list.add(dto);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			db.dbClose(rs, pstmt, conn);
		}
		return list;
	}
	
	public void deleteMemo(String num)
	{
		Connection conn=db.getConnection();
		PreparedStatement pstmt=null;
		
		String sql="delete from memo where num=?";
		
		try {
			pstmt=conn.prepareStatement(sql);
			pstmt.setString(1, num);
			pstmt.execute();
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			db.dbClose(pstmt, conn);
		}
	}
	
	//num에 해당하는 dto반환
	public MemoDto getData(String num)
	{
		MemoDto dto=new MemoDto();
		
		Connection conn=db.getConnection();
		PreparedStatement pstmt=null;
		ResultSet rs=null;
		
		String sql="select * from memo where num=?";
		
		try {
			pstmt=conn.prepareStatement(sql);
			pstmt.setString(1, num);
			rs=pstmt.executeQuery();
			
			if(rs.next())
			{
				dto.setNum(rs.getString("num"));
				dto.setWriter(rs.getString("writer"));
				dto.setStory(rs.getString("story"));
				dto.setAvata(rs.getString("avata"));
				dto.setWriteday(rs.getTimestamp("writeday"));
			}
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			db.dbClose(rs, pstmt, conn);
		}
		
		return dto;
	}
	
	public void updateMemo(MemoDto dto)
	{
		Connection conn=db.getConnection();
		PreparedStatement pstmt=null;
		
		String sql="update memo set writer=?,story=?,avata=? where num=?";
		
		try {
			pstmt=conn.prepareStatement(sql);
			pstmt.setString(1, dto.getWriter());
			pstmt.setString(2, dto.getStory());
			pstmt.setString(3, dto.getAvata());
			pstmt.setString(4, dto.getNum());
			pstmt.execute();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			db.dbClose(pstmt, conn);
		}
	}
}

memo.html

모든 폼과 액션들이 여기서 행해진다 (액션은 따로 만들어서 불러옴)

insertForm

style을 주는 이유는 위치를 잡아주기 위해서 body에 모든 폼 액션 이곳에 작성

id

각 폼에 id를 준 이유는 각각의 요소를 지정할 수 있어서

textarea

textarea는 나중에 수정할 때도 태그 사이에서만 수정 가능 원래는 colspan줘서 th없이 메모장 작성 가능하게 만듦

<tr>
	<th style="background-color: #00bfff; width: 120px;">메모</th>
	<td>
	<!-- textarea는 나중에 수정할 때도 태그 사이에서만 수정 가능
		 원래는 colspan줘서 th없이 메모장 작성 가능하게 만듦 -->
		<textarea class="form-control"
		name="story" id="story" style="width: 270px; height: 150px; font-size: 1.1em;"></textarea>
	</td>
</tr>
  • insertform
<body>
	<!--style을 주는 이유는 위치를 잡아주기 위해서
		모든 폼 액션 이곳에 작성-->
<div class="memo button">
	<button type="button" class="btn btn-info"
	id="btnadd">메모추가</button>
</div>

<!-- id를 준 이유는 각각의 요소를 지정할 수 있어서
	 insertForm -->
<div class="memo addform">
	<form id="addfrm">
		<table class="table table-bordered">
			<tr>
				<th style="background-color: #00bfff; width: 120px;">작성자</th>
				<td>
					<input type="text" class="form-control"
					name="writer" id="writer" style="width: 120px;">
				</td>
			</tr>
			
			<tr>
				<th style="background-color: #00bfff; width: 120px;">메모</th>
				<td>
					<!-- textarea는 나중에 수정할 때도 태그 사이에서만 수정 가능
						 원래는 colspan줘서 th없이 메모장 작성 가능하게 만듦 -->
					<textarea class="form-control"
					name="story" id="story" style="width: 270px; height: 150px; font-size: 1.1em;"></textarea>
				</td>
			</tr>
			
			<tr>
				<th style="background-color: #00bfff; width: 120px;">아바타</th>
				<td>
					<!-- type이 text면 번호 매겨지기 때문에 hidden으로 적용 -->
					<input type="hidden" name="avata" id="avata">
					<script>
						// 사진 5개 1줄로 넣기
						var s="";
						for(var i=1;i<=10;i++)
						{
							s+="<img src='../image/b"+i+".png' width='50' class='avata'>"
							if(i%5==0)
							{
								s+="<br>"
							}
						}
						document.write(s);
					</script>
				</td>
			</tr>
			<tr>
				<td colspan="2" align="center" style="cursor: pointer; background-color: #00bfff;"
				class="dbsave">
					DB에 저장하기
				</td>
			</tr>
		</table>
	</form>
</div>

사용자함수(list)

script는 이벤트 줄 것이 많아서
사용자함수(호출용)은 function 밖에 있어야해서 따로 만듦

alert

로딩,클릭 등등 특정 상황마다 확인하기

function list(){
		
		$.ajax({
			type:"get",
			dataType:"json",
			url:"memolist.jsp",
			success:function(data){
				
				//로딩,클릭 등등 특정 상황마다 확인하기
				//alert(data.length);
                var s="";

데이터가 없다면

	//데이터가 없다면
	if(data.length==0)
	{
		s+="<h3 class= 'alert alert-info'>저장된 메모가 없습니다</h3>";
	}

데이터 출력

넘어오는 데이터는 배열식으로 넘어오기 때문에 $.each

$.each(data,function(i,elt){

날짜 시간 등등

//날짜 시간 등등 span태그로 들어감 (옆으로 조그맣게 넣을 수 있음)

s+="<span class='mod' num='"+elt.num+"'>수정/</span>"
s+="<span class='del' num='"+elt.num+"'>삭제</span>"

pre 태그

자체적으로 엔터 먹는 태그

//자체적으로 엔터 먹는 태그
s+="<pre>"+elt.story;
s+="<img src='"+elt.avata+"' align='right' width='80'>";
s+="</pre>";
  • 데이터 출력
				else
				{
					//넘어오는 데이터는 배열식으로 넘어오기 때문에 $.each
					$.each(data,function(i,elt){
						
						s+="<table class='table'>";
						s+="<tr><td>";
						//날짜 시간 등등 span태그로 들어감 (옆으로 조그맣게 넣을 수 있음)
						s+="<span class='writer'>작성자:"+elt.writer+"</span>";
						s+="<span class='writeday'>"+elt.writeday+"</span>";
						//수정 버튼에 시퀀스 가져와야함
						s+="<span class='mod' num='"+elt.num+"'>수정/</span>"
						s+="<span class='del' num='"+elt.num+"'>삭제</span>"
						s+="<br>";
						//자체적으로 엔터 먹는 태그
						s+="<pre>"+elt.story;
						s+="<img src='"+elt.avata+"' align='right' width='80'>";
						s+="</pre>";
						s+="</td><tr>";
						s+="</table><br>";
					});
				}
				$("div.list").html(s);
			}
		})
	}
  • 사용자함수...list
	//사용자함수...list
	//script는 이벤트 줄 것이 많아서 //사용자함수(호출용)은 function 밖에 있어야해서 따로 만듦
	function list(){
		
		$.ajax({
			type:"get",
			dataType:"json",
			url:"memolist.jsp",
			success:function(data){
				
				//로딩,클릭 등등 특정 상황마다 확인하기
				//alert(data.length);
				var s="";
				//데이터가 없다면
				if(data.length==0)
				{
					s+="<h3 class= 'alert alert-info'>저장된 메모가 없습니다</h3>";
				}
				else
				{
					//넘어오는 데이터는 배열식으로 넘어오기 때문에 $.each
					$.each(data,function(i,elt){
						
						s+="<table class='table'>";
						s+="<tr><td>";
						//날짜 시간 등등 span태그로 들어감 (옆으로 조그맣게 넣을 수 있음)
						s+="<span class='writer'>작성자:"+elt.writer+"</span>";
						s+="<span class='writeday'>"+elt.writeday+"</span>";
						//수정 버튼에 시퀀스 가져와야함
						s+="<span class='mod' num='"+elt.num+"'>수정/</span>"
						s+="<span class='del' num='"+elt.num+"'>삭제</span>"
						s+="<br>";
						//자체적으로 엔터 먹는 태그
						s+="<pre>"+elt.story;
						s+="<img src='"+elt.avata+"' align='right' width='80'>";
						s+="</pre>";
						s+="</td><tr>";
						s+="</table><br>";
					});
				}
				$("div.list").html(s);
			}
		})

insert폼 띄우고 꾸미기

첫 로딩시 만든 폼을 출력(호출)

	$(function(){
		
		//처음 로딩시 목록 출력하기 (호출해야함)
		list();

로딩후 아무 것도 없게 만들기

버튼 이벤트로 띄우기 위해서 함

//로딩 됐을때 아무 것도 없어야함
$("div.addform").hide();
$("div.updateform").hide();

메모추가 이벤트

메모추가 버튼 누르면 addform 나타나기

//메모추가 버튼 누르면 addform 나타나기
$("#btnadd").click(function(){
	$("div.addform").slideToggle();
})

사진 선택 효과

만든 클래스를 넣어서 사진이 선택된 효과를 줌

//아바타 2번인덱스에 select클래스 추가
$("img.avata:eq(2)").addClass("select");

초기 선택된 사진 효과

아바타 2번인덱스에 src값을 얻어서 input태그에 넣어주기
input태그를 통해 db에 넣어주기 때문에 넣어줘야함

/아바타 2번인덱스에 src값을 얻어서 input태그에 넣어주기
//input태그를 통해 db에 넣어주기 때문에 넣어줘야함
//avata라는 id에 img.avata의 2번 인덱스 src값을 추출해서 그 벨류 값을 넣어준다
$("#avata").val($("#img.avata").eq(2).attr("src"));

사진 선택 이벤트

아바타(사진) 선택하면 값이 변경되어야함

		$("img.avata").each(function(){
			$(this).click(function(){
				$(this).addClass("select");
				$(this).siblings().removeClass("select");
				$("#avata").val($(this).attr("src"));
			})
		})
  • insert폼 띄우기
	$(function(){
		
		//처음 로딩시 목록 출력하기 (호출해야함)
		list();
		
		//로딩 됐을때 아무 것도 없어야함
		$("div.addform").hide();
		$("div.updateform").hide();
		
		//메모추가 버튼 누르면 addform 나타나기
		$("#btnadd").click(function(){
			$("div.addform").slideToggle();
		})
		
		//아바타 2번인덱스에 select클래스 추가
		$("img.avata:eq(2)").addClass("select");
		
		//아바타 2번인덱스에 src값을 얻어서 input태그에 넣어주기
		//input태그를 통해 db에 넣어주기 때문에 넣어줘야함
		//avata라는 id에 img.avata의 2번 인덱스 src값을 추출해서 그 벨류 값을 넣어준다
		$("#avata").val($("#img.avata").eq(2).attr("src"));
		
		//아바타 선택하면 값이 변경되어야함
		$("img.avata").each(function(){
			$(this).click(function(){
				$(this).addClass("select");
				$(this).siblings().removeClass("select");
				$("#avata").val($(this).attr("src"));
			})
		})

db insert

저장용(insert)..추가성공시 list(); 호출 -> memoinsert.jsp와 연결 되어있음

insertform의 모든 값 가져오기

id addfrm인 곳의 모든 태그 불러오기

alert는 값을 잘 가져오는지 확인용

//id addfrm인 곳의 모든 태그 불러오기
var data=$("#addfrm").serialize();
//alert(data);

db저장/저장한 정보 list 띄우기

memoinsert에 엔코딩해서 post가능
보안성과 대용량의 데이터를 보낼때 post 사용

data type

받아오는 json값이 없기 때문에 html(return 값이 없다)

var data

모든 태그를 가져와서 변수로 data:변수로 지정 가능

  • db저장/저장한 정보 list 띄우기
			//db에 저장하면서 list에 저장한 정보 띄우기
			$.ajax({
				//memoinsert에 엔코딩해서 post가능
				//보안성과 대용량의 데이터를 보낼때 post 사용
				type:"post",
				//출력만해서 html
				dataType:"html",
				url:"memoinsert.jsp",
				//위에 var data는 모든 태그를 가져와서 변수로 data:변수로 지정 가능
				data:data,
				success:function(){
				
					list();

list 출력 후 모든 값들 초기화

추가 성공시 다시 목록 출력
입력값 지우기...초기화

$("#writer").val(" ");
$("#story").val(" ");

선택된 아바타 클래스 제거

$("img.avata").removeClass("select");

다시 초기값 입력

//아바타 2번인덱스에 select클래스 추가
$("img.avata:eq(2)").addClass("select");
//아바타 2번인덱스에 src값을 얻어서 input태그에 넣어주기
$("#avata").val($("#img.avata").eq(2).attr("src"));

작성자창으로 자동으로 이동하기

//작성자창으로 자동으로 이동하기
$("#writer").focus();
  • db insert
		//저장용(insert)..추가성공시 list(); 호출
		$("td.dbsave").click(function(){
			
			//id addfrm인 곳의 모든 태그 불러오기
			var data=$("#addfrm").serialize();
			//alert(data);
			
			//db에 저장하면서 list에 저장한 정보 띄우기
			$.ajax({
				//memoinsert에 엔코딩해서 post가능
				//보안성과 대용량의 데이터를 보낼때 post 사용
				type:"post",
				//출력만해서 html
				dataType:"html",
				url:"memoinsert.jsp",
				//위에 var data는 모든 태그를 가져와서 변수로 data:변수로 지정 가능
				data:data,
				success:function(){
				
					list();
					
					
					//list 출력하고 모든 값들 초기화 시키기
					
					//추가 성공시 다시 목록 출력
					//입력값 지우기...초기화
					$("#writer").val(" ");
					$("#story").val(" ");
					
					//선택된 아바타 클래스 제거
					$("img.avata").removeClass("select");
					
					//아바타 2번인덱스에 select클래스 추가
					$("img.avata:eq(2)").addClass("select");
					//아바타 2번인덱스에 src값을 얻어서 input태그에 넣어주기
					$("#avata").val($("#img.avata").eq(2).attr("src"));
					
					//작성자창으로 자동으로 이동하기
					$("#writer").focus();
					
				}
			})
			
		})

delete

우리가 만든 태그에 이벤트로 만들어진 버튼이라 동적이벤트 적용
->memoDelete.jsp 사용

dataType

다른 파일에서 json형식/xml형식으로 받아올 것이 없으면 html로 받아온다
/ex) return값이 없다고 생각하면 된다
json형식 하나의 예로 JSONObject 값을 받아올 경우

dataType:"html",

data

var num으로 가져온 것은 속성값이기에 어떤 속성 값인지 json형식으로 지정해줘야한다

data:{"num":num},
  • delete
//삭제
		//우리가 만든 태그여서 동적이벤트 적용
		$(document).on("click","span.del",function(){
			
			var num=$(this).attr("num");
			//alert(num);
			
			$.ajax({
				
				type:"get",
				//다른 파일에서 json형식/xml형식으로 받아올 것이 없으면 html로 받아온다
				//ex) return값이 없다고 생각하면 된다
				//json형식 하나의 예로 JSONObject 값을 받아올 경우
				dataType:"html",
				url:"memoDelete.jsp",
				//위에 var num으로 가져온 것은 속성값이기에 어떤 속성 값인지 json형식으로 지정해줘야한다
				data:{"num":num},
				success:function(){
					
					list();
				}
			})
		})

정보가져오기(update 초기단계)

리스트의 수정버튼 클릭시 수정폼이 나오면서 해당 정보 가져오기

num값 가져오기

var num=$(this).attr("num");

success:function('')

가져올 정보가 있어서 ''안에 변수로 가져오기

				//받아올 것이 있어서 res로 받아옴
				success:function(res){

res로 받아온 값 수정폼 태그에 넣어주기

value값에 넣어서 값 넣어주기

$("#unum").val(res.num);
$("#uwriter").val(res.writer);
$("#ustory").val(res.story);
$("#uavata").val(res.avata);

가져온 이미지 선택표시

list에서 가져온 이미지가 select된 표시 나타나게하기

//해당이미지에 select클래스 추가
$("img.uavata").each(function(i,ele){
						
	if($(this).attr("src")==res.avata)
		$(this).addClass("select");
	else
		$(this).removeClass("select");
});

수정폼 띄우고 추가폼 없애기

추가폼(addform)이 있다면 숨기고 수정폼(updateform)을 나타낸다

$("div.addfrm").hide();
$("div.updateform").show();

수정폼 띄워져있을 때 버튼눌러도 추가폼 안뜨게 하기

$("#btnadd").click(function(){
	$(".addform").hide();
})
  • 수정폼 정보 입력상태로 가져오기
$(document).on("click","span.mod",function(){
			
			//이 num이 update폼에 들어가야함
			var num=$(this).attr("num");
			//alert(num);
			
			//수정폼의 unum에 num넣기
			$("#unum").val(num);
			
			$.ajax({
				
				type:"get",
				url:"memoGetData.jsp",
				dataType:"json",
				data:{"num":num},
				//받아올 것이 있어서 res로 받아옴
				success:function(res){
					
					//res로 받아온 값들을 수정폼 태그(value값으로) 안에 넣어준다
					$("#unum").val(res.num);
					$("#uwriter").val(res.writer);
					$("#ustory").val(res.story);
					$("#uavata").val(res.avata);
					
					//해당이미지에 select클래스 추가
					$("img.uavata").each(function(i,ele){
						
						if($(this).attr("src")==res.avata)
							$(this).addClass("select");
						else
							$(this).removeClass("select");
					});
					
					//추가폼(addform)이 있다면 숨기고 수정폼(updateform)을 나타낸다
					$("div.addfrm").hide();
					$("div.updateform").show();
				}
			});
			
			//수정폼이 떠있을때 추가폼이 뒤에 안뜨게 하기
			$("#btnadd").click(function(){
				$(".addform").hide();
			})
		});

update

-> memoUpdate.jsp 사용

에러

에러 떴을때...form 안에 input unum값 가져오는 것을 안넣어놔서 unum값을 못 가져왔었음

var data=$("#updatefrm").serialize();
			
alert(data);
  • update
		$("td.dbupdate").click(function(){
				
				//에러 떴을때...form 안에 input unum값 가져오는 것을 안넣어놔서 unum값을 못 가져왔었음
				var data=$("#updatefrm").serialize();
			
				alert(data);
				
				$.ajax({
				type:"post",
				dataType:"html",
				url:"memoUpdate.jsp",
				data:data,
				success:function(){
				
					list();
					
					
					$("#uwriter").val(" ");
					$("#ustory").val(" ");
					
					$("img.uavata").removeClass("select");
					
					$("img.uavata:eq(2)").addClass("select");
					$("#uavata").val($("#img.uavata").eq(2).attr("src"));
					
					$("#uwriter").focus();
					
					}
				})
		});

memo.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Cute+Font&family=Diphylleia&family=Dokdo&family=Nanum+Brush+Script&family=Nanum+Gothic+Coding&family=Noto+Sans+KR&display=swap" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<title>Insert title here</title>
<style>
	div.memo{
		position: absolute;
		border: 0px solid gray;
		font-size: 1.5em;
		font-family: 'Cute Font';
	}
	
	div.button{
		left: 150px;
		top: 30px;
		width: 400px;
		height: 100px;
		line-height: 100px;
		text-align: center;
	}
	
	div.addform{
		left: 100px;
		top: 150px;
		width: 550px;
		height: 450px;
		padding: 20px 20px;
	}
	
	div.updateform{
		left: 100px;
		top: 150px;
		width: 550px;
		height: 450px;
		padding: 20px 20px;
	}
	
	div.list{
		left: 800px;
		top: 100px;
		width: 700px;
		height: 700px;
		padding: 20px 20px;
	}
	
	img.avata{
		cursor: pointer;
	}
	
	img.select{
		border: 2px solid mediumpurple;
	}
	
	span.writeday{
		float: right;
		color: #bbb;
	}
	
	span.writer{
		font-weight: bold;
	}
	
	span.mod{
		margin-left: 200px;
		cursor: pointer;
		color: royalblue;
	}
	
	span.del{
		cursor: pointer;
		color: red;
	}
</style>
<script>
	$(function(){
		
		//처음 로딩시 목록 출력하기 (호출해야함)
		list();
		
		//로딩 됐을때 아무 것도 없어야함
		$("div.addform").hide();
		$("div.updateform").hide();
		
		//메모추가 버튼 누르면 addform 나타나기
		$("#btnadd").click(function(){
			$("div.addform").slideToggle();
		})
		
		//아바타 2번인덱스에 select클래스 추가
		$("img.avata:eq(2)").addClass("select");
		
		//아바타 2번인덱스에 src값을 얻어서 input태그에 넣어주기
		//input태그를 통해 db에 넣어주기 때문에 넣어줘야함
		//avata라는 id에 img.avata의 2번 인덱스 src값을 추출해서 그 벨류 값을 넣어준다
		$("#avata").val($("#img.avata").eq(2).attr("src"));
		
		//아바타 선택하면 값이 변경되어야함
		$("img.avata").each(function(){
			$(this).click(function(){
				$(this).addClass("select");
				$(this).siblings().removeClass("select");
				$("#avata").val($(this).attr("src"));
			})
		})
		
		
		
		
		
		
		//수정폼의 아바타 선택하면 값이 변경되어야함
		$("img.uavata").each(function(){
			$(this).click(function(){
				$(this).addClass("select");
				$(this).siblings().removeClass("select");
				$("#uavata").val($(this).attr("src"));
			})
		})
		
		
		
		
		
		
		
		
		//저장용(insert)..추가성공시 list(); 호출
		$("td.dbsave").click(function(){
			
			//id addfrm인 곳의 모든 태그 불러오기
			var data=$("#addfrm").serialize();
			//alert(data);
			
			//db에 저장하면서 list에 저장한 정보 띄우기
			$.ajax({
				//memoinsert에 엔코딩해서 post가능
				//보안성과 대용량의 데이터를 보낼때 post 사용
				type:"post",
				//출력만해서 html
				dataType:"html",
				url:"memoinsert.jsp",
				//위에 var data는 모든 태그를 가져와서 변수로 data:변수로 지정 가능
				data:data,
				success:function(){
				
					list();
					
					
					//list 출력하고 모든 값들 초기화 시키기
					
					//추가 성공시 다시 목록 출력
					//입력값 지우기...초기화
					$("#writer").val(" ");
					$("#story").val(" ");
					
					//선택된 아바타 클래스 제거
					$("img.avata").removeClass("select");
					
					//아바타 2번인덱스에 select클래스 추가
					$("img.avata:eq(2)").addClass("select");
					//아바타 2번인덱스에 src값을 얻어서 input태그에 넣어주기
					$("#avata").val($("#img.avata").eq(2).attr("src"));
					
					//작성자창으로 자동으로 이동하기
					$("#writer").focus();
					
				}
			})
			
		})
		
		//삭제
		//우리가 만든 태그여서 동적이벤트 적용
		$(document).on("click","span.del",function(){
			
			var num=$(this).attr("num");
			//alert(num);
			
			$.ajax({
				
				type:"get",
				//다른 파일에서 json형식/xml형식으로 받아올 것이 없으면 html로 받아온다
				//ex) return값이 없다고 생각하면 된다
				//json형식 하나의 예로 JSONObject 값을 받아올 경우
				dataType:"html",
				url:"memoDelete.jsp",
				//위에 var num으로 가져온 것은 속성값이기에 어떤 속성 값인지 json형식으로 지정해줘야한다
				data:{"num":num},
				success:function(){
					
					list();
				}
			})
		})
		
		//수정 정보 가져오기
		//리스트의 수정버튼
		$(document).on("click","span.mod",function(){
			
			//이 num이 update폼에 들어가야함
			var num=$(this).attr("num");
			//alert(num);
			
			//수정폼의 unum에 num넣기
			$("#unum").val(num);
			
			$.ajax({
				
				type:"get",
				url:"memoGetData.jsp",
				dataType:"json",
				data:{"num":num},
				//받아올 것이 있어서 res로 받아옴
				success:function(res){
					
					//res로 받아온 값들을 수정폼 태그(value값으로) 안에 넣어준다
					$("#unum").val(res.num);
					$("#uwriter").val(res.writer);
					$("#ustory").val(res.story);
					$("#uavata").val(res.avata);
					
					//해당이미지에 select클래스 추가
					$("img.uavata").each(function(i,ele){
						
						if($(this).attr("src")==res.avata)
							$(this).addClass("select");
						else
							$(this).removeClass("select");
					});
					
					//추가폼(addform)이 있다면 숨기고 수정폼(updateform)을 나타낸다
					$("div.addfrm").hide();
					$("div.updateform").show();
				}
			});
			
			//수정폼이 떠있을때 추가폼이 뒤에 안뜨게 하기
			$("#btnadd").click(function(){
				$(".addform").hide();
			})
		});
		
		$("td.dbupdate").click(function(){
				
				//에러 떴을때...form 안에 input unum값 가져오는 것을 안넣어놔서 unum값을 못 가져왔었음
				var data=$("#updatefrm").serialize();
			
				alert(data);
				
				$.ajax({
				type:"post",
				dataType:"html",
				url:"memoUpdate.jsp",
				data:data,
				success:function(){
				
					list();
					
					
					$("#uwriter").val(" ");
					$("#ustory").val(" ");
					
					$("img.uavata").removeClass("select");
					
					$("img.uavata:eq(2)").addClass("select");
					$("#uavata").val($("#img.uavata").eq(2).attr("src"));
					
					$("#uwriter").focus();
					
					}
				})
		});
		
		
		
	})
	
	//사용자함수...list
	//script는 이벤트 줄 것이 많아서 //사용자함수(호출용)은 function 밖에 있어야해서 따로 만듦
	function list(){
		
		$.ajax({
			type:"get",
			dataType:"json",
			url:"memolist.jsp",
			success:function(data){
				
				//로딩,클릭 등등 특정 상황마다 확인하기
				//alert(data.length);
				var s="";
				//데이터가 없다면
				if(data.length==0)
				{
					s+="<h3 class= 'alert alert-info'>저장된 메모가 없습니다</h3>";
				}
				else
				{
					//넘어오는 데이터는 배열식으로 넘어오기 때문에 $.each
					$.each(data,function(i,elt){
						
						s+="<table class='table'>";
						s+="<tr><td>";
						//날짜 시간 등등 span태그로 들어감 (옆으로 조그맣게 넣을 수 있음)
						s+="<span class='writer'>작성자:"+elt.writer+"</span>";
						s+="<span class='writeday'>"+elt.writeday+"</span>";
						//수정 버튼에 시퀀스 가져와야함
						s+="<span class='mod' num='"+elt.num+"'>수정/</span>"
						s+="<span class='del' num='"+elt.num+"'>삭제</span>"
						s+="<br>";
						//자체적으로 엔터 먹는 태그
						s+="<pre>"+elt.story;
						s+="<img src='"+elt.avata+"' align='right' width='80'>";
						s+="</pre>";
						s+="</td><tr>";
						s+="</table><br>";
					});
				}
				$("div.list").html(s);
			}
		})
	}
	
</script>
</head>
<body>
	<!--style을 주는 이유는 위치를 잡아주기 위해서
		모든 폼 액션 이곳에 작성-->
<div class="memo button">
	<button type="button" class="btn btn-info"
	id="btnadd">메모추가</button>
</div>

<!-- id를 준 이유는 각각의 요소를 지정할 수 있어서
	 insertForm -->
<div class="memo addform">
	<form id="addfrm">
		<table class="table table-bordered">
			<tr>
				<th style="background-color: #00bfff; width: 120px;">작성자</th>
				<td>
					<input type="text" class="form-control"
					name="writer" id="writer" style="width: 120px;">
				</td>
			</tr>
			
			<tr>
				<th style="background-color: #00bfff; width: 120px;">메모</th>
				<td>
					<!-- textarea는 나중에 수정할 때도 태그 사이에서만 수정 가능
						 원래는 colspan줘서 th없이 메모장 작성 가능하게 만듦 -->
					<textarea class="form-control"
					name="story" id="story" style="width: 270px; height: 150px; font-size: 1.1em;"></textarea>
				</td>
			</tr>
			
			<tr>
				<th style="background-color: #00bfff; width: 120px;">아바타</th>
				<td>
					<!-- type이 text면 번호 매겨지기 때문에 hidden으로 적용 -->
					<input type="hidden" name="avata" id="avata">
					<script>
						// 사진 5개 1줄로 넣기
						var s="";
						for(var i=1;i<=10;i++)
						{
							s+="<img src='../image/b"+i+".png' width='50' class='avata'>"
							if(i%5==0)
							{
								s+="<br>"
							}
						}
						document.write(s);
					</script>
				</td>
			</tr>
			<tr>
				<td colspan="2" align="center" style="cursor: pointer; background-color: #00bfff;"
				class="dbsave">
					DB에 저장하기
				</td>
			</tr>
		</table>
	</form>
</div>

<!-- updateForm -->
<div class="memo updateform">
	<!-- 항상 input type:hidden으로 num을 넘겨줘야한다
		 각각의 데이터를 value대신 id로 받아와야한다
		 serialize로 받아오면 name으로 받아와야한다 -->
	<!-- hidden -->
	<!-- 나중에 ajax로 받아온 값으로 name id 값을 처리해준다
		 insert와 다른 이름을 써야한다/보통 insert폼의 name id 앞에 u만 붙인다 -->
	<form id="updatefrm">
		<input type="hidden" name="unum" id="unum">
		<table class="table table-bordered">
			<tr>
				<th style="background-color: #00bfff; width: 120px;">작성자</th>
				<td>
					<input type="text" class="form-control"
					name="uwriter" id="uwriter" style="width: 120px;">
				</td>
			</tr>
			
			<tr>
				<th style="background-color: #00bfff; width: 120px;">메모</th>
				<td>
					<!-- textarea는 나중에 수정할 때도 태그 사이에서만 수정 가능
						 원래는 colspan줘서 th없이 메모장 작성 가능하게 만듦 -->
					<textarea class="form-control"
					name="ustory" id="ustory" style="width: 270px; height: 150px; font-size: 1.1em;"></textarea>
				</td>
			</tr>
			
			<tr>
				<th style="background-color: #00bfff; width: 120px;">아바타</th>
				<td>
					<!-- type이 text면 번호 매겨지기 때문에 hidden으로 적용 -->
					<input type="hidden" name="uavata" id="uavata">
					<script>
						// 사진 5개 1줄로 넣기
						var s="";
						for(var i=1;i<=10;i++)
						{
							s+="<img src='../image/b"+i+".png' width='50' class='uavata'>"
							if(i%5==0)
							{
								s+="<br>"
							}
						}
						document.write(s);
					</script>
				</td>
			</tr>
			<tr>
				<td colspan="2" align="center" style="cursor: pointer; background-color: #00bfff;"
				class="dbupdate">
					DB에 수정하기
				</td>
			</tr>
		</table>
	</form>
</div>
<div class="memo list">list</div>

</body>
</html>

memoinsert.jsp

엔코딩

request.setCharacterEncoding("utf-8");

데이터읽기(wirter,story,avata)

String writer=request.getParameter("writer");
String story=request.getParameter("story");
String avata=request.getParameter("avata");

dto로 묶기

MemoDto dto=new MemoDto();
dto.setWriter(writer);
dto.setStory(story);
dto.setAvata(avata);

insert 메서드에 값 넣기

insert 호출

dao.insertMemo(dto);

memoinsert.jsp

<%@page import="db.memo.MemoDto"%>
<%@page import="db.memo.MemoDao"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%-- json이라 html문 다 지움 --%>
<%
	MemoDao dao=new MemoDao();

	//엔코딩
	request.setCharacterEncoding("utf-8");
	
	//데이터읽기(writer,story,avata)
	String writer=request.getParameter("writer");
	String story=request.getParameter("story");
	String avata=request.getParameter("avata");

	//dto로 묶기
	MemoDto dto=new MemoDto();
	dto.setWriter(writer);
	dto.setStory(story);
	dto.setAvata(avata);
	
	//insert호출
	dao.insertMemo(dto);
%>

<%--<%=dto.toString() --%>

memoDelete

JSP의 response.sendRedirect 구문 제외 동일

memoDelete.jsp

<%@page import="db.memo.MemoDto"%>
<%@page import="db.memo.MemoDao"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	MemoDao dao=new MemoDao();

	//function list() span 태그에 있는 num값을 가져온다
	String num=request.getParameter("num");
	
	dao.deleteMemo(num);
%>

memoGetData

list의 수정버튼을 눌렀을때 수정폼 띄움과 동시에 해당 정보 가져오기

여기서 run as 해서 table에 있는 num값 확인하고 url마지막에 ?num=해당num값 입력해주면 json 형태의 배열로 만들어졌는지 확인하기

값을 가져오는지 확인하기 위해서 위 방법을 사용

JSONObject

json형태로 정보를 가져와야함

JSONObject ob=new JSONObject();
	
	
//""안에 있는 값으로 form으로 띄워야 해당 값을 가져와서 그대로 입력되게 할 수 있다
ob.put("num",dto.getNum());
ob.put("writer",dto.getWriter());
ob.put("story",dto.getStory());
ob.put("avata",dto.getAvata());
ob.put("writeday",sdf.format(dto.getWriteday()));

ob.put("1","2") - 1안에 있는 값이 form에 띄워야하는 값
2의 값을 1에 넣어서 1에 있는 값을 가져와 그대로 입력할 수 있다

ob.toString()

json으로 띄울 경우 string값으로 받아와야하기 때문에 사용

<%=ob.toString()%>

memoGetData.jsp

<%@page import="org.json.simple.JSONObject"%>
<%@page import="java.text.SimpleDateFormat"%>
<%@page import="db.memo.MemoDto"%>
<%@page import="db.memo.MemoDao"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	MemoDao dao=new MemoDao();

	String num=request.getParameter("num");
	
	MemoDto dto=dao.getData(num);
	
	SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm");
	
	JSONObject ob=new JSONObject();
	
	
	//""안에 있는 값으로 form으로 띄워야 해당 값을 가져와서 그대로 입력되게 할 수 있다
	ob.put("num",dto.getNum());
	ob.put("writer",dto.getWriter());
	ob.put("story",dto.getStory());
	ob.put("avata",dto.getAvata());
	ob.put("writeday",sdf.format(dto.getWriteday()));
	
	//여기서 run as 해서 table에 있는 num값 확인하고 url마지막에 ?num=해당num값 입력해주면 json 형태의 배열로 만들어졌는지 확인하기
	//값을 가져오는지 확인하기 위해서 위 방법을 사용
%>

<%-- json으로 띄울 경우 string값으로 받아와야하기 때문 --%>
<%=ob.toString()%>

memoUpdate

form에서 받아오는 값

수정버튼 동적이벤트로 이미 값들을 넣어줬기 때문에(이벤트시 값 넘겨줌)
update의 값을 받아올때 updateform 값을 받아와 적용할 수 있다

String uwriter=request.getParameter("uwriter");
String ustory=request.getParameter("ustory");
String uavata=request.getParameter("uavata");
String unum=request.getParameter("unum");

이후 dto에 String으로 가져온 값을 넣어주고 dao에 있는 update메서드 호출해서 값을 넘겨주면 된다

memoUpdate.jsp

<%@page import="db.memo.MemoDao"%>
<%@page import="db.memo.MemoDto"%>
<%@page import="org.json.simple.JSONObject"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	MemoDao dao=new MemoDao();

	request.setCharacterEncoding("utf-8");


	//수정버튼 동적이벤트로 이미 값들을 넣어줬기 때문에(이벤트시 값 넘겨줌)
	//update의 값을 받아올때 updateform 값을 받아와 적용할 수 있다
	String uwriter=request.getParameter("uwriter");
	String ustory=request.getParameter("ustory");
	String uavata=request.getParameter("uavata");
	String unum=request.getParameter("unum");
	
	MemoDto dto=new MemoDto();

	dto.setWriter(uwriter);
	dto.setStory(ustory);
	dto.setAvata(uavata);
	dto.setNum(unum);
	//insert호출
	dao.updateMemo(dto);
%>

<%=dto.toString()%>
profile
백엔드 개발자로서 성장해 나가는 성현이의 블로그~

1개의 댓글

comment-user-thumbnail
2023년 8월 8일

좋은 정보 얻어갑니다, 감사합니다.

답글 달기