입력 필드에 타이핑을 하면 관련 정보를 보여주고 선택할 수 있는 기능이 많이 사용됩니다. jQuery UI에서 제공되는 autocomplete 기능을 사용해서 이 기능을 구현해 봅니다.
1. 필요한 파일 인클루드하기
jQuery UI 스타일 시트 파일과 jQuery 파일, jQuery UI 파일이 필요합니다. 각각은 다운로드 받아서 사용해도 되고 CDN 을 이용해서 사용해도 됩니다. 이 예제에서는 CDN을 사용했습니다.
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
2. 기본 기능 사용하기
<script type="text/javascript">
//<![CDATA[
$(function() {
var availableCity = ["서울","부산","대구","광주","울산"];
$("#city").autocomplete({
source: availableCity,
select: function(event, ui) {
console.log(ui.item);
},
focus: function(event, ui) {
return false;
//event.preventDefault();
}
});
});
//]]>
</script>
<div class="ui-widget">
<label for="city">도시: </label>
<input id="city">
</div>
id가 city 인 입력 필드에 자동완성기능을 만듭니다.
- $("#city").autocomplete() : 자동완성기능을 만듭니다.
- source: avalibleCity : 타이핑시 보여질 내용 입니다.
- select: function(event, ui){}; : 아이템 선택시 실행됩니다. ui.item 이 선택된 항목을 나타내는 객체입니다. 선택된 옵션의 label과 value 값을 가집니다.
- focus: function(event, ui){ return false;} : jQuery UI autocomplete를 한글과 사용할때 커서를 사용해서 아이템을 선택하면 나머지가 사라져 버리는 버그가 있습니다. 이 코드를 추가하면 해결됩니다. return false; 또는 event.preventDefault(); 를 사용해서 이벤트를 무시하게 하는 것입니다.
3. 원격 데이터 조회
입력한 데이터를 서버로 보내 데이터를 조회해서 자동완성으로 출력하는 예제입니다. 서버쪽에서는 검색된 데이터를 json 형식으로 보냅니다.
<script type="text/javascript">
//<![CDATA[
$(function() {
$("#city").autocomplete({
source: "search.php",
minLength: 2,
response: function(event, ui) {
console.log(ui);
},
select: function(event, ui) {
console.log("Selected:" + ui.item.value);
},
focus: function(event, ui) {
return false;
}
});
});
//]]>
</script>
- source: "search.php" : 입력시 서버쪽에서 실행될 스크립트 입니다.
- minLength: 2 : 두자 이상이 입력될 때 서버로 요청을 보냅니다. 영어는 알파벳 두자, 한글을 글자 두자 입니다. 서버쪽으로의 트래픽도 줄이고, 검색된 데이터의 양이 너무 많아지는 것을 방지하는 역할을 합니다.
- response: function(event, ui) {} : 서버에서 응답이 오면 화면에 리스트를 보여주기 전에 실행됩니다. ui는 서버로 부터 보내온 배열 데이터입니다.
- select: function(event, ui) {} : 검색된 리스트에서 항목을 선택하면 실행됩니다.
- focus: function(event, ui) {return false;} : 한글 리스트에서 선택시 리스트가 사라지는 오류 방지용 입니다.
4. 원격 데이터 조회시 서버측 코드 입니다.
예제용으로 간단히 배열에서 찾는 것으로 만들었습니다. 실제 응용에서는 데이터베이스에서 검색하여 반환하는등의 코드가 될 것입니다.
jQuery UI autocomplete에서 원격으로 요청시 검색어의 파라미터를 "term" 입니다. 코드 설명은 주석을 참조해 주세요.
<?php
// 컨텐츠 타입을 json으로 지정합니다.
header("Content-Type: application/json");
// 검색될 샘플 데이터 입니다.
$cities = array("서울","부산","대구","광주","울산");
// 넘어온 검색어 파라미터 입니다.
$term = $_GET['term'];
// 데이터를 루핑 하면서 찾습니다.
$result = [];
foreach($cities as $city) {
if(strpos($city, $term) !== false) {
$result[] = array("label" => $city, "value" => $city);
}
}
// 찾아진 데이터를 json 데이터로 변환하여 전송합니다.
echo json_encode($result);
?>
5. 하나의 입력 필드에 여러개의 값을 선택할수 있게 합니다.
콤마(,)로 분리해서 하나의 입력 필드에 여러개의 값을 선택할 수 있게 하는 방법입니다.
<script type="text/javascript">
//<![CDATA[
$(function() {
function split( val ) {
return val.split( /,\s*/ );
}
function extractLast( term ) {
return split( term ).pop();
}
$("#city")
// 항목을 선택할때 탭으로 이동하지 못하게 한다.
.on("keydown", function( event ) {
if(event.keyCode === $.ui.keyCode.TAB && $(this).autocomplete("instance").menu.active) {
event.preventDefault();
}
})
.autocomplete({
source: function( request, response ) {
$.getJSON( "search.php", {term: extractLast(request.term)}, response);
},
search: function() {
// 최소 입력 길이를 마지막 항목으로 처리합니다.
var term = extractLast(this.value);
if(term.length < 2) {
return false;
}
},
focus: function() {
return false;
},
select: function(event, ui) {
var terms = split(this.value);
// 현재 입력값 제거합니다.
terms.pop();
// 선택된 아이템을 추가합니다.
terms.push(ui.item.value);
// 끝에 콤마와 공백을 추가합니다.
terms.push("");
this.value = terms.join(", ");
return false;
}
});
});
//]]>
</script>
6. 기존의 콤보박스에 자동완성 기능 부여하기
콤보박스를 입력가능하게 하여 자동완성 기능을 사용할 수 있도록 할 수 있습니다.
새로 생성될 위젯의 스타일을 지정합니다.
<style>
.custom-combobox {
position: relative;
display: inline-block;
}
.custom-combobox-toggle {
position: absolute;
top: 0;
bottom: 0;
margin-left: -1px;
padding: 0;
}
.custom-combobox-input {
margin: 0;
padding: 5px 10px;
}
</style>
콤보박스 입니다. 여기에 자동완성 기능을 사용 가능하도록 커스텀 위젯으로 교체가 되는 것입니다.
<div class="ui-widget">
<label for="city">도시: </label>
<select id="city">
<option value="서울">서울</option>
<option value="부산">부산</option>
<option value="대구">대구</option>
<option value="광주">광주</option>
<option value="울산">울산</option>
</select>
</div>
자동완성 기능을 수행하는 커스텀 위젯을 생성하는 코드 입니다. 기능을 주석을 참조해 주세요.
<script type="text/javascript">
//<![CDATA[
$(function() {
$.widget("custom.combobox", {
_create: function() {
this.wrapper = $("<span>").addClass("custom-combobox").insertAfter(this.element);
this.element.hide();
this._createAutocomplete();
this._createShowAllButton();
},
_createAutocomplete: function() {
var selected = this.element.children(":selected"), value = selected.val() ? selected.text() : "";
this.input = $("<input>")
.appendTo(this.wrapper)
.val(value)
.attr("title", "")
.addClass("custom-combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left")
.autocomplete({
delay: 0,
minLength: 0,
source: $.proxy(this, "_source"),
// 한글 항목 커서로 선택시 오류방지
focus: function(event, ui) {
return false;
},
select: function(event, ui) {
// 선택했을때 처리가 여기에 옵니다.
}
})
.tooltip({
classes: {"ui-tooltip": "ui-state-highlight"}
});
this._on( this.input, {
autocompleteselect: function( event, ui ) {
ui.item.option.selected = true;
this._trigger( "select", event, {item: ui.item.option});
},
autocompletechange: "_removeIfInvalid"
});
},
_createShowAllButton: function() {
var input = this.input, wasOpen = false;
$("<a>")
.attr("tabIndex", -1)
.attr("title", "모두보기")
.tooltip()
.appendTo( this.wrapper )
.button({
icons: {primary: "ui-icon-triangle-1-s"},
text: false
})
.removeClass( "ui-corner-all" )
.addClass("custom-combobox-toggle ui-corner-right")
.on("mousedown", function() {
wasOpen = input.autocomplete("widget").is(":visible");
})
.on("click", function() {
input.trigger( "focus" );
// 이미 보여지고 있다면 닫습니다.
if(wasOpen) {
return;
}
// 모든 결과 출력을 위해서 빈문자열을 보냅니다.
input.autocomplete("search", "");
}
);
},
_source: function(request, response) {
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
response( this.element.children("option").map(function() {
var text = $(this).text();
if(this.value && (!request.term || matcher.test(text))) {
return {
label: text,
value: text,
option: this
};
}
}));
},
_removeIfInvalid: function(event, ui) {
// 아이템을 선택합니다. 아무것도 하지 않습니다.
if(ui.item) {
return;
}
// 일치하는것을 찾습니다. (대소문자를 구분하지 않습니다.)
var value = this.input.val(), valueLowerCase = value.toLowerCase(), valid = false;
this.element.children( "option" ).each(function() {
if($(this).text().toLowerCase() === valueLowerCase) {
this.selected = valid = true;
return false;
}
});
// 일치하는것을 찾으면 아무것도 하지 않습니다.
if(valid) {
return;
}
// 빈값 항목을 삭제합니다.
this.input
.val("")
.attr("title", value + " 일치하는 항목이 없습니다.")
.tooltip("open");
this.element.val("");
this._delay(function() {
this.input.tooltip("close").attr("title", "");
}, 2500);
this.input.autocomplete("instance").term = "";
},
_destroy: function() {
this.wrapper.remove();
this.element.show();
}
});
$("#city").combobox();
});
//]]>
</script>
jQuery UI autocomplete 위젯을 사용하여 자동완성 기능을 만들어 보았습니다. 자세한 기능들은 데모페이지(http://jqueryui.com/autocomplete/)와 API 문서(http://api.jqueryui.com/autocomplete/) 를 참조하시면 되겠습니다.
'프로그래밍 > 자바스크립트' 카테고리의 다른 글
새창을 여는 window.open() 함수 사용법 (15) | 2018.06.27 |
---|---|
AX5UI - toast를 사용한 시스템 메세지 출력하기 (0) | 2018.05.15 |
자바스크립트 주기적인 실행(setInterval, setTimeout) (0) | 2018.04.20 |
jQuery .load() 메소드 - 페이지 내용 동적 교체 (0) | 2018.04.20 |
jQuery UI datepicker - 자바스크립트 달력 사용하기 (2) | 2018.04.20 |