https://unstopdevelop.tistory.com/410
ajax를 이용한 검색어 자동 완성 기능 설명
오늘 공부해보고 주변 사람들이 어려움을 겼는 한부분을 설명해보겠습니다. 이 부분을 이해하면 다음에 다른 코드들의 흐름을 읽어보고 따라가는데 도움이 될 것 입니다. suggest.jsp <%@page import="j
unstopdevelop.tistory.com
이글에 이어서 작성합니다 코드의 전체 내용을 볼려면 위의 글 젤위에서 보시면됩니다.
어제 httpRequest.send(httpMethod=='POST'?httpParams:null); 여기까지해서 httpRequest의 상태의 변화가 발생했습니다.
그래서 httpRequest.onreadystatechange=callback; 여기에서 등록된 callback이 실행됩니다. callback은 sendRequest("suggest.jsp",params,displayResult,'POST');여기서 3번째로 넘겨준
function displayResult(){
if(httpRequest.readyState==4){
if(httpRequest.status==200){
var resultText=httpRequest.responseText;
var result=resultText.split('|');
var count=parseInt(result[0]);
var keywordList=null;
if(count>0){
keywordList=result[1].split(',');
var html='';
for(var i=0;i<keywordList.length;i++){
html+="<a href=\"javascript:select('"+keywordList[i]+"')\">"+keywordList[i]+"</a><br/>";
}
var listView=document.getElementById('suggestList');
listView.innerHTML=html;
show('suggest');
}else{
hide('suggest');
}
}else{
alert("에러발생:"+httpRequest.status);
}
}
}
이 함수 입니다.
if(httpRequest.readyState==4)는 ajax통신이 끝났는지 확인하는 의미 즉 4이면 통신이 끝나서 결과가 나왔다는 의미 입니다.
if(httpRequest.status==200)는 제대로 동작되었냐는 의미입니다. 404는 해당페이지를 못찾았다는거고 500 은 내부 서버상 오류가 있다는 의미이고 200이 제대로 의도한대로 동작되었다는 의미 입니다.
우리는 httpRequest.open(httpMethod,httpUrl,true);이코드에서 suggest.jsp?keyword=자바로 POST방식으로 비동기 방식으로 통신하였습니다.
var resultText=httpRequest.responseText; 여기서는 통신해서 받은 데이터를 resultText에 저장해줍니다. 그럼 어떤 데이터가왔는지 알아보겠습니다.
<%
request.setCharacterEncoding("utf-8");
String keyword=request.getParameter("keyword");
List keywordList=search(keyword);
out.print(keywordList.size());
out.print("|");
for(int i=0;i<keywordList.size();i++){
String key=(String)keywordList.get(i);
out.print(key);
if(i<keywordList.size()-1){
out.print(",");
}
}
%>
result jps중에서도 이부분이 실행 됩니다. 위에 부분은 선언 부분이므로 서버 실행시 선언되고 통신한다고 실행 되지 않고 이 곳에서 호출해야지 그때 실행됩니다.
request.setCharacterEncoding("utf-8"); utf-8로 해독 한다는 의미 입니다.
String keyword=request.getParameter("keyword"); 아까 주소에 keyword의 이름으로 전달해준 '자바'라는 값을 keyword라는 변수에 저장합니다.
List keywordList=search(keyword); search함수에 keyword를 인자로 넘겨서 실행합니다.
public List search(String keyword){
if(keyword==null || keywords.equals("")){
System.out.println("se");
return Collections.EMPTY_LIST;
}
keyword=keyword.toUpperCase();
List result=new ArrayList(8);
for(int i=0;i<keywords.length;i++){
if(((String)keywords[i]).startsWith(keyword)){
result.add(keywords[i]);
}
}
return result;
}
if(keyword==null || keywords.equals("")) keyword가 null이거나 keywords가 빈공간이면 if문을 실행하는 코드입니다.
String[] keywords={
"AJAX",
"AJAX 실전 프로그래밍",
"자바",
"자바 프로그래밍",
"자바스터디",
"자바서비스",
"자바캔"
};
return Collections.EMPTY_LIST; 그 경우 비어있는 List를 반환해줍니다. 하지만 현재 자바 이므로 이코드는 뛰어 넘습니다.
keyword=keyword.toUpperCase(); keyword값들을 다 대문자로 변경해서 다시 keyword로 저장합니다. 한글이므로 변화가 없습니다.
List result=new ArrayList(8); 초기에 8개저장공간을 가진 ArrayList를 선언합니다. 8개를 초가하면 공간이 한번에 1.5배로 증가합니다.
for(int i=0;i<keywords.length;i++) i가 1씩증가하면서 위에있는 keywords의 길이 만큼 반복하는 for문입니다.
if(((String)keywords[i]).startsWith(keyword)){
result.add(keywords[i]);
}
이걸 반복하는데 if(((String)keywords[i]).startsWith(keyword) keywords의 i번째 요소가 keyword의 첫번째 글자와 일치하는지 체크하는 것입니다.
그럴 경우 result.add(keywords[i]);이거를 실행해서 result라는 List에 keywords의 i번째 요소를 추가합니다.
즉 현재 자바 이므로 자로 시작하는 글자가 모두다 result 배열에 저장되고 return result; 이걸로 인해서 result배열이 반환됩니다.
List keywordList=search(keyword); 다시 여기로 돌아와서 keywordList에 result 의 배여리 저장됩니다.
out.print(keywordList.size());여기를 만나면 keywordList의 갯수를 반환합니다 현재 자바이므로
{
"자바",
"자바 프로그래밍",
"자바스터디",
"자바서비스",
"자바캔"
}
이렇게 5개가 저장되어있으므로 5가 됩니다.
out.print("|"); 그리고 바로 이어서 | 를 출력하고
for(int i=0;i<keywordList.size();i++) 여기서 i가 1씩 증가하면서 keywordList의 길이만큼 반복합니다.
String key=(String)keywordList.get(i);
out.print(key);
if(i<keywordList.size()-1){
out.print(",");
}
String key=(String)keywordList.get(i); i번째 keywordList를 받아와서 key에 저장하고
out.print(key); 그key를 출력하고
if(i<keywordList.size()-1)i의값이keywordList의 길이 보다 하나 적을때까지만
out.print(","); ,를 출력합니다.
즉 그결과 5| 자바,자바 프로그래밍,자바스터디,자바서비스,자바캔 이것이 출력되고 전달 됩니다.
var resultText=httpRequest.responseText; 여기에 위의 내용이 저장되고
var result=resultText.split('|'); 여기서 | 를기준으로 나눠서 result에 저장하면
{"5","자바,자바 프로그래밍,자바스터디,자바서비스,자바캔 "}이 됩니다.
var count=parseInt(result[0]); count에 5를 저장하고
var keywordList=null; keywordList에 null을 저장하고 선언합니다.
if(count>0) count가 0보다 클때만 if문이 실행됩니다. 현재 5이므로 실행됩니다.
keywordList=result[1].split(','); "자바,자바 프로그래밍,자바스터디,자바서비스,자바캔 "를 , 를 기준으로 나눠서 배열로 만들면{"자바","자바 프로그래밍","자바스터디","자바서비스","자바캔 "}이 됩니다.
var html='';html을 빈문자열로 만든다음 선언하고
for(var i=0;i<keywordList.length;i++) 여기서 i가 1씩 증가하면서 {"자바","자바 프로그래밍","자바스터디","자바서비스","자바캔 "}의 길이만큼 반복됩니다.
html+="<a href=\"javascript:select('"+keywordList[i]+"')\">"+keywordList[i]+"</a><br/>";
html이라는 문자열에 위으 코드에 {"자바","자바 프로그래밍","자바스터디","자바서비스","자바캔 "}에서 한개씩 넣어서
5개의 문자열을 이어서 저장해줍니다.
그럼 a태그가 총 5개 저장됩니다.그 결과 html은<a href="javascript:select('자바')">자바</a><br><a href="javascript:select('자바 프로그래밍')">자바 프로그래밍</a><br><a href="javascript:select('자바스터디')">자바스터디</a><br><a href="javascript:select('자바서비스')">자바서비스</a><br><a href="javascript:select('자바캔 ')">자바캔 </a><br> 이 됩니다.
var listView=document.getElementById('suggestList'); 로 html에서 id가 suggestList인 요소를 찾아서 listView에 저장하고
listView.innerHTML=html; 찾은 그요소의 내부html내용을 위에정의한 html변수내용으로 바꺼줍니다.
show('suggest');가 발동 되면
function show(elementId){
var element=document.getElementById(elementId);
if(elementId){
element.style.display='';
}
}
var element=document.getElementById(elementId); 전달된 인자의 id를 가진 요소를 element에 저장 즉 여기서는 suggest 인 요소를 저장하고
if(elementId)전달된 인자가 존재하면 if 문실행
element.style.display=''; 찾은 요소의 display 속성을 지워서 눈에 보이게 만들어줍니다.
그결과
이렇게 완성됩니다.
}else 만약 count가 0보다 작으면
hide('suggest');를 실행하고
function hide(elementId){
var element=document.getElementById(elementId);
if(elementId){
element.style.display='none';
}
}
var element=document.getElementById(elementId); 전달된 인자의 id를 가진 요소를 element에 저장 즉 여기서는 suggest 인 요소를 저장하고
if(elementId)전달된 인자가 존재하면 if 문실행
element.style.display='none'; 찾은 요소의 display 속성을 none으로 설정해서 눈에 안보이게 만들어줍니다.
하지만 지금은 count가 5이므로 작동 되지 않습니다.
여기서 검색된 요소가 클릭되면 아까 html변수에 담았던 글자에서 연결 시켰던 select라는 함수가 실행됩니다. 해당 하수에 인자로는 눈에 보이는 해당 글자를 입력했습니다.
예시로 비<a href="javascript:select('자바캔')">자바캔</a><br></div> 이렇게 자바캔이 글자로 보이고 인자도 자바캔 이 들어갔습니다.
else httpRequest.status==200 이것이 false 이면 else문 실행하고
alert("에러발생:"+httpRequest.status); 에러발생이라고 창을 뛰워줍니다.
그리고 다시 sendKeyword함수로 돌아와서
}else{ keyword!=lastKeyword를 충족하지 못하면
hide('suggest'); id가 suggest인 요소를 숨겨주고
setTimeout("sendKeyword();",500) 다시 0.5초후에 sendKeyword();가 실행되고 무한 루프가 발생됩니다.
function select(selectedKeyword){
document.search.keyword.value=selectedKeyword;
loopSendKeyword=false;
checkFirst=false;
hide('suggest');
}
select함수가 실행되면document.search.keyword.value=selectedKeyword; 여기서 name이 search인 <form name="search"> 안에서
이름이 keyword인<input type="text" name="keyword" id="keyword" onkeydown="startSuggest()"/>를 찾게 되고 그 값을 전달 받은 인자로 바꺼주고
loopSendKeyword=false; loopSendKeyword를 초기 값으로 변경즉 false
checkFirst=false; checkFirst를 초기값으로 변경 즉 false
hide('suggest'); 를 실행시켜서 id가 suggest인 요소를 숨겨버립니다.
그러면 이렇게 되고 다시검색하면 lastkeyword만 자바캔이 되어있고 나머지는 똑같이 작동됩니다.
이런식으로 동작됩니다.
여기까지 완료했습니다.