カテゴリー別アーカイブ: UI

CakePHP + jQuery UI 1.8 autocomplete

このエントリーをはてなブックマークに追加
はてなブックマーク - CakePHP + jQuery UI 1.8 autocomplete
Share on Facebook
LINEで送る
Share on LinkedIn
Pocket

jQuery UI 1.8から搭載されたautocomplete

フォームの入力の手間を減らすいいものがないかなって思っていたところ、自動的に入力候補を表示してくれる機能をみつけました。

suggestとかautocompleteっていうみたい。

yaほーとかgoogleとかの検索窓で自動で表示されるあれです。

最初はjQueryのプラグインで探すと、以下の2つのプラグインがみつかりました。

  • autocomplete
  • suggest

でもautocompleteは、FireFoxで思ったように動作してくれませんでした。
もう1つのものをためしてみようかなって思っていました。
そのとき、jQueryUI1.8でautocomplete機能が搭載されていることを知り、
CakePHP で動作を確認してみました。

完成イメージ

autocomplete

概要

  • jQueryとjQueryUIのダウンロード(省略)
  • jQueryとjQueryUIの設定
  • autocompleteの設定
  • データを取得し入力候補を表示する(ここではDBからデータを取得するようにする)

jQueryUIの設置

ここから1.8バージョンをダウンロード
ダウンロードしたものを展開し、以下のように配置する。
(追記:20011/04/22)最新のものをDLしてください

  • app/webroot/js/にjquery-1.4.2.min.js、jquery-ui-1.8.2.custom.min.js
  • app/webroot/css/にsmoothnessフォルダ全部

jQueryUI のautocompleteのイメージ

autocompletイメージ

サンプル用のModelの作成

ここではExampleモデルを作成しました。
フィールドは適当に。。。
id, title, place……..

コードの作成

app/views/layouts/default.ctp

<head>
	<?php echo $this->Html->charset(); ?>
	<title>
		<?php echo $title_for_layout; ?>
	</title>
	<?php
		echo $this->Html->meta('icon');

	//==================================================
	// CSS
	//==================================================
		echo $this->Html->css('cake.generic');
		echo $this->Html->css('smoothness/jquery-ui-1.8.2.custom');
        //==================================================
	// jQuery関連
	//==================================================
		echo $this->Html->script('jquery-1.4.2.min');
		echo $this->Html->script('jquery-ui-1.8.2.custom.min');

		echo $scripts_for_layout;
	?>
</head>

なんでもいいのですが、とりあえずMainControllerを作成

<?php
class MainController extends AppController{
	public $name = 'main';
	public $uses = array(
		'Example',
	);
	//========================================	
	// メソッド
	//========================================
	function index(){
		
	}
	// autocomplete用
	function autocomplete(){
		$this->layout = '';
		$field = $this->params['url']['f'];
		$term = $this->params['url']['term'];
		$whitelist = array(
			'place',
			'title',
		);
		if(!in_array($field, $whitelist)){
			return;
		}
		// 入力値 無:全てのデータの中から10件返す。
		// 入力値 有:入力値を含むデータを10件返す
		$condition = array();
		if(!empty($term)){
			$condition = array('Example.'.$field.' like' => "%".$term."%");
		}
		$query = array(
			'fields' => array($field),
			'conditions' => $condition,
			'limit' => 10,
			'order' => array('Example.'.$field => 'ASC'),
			'group' => $field,
		);
		$data = array();
		$items = $this->Example->find('all', $query);
		
		foreach ($items as $item) {
			$cnt = array_push($data, $item['Example'][$field]);
		}
		
		// JSON形式の文字列を生成
		$json = json_encode( $data );   // PHP 5.2未満ではPECLのjsonモジュールが必要みたいです。
		echo $json;
	}
}
?>

GETで送信されたデータを取得し、DBからデータを取得します。
取得したデータをJSON形式に変換して送り返します。

上のコードでは、DBのフィールド名を受け取っているため、
何でもかんでも送信されてしまうと、DBの情報がダダ漏れになります。

したがって、whitelistの配列に取得OKのフィールド名を追加し、
なければ、データを取得できないようにしています。

app/views/main/index.ctp(CakePHP 1.3形式で書いています。)

<h1>AutoComplete</h1>

<?=$form->create('Example', array('action' => 'index'))?>
	<?=$form->input('title')?>
	<?=$form->input('place')?>
	<?=$form->input('comment')?>
<?=$form->end('送信')?>
<?=$html->scriptStart()?>
	$(function() {
			$('#ExamplePlace').autocomplete({source : '<?php echo $html->webroot("main/autocomplete?f=place")?>'})
				.autocomplete('option', 'minLength', 0);
	});
<?=$html->scriptEnd()?>

source:
データを取得するURL。
もしくは、[“hoge”, “geho”, “ahe”]というように記述してもOK。

入力値のデータ(term=入力値)以外のデータを送りたい場合は、下記のように通常のGET送信すればOK。
“main/autocomplete?f=place”

つまり、
“main/autocomplete”では、
main/autocomplete?term=hogeのように送信され、
“main/autocomplete?f=place”では、
main/autocomplete?f=place&term=hogeのように送信されます。

minLength:
データを検索し始めるまでの文字数です。デフォルトは1文字。
ここではDBから取得するときに制限をかけていますが、
1文字だけだと、表示されるデータが多すぎる場合があるので、ここの値で調整します。

その他のオプション等は、jQueryUIのHPをご覧下さい。

追記
autocompleteの処理はComponent化してみました。

==追記:2011/04/22================

//hoge_controller.php
	function autocomplete(){
		if(!$this->RequestHandler->isAjax()){
			$this->redirect('hogehoge');
		}
		$whitelist = array(
			'foo',
			'bar',
		);
		$get = $this->params['url'];
		if(!empty($get['term'])){
			$data = $this->JuAutocomplete->getData('Hoge', $whitelist);
		}else{
			// 空でリクエストが来た場合の処理
			$data = array();
			switch ($get['field']) {
				case 'foo':
					$data = array(
					);
					break;
				case 'bar':
					$data = array(
					);
					break;
				default:
					;
				break;
			}
		}
		$this->_renderJson($data);
	}

jsonを返す処理は下記を参照。
[CakePHP]Ajax処理のJSON出力を共通化する
=========================

参考サイト:
[jQuery UI] jQuery UI1.8で追加されたウィジェット(Autocomplete編)