jquery ui autocompleteをjson形式でcakephp1.3から使用する

 ツイート 1  シェア 0  Hatena 0

keyboard-mac

この記事はjquery ui autocomplete をcakephp1.3からjsonを出力して使用する方法について解説しています。

cakephpからjsonを出力する方法は下記エントリが参考になるかと思います。
cakephp1.3でjsonを出力する方法

環境

  • jquery 1.6.4
  • jquery-ui 1.8.16
  • cakephp 1.3

目次

  1. ファイルの準備
  2. コントローラ作成
  3. ビュー作成
  4. ブラウザからアクセスして動作確認

ファイルの準備

下記からjquery ui autocompleteのファイル一式をダウンロード。
http://jqueryui.com/download/

autocomplete0
下記にチェックを入れてダウンロード。

  • Core
  • Widget
  • Position
  • Autocomplete

ダウンロードしたファイルを解凍し、jsフォルダとcssフォルダ以下のファイルをcakephpのwebrootディレクトリにコピー。


jquery-ui-1.8.16.custom/js/*
jquery-ui-1.8.16.custom/css/*

下記の構成になっていればOKです


/webroot/js/jquery-1.6.4.min.js
/webroot/js/jquery-ui-1.8.16.custom.min.js
/webroot/css/ui-lightness/…

コントローラ作成

/app/controllers/samples_controller.php


<?php
class SamplesController extends AppController {

	var $name = 'Samples';
	var $uses = array();
	var $helpers = array('Html', 'Form', 'Js');
	var $components = array('RequestHandler');
	var $layout = 'default';

	function index(){
		pr($this->data);
	}

	function getjson() {
		
		//サンプルでDBとつなぐのは大変なのでひとまず配列でデータ作成。
		$data = array();
		$data[]['Sample'] = array('id'=>'1', 'name'=>'name1');
		$data[]['Sample'] = array('id'=>'2', 'name'=>'name2');
		$data[]['Sample'] = array('id'=>'3', 'name'=>'name3');
		
		//DBと連動させる場合は下記を参考に
		/*
		//パラメータはGETで送信されてくる。キーはterm
		if ($this->params['url']['term'] != '') {
			$params['conditions'] = array('name LIKE' => $this->params['url']['term'] . '%');
		}
		$params['fields'] = array('id', 'name');
		$data = $this->Model->find('all', $params);
		*/
		
		//_renderJson関数に渡すためにデータを加工
		$forJson = array();
		foreach ($data as $key1 => $value1) {
			foreach ($value1 as $key2 => $value2) {
				$forJson [] = $value2;
			}
		}
		
		//json出力
		$this->_renderJson($forJson);
	}


	function _renderJson($contents=array(), $params=array()) {
		$params = Set::merge(array(
			'header' => true,
			'debugOff' => true,
		), $params);
		if ($params['debugOff']) {
			Configure::write('debug', 0);
		}
		if ($params['header']) {
			$this->RequestHandler->setContent('json');
			$this->RequestHandler->respondAs('application/json; charset=UTF-8');
		}
	
		$this->layout = false;
		$this->set(compact('contents'));
		$this->render('/ajax/json');
	}
}

_renderJson関数はあちこちで使うのでapp_controller.php等に記述したほうがいいと思います。

ビュー作成

/app/views/samples/index.ctp


<?php echo $this->Form->create(); ?>
<?php echo $this->Form->hidden('sample_id'); ?>
<?php echo $this->Form->text('sample_name'); ?>
<input type="submit" class="button" value="送信" />
<?php echo $this->Form->end(); ?>
<?php
echo $this->Html->script(array('jquery-1.6.4.min.js', 'jquery-ui-1.8.16.custom.min.js'
));
echo $this->Html->css(array('ui-lightness/jquery-ui-1.8.16.custom.css'
));
$script = <<<SCRIPT
$(function() {
	$("#sample_name").autocomplete({
		source: function( request, response ) {
			$.ajax({
				url: "/samples/getjson",
				dataType: "json",
				data: {
					term: request.term
				},
				success: function(data) {
					response($.map(data, function(item) {
						return {
							id: item.id,
							label: item.name,
							value: item.name
						}
					}));
				}
			});
		},
		select: function( event, ui ) {
			$("#sample_id").val(ui.item.id);
		},
		minLength: 0
	});
});
SCRIPT;
echo $this->Html->scriptBlock($script);

/app/views/ajax/json.ctp


<?php
echo $this->Js->object($contents);

ブラウザからアクセスして動作確認

/samples/indexにアクセス。テキストボックス上でキーボードの下を入力したりnameと入力したりして動作確認。

候補を選択するとidの値がhiddenにセットされ、nameの値がテキストボックスにセットされる。
送信ボタンをクリックしてformの値を確認。

autocomplete1

 ツイート 1  シェア 0  Hatena 0

コメント

  1. jquery-ui-1.8.16
    jquery-1.6.3
    では、json.ctpで$this->params[‘url’][‘callback’]にはいっている、
    “JQueryxxxxxx_xxxx”を出力しないと認識しませんでした。
    そういう仕様なんですかね???

    サンプル

    echo $this->params[‘url’][‘callback’] .’(‘ . $this->Js->object($contents) . “);”;

  2. urlのGETパラメータにcallbackキーがあるということは、$.ajaxメソッドのdataTypeに “jsonp”を指定されていませんか。
    jsonpを指定されるようでしたら、php側でもjsonpフォーマットでレスポンスを返す必要があります。

    dataTypeに”json”を指定すれば、サンプルのコードはjquery-1.6.3、query-ui-1.8.16のバージョンでも動作します。
    ご確認ください。