CakePHP – jQuery Autocomplete Tutorial

CakePHP – jQuery Autocomplete Tutorial

In this tutorial, i will show you how to implement jQuery UI’s autocomplete widget in cakephp. The script in this tutorial is copy paste from tutorialzine article “A Simple Movie Search App w/ jQuery UI” . We are using a MySql database containing a users table. When you start typing a user name in the text box of the search form, an AJAX request is sent to controller. The controller returns a JSON object with suitable user name.

This is what we’re going to create:

CakePHP – jQuery Autocomplete Tutorial

CakePHP – jQuery Autocomplete Tutorial



MySQL Table

CREATE TABLE `users` (
 `id` int(10) unsigned NOT NULL auto_increment,
 `username` text,
 `profile_pictures` varchar(64) default NULL,
 `created` datetime default NULL,
 `modified` datetime default NULL,
 PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=31 DEFAULT CHARSET=latin1

routes.php

<?php
//file:app/config/routes.php
 Router::connect('/', array('controller' => 'users', 'action' => 'home'));
/**
 * ...and connect the rest of 'Pages' controller's urls.
 */
 Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
?>

On apps first load, we will redirect the apps to home action in users controller.

default.ctp

<?php
//file:app/view/layout/default.ctp
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<?php echo $this->Html->charset(); ?>
	<title>
		<?php __('CakePHP: the rapid development php framework:'); ?>
		<?php echo $title_for_layout; ?>
	</title>
	<?php
		echo $this->Html->meta('icon');

		echo $this->Html->css('cake.generic');

		echo $scripts_for_layout;
	?>
</head>
<body>
	<div id="container">
		<div id="header">
			<h1><?php echo $this->Html->link(__('CakePHP: the rapid development php framework', true), 'http://cakephp.org'); ?></h1>
		</div>
		<div id="content">

			<?php echo $this->Session->flash(); ?>

			<?php echo $content_for_layout; ?>

		</div>
		<div id="footer">
			<?php echo $this->Html->link(
					$this->Html->image('cake.power.gif', array('alt'=> __('CakePHP: the rapid development php framework', true), 'border' => '0')),
					'http://www.cakephp.org/',
					array('target' => '_blank', 'escape' => false)
				);
			?>
		</div>
	</div>
	<?php echo $this->element('sql_dump'); ?>
	<?php echo $javascript->link('http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js');?>
	<?php echo $javascript->link('http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/jquery-ui.min.js');?>
	<?php echo $javascript->link('application.js');?>
</body>
</html>

In deafult.ctp we are are included jQuery, jQuery UI and our own script “application.js” (will create later).

users_controller.php

<?php
//file:app/controller/users_controller.php
<?php
class UsersController extends AppController {

	var $name = 'Users';
	var $helpers = array('Ajax', 'Javascript');
	var $components = array('RequestHandler');

	function home(){
	}

	function search(){
		if ( $this->RequestHandler->isAjax() ) {
   			Configure::write ( 'debug', 0 );
   			$this->autoRender=false;
			$users=$this->User->find('all',array('conditions'=>array('User.username LIKE'=>'%'.$_GET['term'].'%')));
				$i=0;
				foreach($users as $user){
					$response[$i]['value']=$user['User']['username'];
					$response[$i]['label']="<img class=\"avatar\" width=\"24\" height=\"24\" src=".$user&#91;'User'&#93;&#91;'profile_pictures'&#93;."/><span class=\"username\">".$user['User']['username']."</span>";
				$i++;
				}
			echo json_encode($response);
		}else{
			if (!empty($this->data)) {
				$this->set('users',$this->paginate(array('User.username LIKE'=>'%'.$this->data['User']['username'].'%')));
			}
		}
	}

}
?>

In users_controller.php we need to included ruquestHandler component. The Request Handler component is used in Cake to determine information about the incoming HTTP request. In this tutorial we will used to detect incoming ajax request. We have two action in users_controller home() and search. Home action is used to default page. Search action is action which we will call from our script.

home.ctp

//file:app/views/users/home.ctp
<div class="users form">
	<?php echo $this->Form->create('User',array('action'=>'search'));?>
	<?php
		echo $this->Form->input('username',array('type'=>'text','id'=>'username','label'=>'Search'));
	?>
	<?php echo $this->Form->end(__('Submit', true));?>
</div>
<p><a href="http://blogfreakz.com/">Read & Download on Blogfreakz</a></p>

application.js

////file:app/webroot/js/application.js
$(document).ready(function(){
// Caching the movieName textbox:
var username = $('#username');

// Defining a placeholder text:
username.defaultText('Search for people');

// Using jQuery UI's autocomplete widget:
username.autocomplete({
minLength    : 1,
source        : 'users/search'
});

});

// A custom jQuery method for placeholder text:

$.fn.defaultText = function(value){

var element = this.eq(0);
element.data('defaultText',value);

element.focus(function(){
if(element.val() == value){
element.val('').removeClass('defaultText');
}
}).blur(function(){
if(element.val() == '' || element.val() == value){
element.addClass('defaultText').val(value);
}
});

return element.blur();
}

The search terms, that the user has entered into the search box, are available in $_GET[‘term’]. Calling the search() method with these terms.The search method will return JSON object, here is sample response:

[{"value":"Webmestre Jobillico","label":"<img class=\"avatar\" width=\"24\" height=\"24\" src=http:\/\/graph.facebook.com\/100001094382363\/picture\/><span class=\"username\">Webmestre Jobillico<\/span>"},{"value":"Web Panorama","label":"<img class=\"avatar\" width=\"24\" height=\"24\" src=http:\/\/graph.facebook.com\/100001449013053\/picture\/><span class=\"username\">Web Panorama<\/span>"},{"value":"Wynnia Savitrie","label":"<img class=\"avatar\" width=\"24\" height=\"24\" src=http:\/\/graph.facebook.com\/100000881073253\/picture\/><span class=\"username\">Wynnia Savitrie<\/span>"},{"value":"Marsie Wilbourn Holton","label":"<img class=\"avatar\" width=\"24\" height=\"24\" src=http:\/\/graph.facebook.com\/705486368\/picture\/><span class=\"username\">Marsie Wilbourn Holton<\/span>"}]

autocomplete.css

/** //file:app/webroot/css/autocomplete.css **/
/** search container **/
.users{
	width:640px;
	margin:0 auto;
	min-height:225px;
}
#content p{
	width:640px;
	margin:0 auto;
	text-align:center;
}
#username{
	border:1px solid silver;
	padding:3px 10px;
	clear:none;
	width:460px;
}
.input{
	clear:none;
	float:left;
}
.submit{
	clear:none;
	float:right;
	padding:20px 0;
}

/* Styling the markup generated by the autocomplete jQuery UI widget */

ul.ui-autocomplete{
	width:250px;
	background-color:white;
	border:1px solid gray;
	margin-left:3px;
	margin-top:-4px;
	font-family:Helvetica, Arial,sans-serif;
}

ul.ui-autocomplete li{
	list-style:none;
	border-top:1px solid white;
	border-left:1px solid white;
	margin:0;
}

ul.ui-autocomplete li:first-child{
	border-top:none;
}

ul.ui-autocomplete li:last-child{
	border-bottom:none;
}

ul.ui-autocomplete li a{
	border:none !important;
	text-decoration:none !important;
	padding:2px;
	display:block;
	color:black;
}
ul.ui-autocomplete li img{
	margin-right:4px;
}
ul.ui-autocomplete li span{
}

#ui-active-menuitem{
	background-color:#efefef;
	cursor:pointer;
}

Wrapping Up
This tutorial showed how to implement autocomplete in cakephp. With jquery UI autocomplete widget, the creation of autocomplete become more easier. Cakephp has requesHandler component that we can used to determine the incoming request. Hope you find this tutorial is useful for you.

Source: http://blogfreakz.com/cakephp/cakephp-jquery-autocomplete-tutorial/

Pin It on Pinterest

Share This