AutoComplete Control: Custom Function to Search Different Fields at Runtime

このExampleは、AutoCompleteを実装するにあたって、

  1. サーチをする関数を自作する(カスタム・サーチ)
  2. AutoCompleteの候補を表示するフォーマットをカスタマイズする

方法を説明している。

データは[area code, state]のArrayフォーマットになっており、このどちらでもサーチができるようなカスタムサーチを実装する。

以下は、state(アメリカの州の名前)でサーチした結果を、入力値の候補としている画面。

以下は、area codeでサーチした結果を、入力値の候補としている画面である。
それぞれ、サーチするもの(stateかarea code)によって、入力候補の出方が違うことが分かる。

上1を実現するには、

  • YAHOO.util.FunctionDataSourceを利用する。
  • カスタム・サーチの関数を定義する。
  • カスタムサーチの結果をこのDataSourceに定義する。

というやり方をとる。

また、2を実現するには、

  • YAHOO.widget.AutoComplete()の属性、formatResultを設定する

というやり方となる。

以下にHTMLの全文を示す

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
<html> 
<head> 
    <meta http-equiv="content-type" content="text/html; charset=utf-8"> 
<title>Ajax Sample</title> 
 
<style type="text/css"> 
body {
	margin:0;
	padding:0;
}
</style> 

<link rel="stylesheet" type="text/css" href="scripts/yui/fonts/fonts-min.css" /> 
<link rel="stylesheet" type="text/css" href="scripts/yui/autocomplete/assets/skins/sam/autocomplete.css" /> 
<script type="text/javascript" src="scripts/yui/yahoo-dom-event/yahoo-dom-event.js"></script> 
<script type="text/javascript" src="scripts/yui/animation/animation-min.js"></script> 
<script type="text/javascript" src="scripts/yui/datasource/datasource-min.js"></script> 
<script type="text/javascript" src="scripts/yui/autocomplete/autocomplete-min.js"></script> 

<style type="text/css" id="defaultstyle">
#main {
	margin: 2px;
	padding: 3px;
}

#myAutoComplete {
    width:15em; /* set width here or else widget will expand to fit its container */
    padding-bottom:2em;
}

</style>

<script type="text/javascript" src="scripts/yui/autocomplete/assets/js/data.js"></script> 
<script type="text/javascript"> 
YAHOO.util.Event.addListener(window, "load", function() {
	
	YAHOO.example.FnMultipleFields = function() {
	    // DataへのAlias
	    var allData = YAHOO.example.Data.arrayAreaCodesStates;
		
	    // stateでのsearchか、area codeでのsearchかを知るため。
	    // state; 1、area code; 0 <= YAHOO.example.Data.arrayAreaCodesStatesの並び順(配列の添え字)
	    // とあわせている。
	    var nSearchField;

	    // カスタム・サーチの定義(aQuery; 入力値)
	    // (注)サーチするするデータが、[areacode(number), state(string)]という形式であることに依存している。
	    var searchAreaCodesAndStates = function(sQuery) {
	        var allMatches = [],
	            item, i, l;
	            
	        // state; 1、area code; 0 <= YAHOO.example.Data.arrayAreaCodesStatesの並び順(配列の添え字)
	        nSearchField = (YAHOO.lang.isNumber(sQuery*1)) ? 0 : 1;

	        for(i=0, l=allData.length; i<l; i++) {
	        	//allData[i]の形式は、["201", "New Jersey"]。
	            item = allData[i];

	            // stateの処理;  nSearchField=1
	            // 小文字にして先頭も文字が一致すれば、allMatchesに格納する。
	            // State must be made case-insensitve and make the state return as index 0
	            if(nSearchField) {
	                if(item[nSearchField].toLowerCase().indexOf(sQuery.toLowerCase()) === 0) {
	                    allMatches[allMatches.length] = [item[1], item[0]];
	                }
	            }
	            // Area Codeの処理; nSearchField=0
	            // 先頭の数字が一致すれば、allMatchesに格納する。
	            // Area codes are simpler
	            else {
	                if(item[nSearchField].indexOf(sQuery) === 0) {
	                    allMatches[allMatches.length] = item;
	                }
	            }
	        }
	        
	        // States should be sorted alphabetically
	        // Define schema on the fly (since the return order changes)
        	// stateの処理;  ソート&(このallMatchesをDataSourceに食わせるので)DataSourceのfield定義
	        if(nSearchField) {
	            allMatches.sort();
	            this.responseSchema = {fields: ["state", "areacode"]};
	        }
        	// stateの処理;  ソート&DataSourceのfield定義
	        else {
	            this.responseSchema = {fields: ["areacode", "state"]};
	        }
	        return allMatches;
	    };

            // カスタム・サーチを使うために、FunctionDataSourceを定義し、カスタムサーチ関数(上で定義)を指定。
	    var oDS = new YAHOO.util.FunctionDataSource(searchAreaCodesAndStates);

	    // Instantiate AutoComplete
	    var oAC = new YAHOO.widget.AutoComplete("myInput", "myContainer", oDS);
	    oAC.useShadow = true;
	    // そのまま、データを使う。
	    oAC.resultTypeList = false;
	    // カスタム・サーチの出力フォーマットを定義
	    oAC.formatResult = function(oResultData, sQuery, sResultMatch) {
		// マッチした値(sResultMatch)と、検索するもの(state, areacode)でない方を()付で返却する。
	        return (sResultMatch + " (" + ((nSearchField) ? oResultData.areacode : oResultData.state) + ")");
	    };

	    return {
	    	fnSearch:searchAreaCodesAndStates, 
	    	oDS:oDS, 
	    	oAC:oAC
	    };
	}();
});
</script>
</head> 
 
<body class=" yui-skin-sam">
<div id="main">
<p>AutoCompleteのサンプルです。<br/>
stateもしくは、area codeでAutoCompeteします。
</p>
<h3>state もしくは、 area codeを入力してください:</h3> 
<div id="myAutoComplete"> 
	<input id="myInput" type="text"> 
	<div id="myContainer"></div> 
</div>
</div>
</body> 
</html>