Chillax in dev

[Ajax] 에이젝스로 삭제 기능 구현하기 본문

jQuery Js

[Ajax] 에이젝스로 삭제 기능 구현하기

Seong Story 2021. 4. 9. 18:22
728x90

[Ajax] 에이젝스로 삭제 기능 구현하기

- ajax를 이용하여 게시판에서 특정 칼럼에 대하여 삭제할 수 있고 또한 체크박스로 체크된 항목에 대하여 다중으로 삭제하는 기능을 구현해보며 ajax를 공부하고자 합니다.

#개발환경

- 언어: php 5

- 프레임 워크 : 코드이그나이터 3.0

- 스크립트 버전 : jQuery v3.2.1

- Bootstrap : 아이콘 활용

<단일 삭제 리스트 에서 ajax로 구현하기>

1. view에 삭제 버튼과 체크박스로 삭제 할 수 있는 view딴을 먼저 만듭니다.

- 먼저 특정 칼럼에 대해 단일 삭제 하는 로직을 구현해 보겠습니다.

태그를 만들어 줍니다.

- 아

<!--주소지 삭제 버튼-->
<button class="btn btn-danger btn-xs delete-address-item" data-index="<?=$row['address_srl']?>">
	<span class="glyphicon glyphicon-trash" style=" vertical-align: middle;">
	</span>
</button>

// 화면딴은 아무것도 없이 버튼 태그에 class로 btn btn-danger btn-xs 디자인을 주었고 중요한건 delete-address-item 이라는 클래스 명을 주어 이를 활용해 제이쿼리를 걸어줄 것입니다. 또한 특정 칼럼을 선택하기위해 data-index 속성을 직접 만들어 주어 해당 칼럼의 고유한 번호 값을 넣어줬습니다. address_srl은 주소에 대한 pk 값입니다.

//span 태그에 glyphicon glyphicon-trash를 주어 부트스트랩 쓰레기통 모양의 버튼을 만들었습니다. 화면은 이게 전부 입니다.

 

2. 이제 제이쿼리로 에이젝스를 구현해줍니다. 

- 단일 칼럼을 삭제하든 여러 칼럼을 선택하든 하나의 제이쿼리로 기능을 수행 할 수있게 만들었습니다.

delAddressItem() 함수를 하나 만들어서 각각의 경우 참조하여 사용하는 방식으로 만들었습니다.

// 싱글 삭제처리
	$(document).on("click", "button.delete-address-item", function(){
		var index = $(this).attr("data-index");
		if(confirm("선택한 주소를 삭제 하시겠습니까?")){
			var itemList = [];
			itemList[0] = index;
			delAddressItem(itemList);
		}
	})
	
	function delAddressItem(itemList){
		var inputData = {
			csrf : '<?=$this->auth->statusKey?>',
			itemList : itemList
		};
		
		$.ajax({
			url : '<?=$this->lib->getUrl("distribute/address/api/delete")?>',
			type : "POST",
			async: false,
			data : inputData,
			dataTyee : "json",
			error : function(request, status, error){
				console.log("Code:"+request.status+" / Message:"+request.responseText+" / Error: "+error);
			},
			success: function(data){
				//console.log(data);
				if(data.resultCode == 200){
					window.alert("삭제가 완료가 확인 되었습니다.");
					document.location.reload(true);
				}else{
					window.alert(data.message);
				}
			},
			beforeSend:function(){
				$('.wrap-loading').removeClass('display-none');
				$('.wrap-loading .loading-message').html("...삭제 처리중...");
			},
			complete:function(){
				$('.wrap-loading').addClass('display-none');
				$('.wrap-loading .loading-message').html("...데이터를 저장하는 중입니다...");
			},
		})
		
	}

// 한줄한줄 이해해 봅시다.

$(document).on("click", "button.delete-address-item" , function(){

})

이부분을 이해하기 에 앞서 

 

$(document).ready(function(){}) 과 $(document).on(function(){})의 차이를 잘 이해해야한다.

ready의 경우 DOM이 준비 되었을때 이벤트를 시작하겠단 의미이고 이는 $(window).load와 같은 경우로 window에서 모든게 load된 시점에 이벤트를 떄리겠단의미입니다. 문제가 있다면 element가 동적으로 생성되면 이벤트가 반영이 안된다는것입니다. 즉 이방법은 동적으로 요소사 생성되지 않을때 사용해야겠다는것이다.

 

on의 경우는 이벤트를 위임하는 느낌으로 위 요소부터 아래 요소 까지 이벤트가 이어져 내려가기에 새로 생긴 요소에도 기본 부모가 이벤트를 가지고 있어 이를 넘겨주어  동적으로 생긴 element에 대해서도 이벤트가 적용되는것이다.

제이쿼리는 선택자가 전부라고도할 수 있다. 위의 "button.delete-address-item" 부분은 아까준 버튼 태그의 클래스를 선택한 선택자 이고 이를클릭했을때 function을 실행한다는것이다.

 

var index = $(this).attr("data-index");

//아까준 data-index의 속성값을 index에 저장한다. 그속엔 주소지의 pk값이들어있다.

 

if(confirm("선택한 주소를 삭제 하시겠습니까?")){
var itemList = [];
itemList[0] = index;
delAddressItem(itemList);
}

 

//confirm을 통해서 선택한 주소를 삭제할지 확인하는 확인 alert를 띄우고 예->true, 아니요-> false한다.

예를 누르면 itemList 라는 배열에 해당 주소지의 pk값을 가지고 delAddressItem(itemList); 함수를 실행한다.

 

이제 ajax를 실행하는 함수를 살펴보자.

function delAddressItem(itemList){
var inputData = {
csrf : '<?=$this->auth->statusKey?>',
itemList : itemList
};

// csrf는 보안상 해주는검사이다. 모든 post값에 대해서 여러 스크립팅 공격을 방지함으로 꼭 넣어주자.

//ltemList라는 key로  받아온 주소 pk값을 넣줍니다.

이렇게 {} 에 넣는방식은 json 입니다. 배열이라고 생각하면 거부감이 들하고 사람이 알아보기쉬우며 파싱도 간단합니다.

그저 단순한 데이터 포맷이다.

 

$.ajax({

url : '<?=$this->lib->getUrl("distribute/address/api/delete")?>',

type : "POST",
async: false,
data : inputData,

dataTyee : "json",

//이제  에이젝스를 작성한다.

url은 에이젝스를 처리할 프로세스의 url인데 컨트롤러에서 다음 url을 타고 가서 실행값을 반환한다.

type: 타입은 post이고

async는 false 즉 동기화 기능을 사용하기 않겠다. 이렇게 해준 가장큰이유는 자바스크립트의 처리속도와 여러가지가 안맞아 에러를 낼수 있는데 이런 위험을 줄이고자 동기 기능은 안쓰겠다 한거다.

data는 아까만들어준 제이슨 inputData 당연히 타입은 제이슨이다.

 

이제 해당 통신이 성공했거나 실패했거나 과정등에 발생하는 동작들을 넣어주면 끝이다.

 

success: function(data){
				//console.log(data);
				if(data.resultCode == 200){
					window.alert("삭제가 완료가 확인 되었습니다.");
					document.location.reload(true);
				}else{
					window.alert(data.message);
				}
			},
			beforeSend:function(){
				$('.wrap-loading').removeClass('display-none');
				$('.wrap-loading .loading-message').html("...삭제 처리중...");
			},
			complete:function(){
				$('.wrap-loading').addClass('display-none');
				$('.wrap-loading .loading-message').html("...데이터를 저장하는 중입니다...");
			},
		})

success : 해당 url이성공하면 data를 반환하는데 그값을 받아다 성공하면 resultCode 는 200 완료 사실을 알려주고 새로고침한다. else라면 message를 띄어 문제를 알수 있게 해준다.

 

beforeSend 는 처리과정중에 보이는 부분을 만들어준다 오래걸리면 작동중임을 알려야하니 말이다.

 

complete: c의 finally와 같은 녀석인데 error나 success callback함수가 수행된 후에도 실행되는 함수이다.

 

//이것으로 에이젝스분석까지 끝났고

//이제 컨트롤러에서 url 타고가서 하는 처리부분을 살펴보자

 

 

if($method == "api"){
			///////////////////////////////////////////////
			// API // distribute/address/api/{action}
			///////////////////////////////////////////////
			// Action 값이 입력되어있는지 확인 
			header("Content-Type: application/json;charset=utf-8");
			if(!isset($data[0])){
				$this->lib->getJSON(404,"잘못된 경로 : 액션값이 입력되지 않았습니다.");
			}else{
				$action = $data[0];
			}
			// Security XSS GLOBAL CLEAN
			$data = $this->security->xss_clean($_POST);
			// Cross Domain CSRF 체킹
			if(!isset($data['csrf'])){
				$this->lib->getJSON(403, "권한 애러 : 세션값을 확인할 수 없습니다.");
			}
			
			// SCRF 체크
			if($this->session->statusKey != $data['csrf']){
				$this->lib->getJSON(403, "권한 애러 : 잘못된 세션입니다.");
			}
			
			// 모델링 가져오기
			$this->load->model('distribute/address/process');
			
			switch($action){
				case "delete":
					$this->process->delAddress($data);
				break;
				default:
					$this->lib->getJSON(404, "잘못된 경로 : 잘못된 액션값으로의 접근입니다.");
				break;
			}
			
		}

//header("Content-Type: application/json;charset=utf-8");

헤더는 콘텐츠가 인코딩 된 내용을 표시 할뿐입니다. 콘텐츠 자체에서 콘텐츠 유형을 추론하는 것이 반드시 가능하지는 않습니다. 즉, 콘텐츠를보고 어떻게해야할지 알 수는 없습니다. 이것이 바로 HTTP 헤더의 용도이며 수신자에게 어떤 종류의 콘텐츠를 처리하고 있는지 알려줍니다.

//스택 오버프롤우에서 발췌한 답변 내용이다. 그냥 인코딩 해준거다.

나머진 message

404 : 액션값이 없을때

403: csrf값 안넘어왔을때 

403: 지정해준 세션값이 안넘어왔을때

 

그후 delete를 확인하여 결국 또 모델로 보내데이터를 처리한다.

 

//model 부분을보면

 

	//삭제는 ajax로 처리.
	public function delAddress($data){
		if(!isset($data['itemList'])){
			$this->lib->getJSON(400, "삭제할 주소록이 입력되지 않았습니다.");
		}
		
		if(!is_array($data['itemList'])){
			$this->lib->getJSON(400, "삭제할 주소록 값이 입력되지 않았습니다.");
		}
		
		if(count($data['itemList']) > 0){
			foreach($data['itemList'] as $idx){
				$qry = $this->db2->query("select * from `ws_distribute_address` where `address_srl`='".$this->db2->escape_str($idx)."' and `is_delete`='N'");
				if($qry->num_rows() == 1){
					$address = $qry->row();
					$this->db2->simple_query("update `ws_distribute_address` set `is_delete`='Y', `delete_dt`=NOW() where `address_srl`='".$address->address_srl."'");
				}
			}
			
			$this->lib->getJSON(200, "선택한 주소록 정보가 삭제 되었습니다.");
		}else{
			$this->lib->getJSON(401, "삭제할 데이터가 없습니다.");
		}
		
		
	}

// 드디어 받아온 제이슨을 처리 하고 sql을 실행한다. 이는 모델에서 하는 일로 여기서 볼건

foreach로 하나의 삭제나 여러 배열로주소pk가 오나 다 삭제해주는 쿼리의 실행과

실행후 $this->lib->getJson()으로 미리만든 라이브러리에서 해당 제이슨 반환코드를 같이 넘겨주며 메시지를 보낸다.

 

//결과

url변동없이 삭제만 쏙 가능하다~

 

다중삭제도 별다를건없지만 다음에 다시 공부하는겸 포스팅 하기로 하고 이번에 살펴본 에이젝스를 정리하고 마무리하자.

 

정리

- 1. 화면딴에 사용할 버튼등을 만들어 클레스를 걸어주고 직접 만든 속성에 유일한 값을넣어 준다.

- 2. 제이쿼리로 해당 태그를 선택하여 이벤트를 건다.

- 3. 필요한 데이터를 제이슨으로 저장한다.

- 4. 함수의 형태로 ajax를 구현한다. 그후 컨트롤러에 보낸다  url로 수행

- 5. 컨트롤러에선 값이 잘넘어왔나 확인후 결국 process란 모델로 보낸다.

- 6. 모델에선 이제 해당 제이슨에 대해 sql문으로 원하는 동작을 넣어준다.

- 7. 그후 결과 갑의 여부에 대하여 제이슨 값을 반환하고 그값을 보여주며 끝낸다.

 

728x90
LIST

'jQuery Js' 카테고리의 다른 글

[제이쿼리] input 태그 숫자입력 강제하기  (0) 2022.02.22
Comments