jQuery UI AutoComplete in CakePHP

Demo : http://cbunny.rudylee.com/autocomplete

Demo source code : https://github.com/rudylee/cbunny
The post to add auto redirect feature into the AutoComplete : http://blog.rudylee.com/2011/12/12/auto-redirect-in-cakephp-jquery-autocomplete/
You can copy the modified Ajax and Javascript helpers from here https://github.com/rudylee/topping

Last week I was trying to use jQuery UI Autocomplete in my CakePHP apps. However, CakePHP Ajax and Javascript helpers don’t support jQuery by default. After googling a little bit, I found that this guy ( http://www.cakephp.bee.pl/ ) already made Ajax and Javascript helpers for jQuery.

So I just copied these helpers from his site and put it into my apps. It’s done ? obviously not. It turned out that the autocomplete script that he using in his helper is the old one ( http://docs.jquery.com/Plugins/autocomplete ).

Thus, I had to add a method inside that helper to use jQuery UI autocomplete. Here are the sample codes ( you can copy from my github for the complete file, this one is just snippet ) :

 /**
     * Options for auto-complete editor.
     *
     * @var array
     */
    var $autoCompleteOptions = array(
	'select', 'source'
    );

    /**
     * Create a text field with Jquery UI Autocomplete.
     *
     * Creates an autocomplete field with the given ID and options.
     * needs include jQuery UI Autocomplete file
     *
     * @param string $field DOM ID of field to observe
     * @param array $options Ajax options
     * @return string Ajax script
     * check out http://jqueryui.com/demos/autocomplete/
     */
    function autoComplete($field, $options = array()) {
	$var = '';
	if (isset($options['var'])) {
	    $var = 'var ' . $options['var'] . ' = ';
	    unset($options['var']);
	}

	if(isset($options['source'])) {
	    $options['source'] = "'".Router::url($options['source'])."'";
	}

	if (!isset($options['id'])) {
	    $options['id'] = Inflector::camelize(str_replace(".", "_", $field));
	}

	$htmlOptions = $this->__getHtmlOptions($options);
	$htmlOptions['autocomplete'] = "off";

	foreach ($this->autoCompleteOptions as $opt) {
	    unset($htmlOptions[$opt]);
	}

	$options = $this->_optionsToString($options, array('multipleSeparator'));
	$callbacks = array('formatItem', 'formatMatch', 'formatResult', 'highlight');

	foreach ($callbacks as $callback) {
	    if (isset($options[$callback])) {
		$name = $callback;
		$code = $options[$callback];
		switch ($name) {
		    case 'formatResult':
			$options[$name] = "function(data, i, max) {" . $code . "}";
			break;
		    case 'highlight':
			$options[$name] = "function(data, search) {" . $code . "}";
			break;
		    default:
			$options[$name] = "function(row, i, max, term) {" . $code . "}";
			break;
		}
	    }
	}
	$options = $this->_buildOptions($options, $this->autoCompleteOptions);

	$text = $this->Form->text($field, $htmlOptions);
	$script = "{$var} $('#{$htmlOptions['id']}').autocomplete(";
	$script .= "{$options});";

	return "{$text}\n" . $this->Javascript->codeBlock($script);
    }

And here are the sample to use it in our application

echo $this->Ajax->autoComplete('Guest.search', array(
    'source' => array(
	'controller' => 'users',
	'action' => 'autoComplete',
	'prefix' => 'host'
    ),
));

Action code :

 /**
     * Auto Complete Action for Host
     *
     * Auto Complete action for host list of guests
     * also process the search
     */
    function host_autoComplete() {
	if (!empty($this->data)) {
	    $this->redirect(array(
		'controller' => 'users',
		'action' => 'view', $this->data['Guest']['id']
	    ));
	}
	$this->autoRender = false;
	$guests = $this->User->getGuests(array(
		    'host_id' => Configure::read('User.id'),
		    'conditions' => array(
			'OR' => array(
			    'User.name LIKE' => '%' . $_GET['term'] . '%',
			    'User.surname LIKE' => '%' . $_GET['term'] . '%'
			)
		    )
		));
	echo json_encode($this->User->autoComplete_encode($guests));
    }

Model method ( encode the data array to display fields that we want, in this example I am just showing firstname and surname )

  /**
     * autoComplete encode
     *
     * Parsing passed array and change it to consume-able
     * by autocomplete jQuery UI
     * @param array $data
     * @return json $data
     */
    function autoComplete_encode($postData = array()) {
	$temp = array();
	foreach ($postData as $user) {
	    array_push($temp, array(
		'id' => $user['User']['id'],
		'label' => $user['User']['name'].' '.$user['User']['surname'],
		'value' => $user['User']['name'],
	    ));
	}
	return $temp;
    }

Don’t forget to use $_GET['term'] to get data from autocomplete field and also encode the data to JSON so it can be displayed by jQuery UI.

33 Comments on "jQuery UI AutoComplete in CakePHP"

  1. avatar riani says:

    ooh nice template….

  2. avatar Rudy says:

    riani ga ngeblog lagi ? :(

  3. avatar maydian says:

    waaa…. template baru.. mantap coiii..

  4. avatar Rudy says:

    iya donk… yang lama terlalu gloomy dan tulisannya kecil amat…

    yang ini lebih mantap dan jelas tulisannya

  5. avatar riani says:

    Saya tidak sejago anda lah Pak Rudy
    Jarang ngeblog saya :)

  6. avatar Rudy says:

    Ngeblog kan ga harus jago. Hiks

  7. avatar maydian says:

    Imba tepatnya wakkakaka

  8. avatar Rudy says:

    kalau kata kakek semua orang sudah terlahir imba :D

  9. Hello Rudy

    i have downloaded the code from github.com. the code does not have any helper file and you also did not instructed in a proper way that where the above code needs to be placed, like in which file and thus i am having problem to make the code working.
    Please let me know better instructions so that the code can work.
    Thanks
    Vaseem Ansari
    http://www.vaseemansari.com

  10. avatar Rudy says:

    Hi Vaseem,

    sorry for my confusing article :) . You can find the helpers file inside “view” folder and if you want to see how the code works, just see my demo apps source code https://github.com/rudylee/cbunny ( demo link http://cbunny.rudylee.com/autocomplete )

    I’ll restructure the article this weekend and make it straight forward. Thanks for your comment, cheers.

  11. avatar Renato says:

    Hi, I just downloaded your code and it does not work.
    I mean the javascript part. It says there is an error in :

    //

    I can see the rest of the page but the autocomplete textbox does not work. Any pointers??
    Thanks in advance.

  12. avatar Renato says:

    this is the error, I dunno why it doesn’t show in the first one. It says that Ajax hasn’t been defined

    //

  13. avatar Renato says:

    new Ajax.Autocompleter(‘UserSearch’, ‘UserSearch_autoComplete’, ‘/users/index/source:Array’, {});

  14. avatar Rudy says:

    can you paste your view code, controller code in the pastebin ? I can’t see the error messages.

    are you sure you have added the Ajax helper, Javascript helper, and jQuery UI + jQuery in your apps ?

  15. avatar Renato says:

    Thanks for the quick reply. What I did was to download all your code, and just try to run it, but I haven’t been able to.
    There is also a syntax error which I dunno where it is comming from, It says it comes from the jquery-ui “syntax error @ http://localhost/js/jquery-ui-1.8.14.custom.min.js:1
    but the generated code it shows is: http://pastebin.com/q4HZCNF1

    This is the code of the generated view: http://pastebin.com/rC4xN7fH there it says that the Ajax method can’t be found in the libraries.
    This is the default code.

  16. avatar Rudy says:

    the error says that it can’t find JsController which is my sample apps doesn’t have… I think the problem maybe lies in your rewrite / .htaccess settings.

    is there any chance you can drop in to #cakephp channel in FreeNode ? just message me, my nickname is ZhouYu.

  17. avatar Renato says:

    Thank you very much man!

  18. avatar Molotsi says:

    Hi Rudy,
    i cant seem to find the complete file you referring to in your github. I have downloaded cbunny but only controller and view files, and the ajax and javascript files from topping… Please assist

    I have been unfortunate for 3 days now not finding a working auto-complete solution

  19. avatar Rudy says:

    Hi Molotsi,

    I have fixed the cbunny repository in the github. There was a problem with the submodule which not download the topping folder. So I removed the submodule for the moment and include the topping folder inside the plugins folder.

    You can download it again and try it. Let me know if you still have issue with it.

  20. avatar Robert says:

    Hi,

    thank you for the autocomplete script. I did install it and it seems to work, however, I have no idea how to automatically redirect the user to the view page (ie. for “johndoo” to “users/view/1″) once the name is entered in the field.

    Thanks,

    Robert

  21. avatar Rudy says:

    Lucky for you, I just implemented exactly the same feature in my current project. Here what I did to achieve that :

    Form->create('autoComplete',array('url' => array('controller' => 'users', 'action' => 'autoComplete'),'id' => 'GuestForm'));
    echo $this->Form->hidden('Guest.id');
    echo $this->Ajax->autoComplete('Guest.search', array(
    'source' => array(
    'controller' => 'users',
    'action' => 'autoComplete',
    'prefix' => 'admin'
    ),
    'select' => 'function(event, ui){
    $("#GuestId").val(ui.item.id);
    $("#GuestForm").submit()}'
    ));
    ?>

    ‘select’ option would be triggered when user click the value inside the autocomplete form. As you can see from my code that I update the hidden field and submit the form when someone click the value inside the autocomplete form.

    Let me know if you have problem with it :)

  22. avatar raja says:

    Though this works for cakephp 1.3, I am trying to clone for cakephp 2.1+ version. Any clue in this direction would be more helpful.

  23. avatar Rudy says:

    hi Raja, I haven’t got any chance to clone it to CakePHP 2.1+. You might want to try this helper http://bakery.cakephp.org/articles/jozek000/2011/11/23/ajax_helper_with_jquery_for_cakephp_2_x. I haven’t test it yet, but it’s a good start.

    I’ll try to implement the autocomplete in Cake 2.0 in couple weeks and let you know. Cheers.

  24. avatar raja says:

    Dear Rudy,
    Thanks for such a quick response, being a starter in cakephp, I will wait for your tutorial/guidance and implementation . Thanks again.

  25. avatar Rudy says:

    Sorry, forgot to put the link to the helper. While you wait, you might want to try the helper in that bakery.

  26. avatar raja says:

    Dear Rudy,
    I tried the new AjaxHelper for cakephp 2.01. I tried to clone your controllers and index.ctp. Not being experienced in this frame work, I also took all those suggested suggestions by Andrew Perkins (http://www.youtube.com/watch?v=-oHofPGqPBo) but could not succeed in making autocomplete to work. Being quite old (nearly sixty years) and almost vision less I have no choice other than wait for your tutorials. Thanks for your links.

  27. avatar Rudy says:

    Hi Raja,

    I have tested the helpers from that link and it works perfectly. You just need to add another function in the Ajax helper to use jQuery UI Auto Complete( you can just copy the function from blog post above ). Anyway, I have made demo apps for you, here is the link : http://cbunny2.rudylee.com/users

    You can copy the source code from my github account here : https://github.com/rudylee/cbunny/tree/2.0 ( make sure you set up the database.php and import the SQL file ).

    Cheers

  28. avatar raja says:

    Dear Rudy,
    I just finished testing your new integration of ajax helper for cakephp 2+, works perfectly. My good wishes are with you, also I am certain other’s wishes also going to be with you whoever uses your guidance. Thanks again.
    -Raja

  29. avatar Rudy says:

    great, happy to hear that. cheers.

  30. avatar Awais says:

    thanks alot for this post, I am using cakephp2.0 and it works perfect for me… thanks for this great post :)

  31. avatar Milan Saha says:

    This is awesome. Perfectly works with cakephp 2.1.2 as well. Thanks Rudy.

  32. avatar Luke says:

    Hi Rudy,

    How would one go about making this plugin play nice with Jquery Mobile? I’d like to append a data-role tag, amongst other jquery-moble paramaters, to the list that is generated.

    Thanks!

  33. avatar Rudy says:

    Hi Luke,

    Sorry, I am not familiar with jQuery Mobile. I am suggesting you to write plain jQuery autocomplete function if you want to modify the data.

    That would be easier to debug and manage in the future. Use this post as a reference http://blog.rudylee.com/2013/02/02/select2-ajax-auto-complete-with-cakephp-2-0/

Got something to say? Go for it!