Auto redirect in CakePHP jQuery AutoComplete

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

Demo source code : https://github.com/rudylee/cbunny

In my previous post ( http://blog.rudylee.com/2011/07/25/jquery-ui-autocomplete-in-cakephp/ ) we have successfully integrated the jQuery AutoComplete with CakePHP with a little bit hacky way. Now we gonna add another feature that can redirect user to our desired place when they click the result value in the AutoComplete ( try the demo for more details ).

So let’s start the coding ( I assume you have integrated the jQuery UI AutoComplete in your apps, if you haven’t, just read my previous post ), so basically what we need to do are divided into 4 steps:

  • Wrap the jQuery UI AutoComplete search field in a form tag.
  • Add a hidden field which will hold the ID of the result.
  • Add ‘select’ option into the helper.
  • Set up the action that will handle the form submit

Here is the sample code :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
    echo $this->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()}'
    ));
    ?>
    </form>

As you can see in line 1, I defined the form and the controller + action that will handle the form submit. Line 2 is the hidden field that will hold the ID of the result. Line 3 is the AutoComplete form, I have added select option into the helper which will run the function defined to it each time user click the result. Line 10 means that the hidden field ( field that has ID GuestID ) will have value based on the AutoComplete Item ID ( which came from ui.item.id) and Line 11 will submit the form.

Here is the sample of the action code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    function admin_autoComplete() {
	if (!empty($this->data)) {
	    $this->redirect(array(
		'controller' => 'users',
		'action' => 'view', $this->data['Guest']['id']
	    ));
	}
	$this->autoRender = false;
	$guests = $this->User->getGuests(array(
	    'conditions' => array(
		'OR' => array(
		    'User.name LIKE' => '%' . $_GET['term'] . '%',
		    'User.surname LIKE' => '%' . $_GET['term'] . '%'
		)
	    )
		));
	echo json_encode($this->User->autoComplete_encode($guests));
    }

Just ignore line 8 and so, we gonna focus on line 2 to 7. In that line, I redirect the user to the view action which based on the Guest ID which I got from the form. You can change the controller/action in this section. I hope everything is clear. Cheers.

Holiday has arrived

Today is the last day of my exams and I will have holiday for 3 months. It’s quite long considering that you spent the same amount of time for study as well. That means in one semester you will have 3 months study and another 3 months for holiday. From my perspective, it’s not efficient, wasting time and of course wasting money :D . But who am I to judge the system, the system is there for a reason which I don’t care much.

So what is my plan for holiday ? not sure, I was planning to go back to Indonesia but looks like I am gonna trapped here with a bunch of works to do. I wish I can surprise my girlfriend by I suddenly appear at her rented room and let her hug me tightly like in the movies but looks like that impossible to happen at the moment. I hope she can understand ( I know she can’t :( ).

By the way, I have a number of tasks that need to be done during this break. First thing is to renew my passport which will be expired in January 2012. Without this passport, I can’t go back to Indonesia because you need to have passport that expired more than 6 months if you are planning to go overseas. That’s what I have been told, not sure whether it’s true or not. It cost around 40$ to get a new passport, not too expensive considering the living cost in here is far different from Indonesia ( 40$ is just like 200k in Indonesian rupiah ).

The second thing is to find new place to stay that closer to my university. My current place is not bad at all considering I have lived there for almost 1 year, quite comfortable with the people that live there and it’s just around 20-30 minutes walk from my university. But, I think it’s better if I can find a place that nearer to my university and of course cheaper :D

The third one and the final one is to complete pending projects that have been waiting for months. Most of them are fun projects which I created to learn new technology. Fascinating, but the reality is not easy as it looks especially because I am well-known for being undisciplined and unmotivated person.

That’s all my story for this month, still need to write a blog post for last month :D

Picture is taken from http://www.flickr.com/photos/8810648@N03/3048143981/

Short conversation with my mom

Sepenggal perbincangan di telepon dengan nyokap…

Gwa: Jadi kapan koko ted bakal married ? ( koko ted adalah panggilan gwa buat koko gwa :P )

Nyokap: Belom tau, rumah aja blom selesai dibangun.

Gwa: Oh gitu…

Nyokap: Jadi setelah si Teddy married, giliran lu lagi la ?

Gwa: Enggak donk… kan beda umur gwa ama koko 5 tahun… jadi gwa married masih 5 tahun lagi…

Nyokap: Emang orang tuanya Riani bolehin ? bukannya biasanya orang tua suka ketar ketir kalo belum jelas kek begini. Kalau gwa jadi orang tuanya pun khawatir.

Gwa: …

PS : kata2 sedikit diubah agar mudah dimengerti

Reasons why I hate long weekend

Too much sleep

Less productive

Tasks waiting after holiday

and

Far away from your girlfriend

Gource

Gource is a software version control visualization tool. It was built using C/C++ ( not sure ). Several version controls that supported by Gource are Git, SVN, Mercurial and Bazaar.

Basically Gource is a command line tool that you can use to visualize your project’s progress that using software version control. Here is the example of my project :

Cool isn’t it ? In my video, there is only one person because I am working for this project alone. However, if you are looking in YouTube, you can find a lot of big projects that using Gource to visualize their progress. One of the project that you should see is the Linux Kernel project.

Here is the link to the Gource Website

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.

Change wordpress default email and name

Actually you can find this solution easily in Google. However, I’ll put it in my blog just because I am lazy to find it again.

So wordpress has default email address and name which are “WordPress” as the name, wordpress@yourdomain.com as the email. To change it you can use plugin or put these wordpress action to your functions.php file in themes folder :

add_filter('wp_mail_from', 'new_mail_from');
add_filter('wp_mail_from_name', 'new_mail_from_name');
 
function new_mail_from($old) {
 return 'no-reply@rudylee.com';
}
 
function new_mail_from_name($old) {
 return 'Rudy';
}

Just change the email address and name to your’s. Hope it works, cheers.

Fixing rake command error in rails 3.0.7

Today I was trying to add rails project to Netbeans 6.9,but suddenly there is a pop up window that said “Rake task fecthing failed” with bunch of other errors. After that, I tried go to my application folder and try to run the rake command

rake -D

However I got this error

rudy@rudy-laptop:~/www/depot$ rake -D
rake aborted!
undefined method `task' for #<Depot::Application:0x91fa9c4>
 
(See full trace by running task with --trace)

After a little bit research, I found that I have to uninstall my rake 0.9 and install 0.8.7 instead. So I ran this command :

gem uninstall rake -v 0.9
gem install rake -v 0.8.7

Edited the gem file and added this code inside that file :

gem 'rake', '0.8.7'

Last step is update the bundle

bundle update

After that you can try run your rake command or import your project to Netbans, it’s should be fine.

UPDATE :
It turns out that the problem is because I was using rake 0.9 and it’s break out all the installation.

gem install bundler

You might want to install bundler if you encounter some errors related to Netbeans couldn’t find bundler setup. Another thing is you have to add gem path to your Netbeans ( Tools > Rubygems ) and add your gem path.

I am using rvm to install ruby and also rails. So I run this command to find gem path

rvm gemdir

Make wordpress using the latest jQuery

I just copied this from another website, put it here just in case that I forgot.

if( !is_admin()){
   wp_deregister_script('jquery');
   wp_register_script('jquery', ("http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"), false, '');
   wp_enqueue_script('jquery');
}

Put this snippet to functions.php file in your theme folder ( eg : wp-content/theme/whatever/functions.php )

Apache GeoIP

Apache GeoIP is an apache module for detecting your visitor’s IP and block/redirect them to another website. Installing and configuring GeoIP is very easy in Ubuntu. Here are the steps :

1.Install the Apache GeoIP module and restart apache webserver

sudo apt-get install libapache2-geoip
sudo /etc/init.d/apache2 restart

2.Create the .htaccess file and put in your webroot folder / website folder

GeoIPEnable On
 
# Redirect one country
RewriteEngine on
RewriteCond %{ENV:GEOIP_COUNTRY_CODE} ^AU$
RewriteRule ^(.*)$ http://www.canada.com$1 [L]

In the example above, GeoIP will check whether the visitor is from Australia or not. If the visitor is from Australia then apache will redirect the visitor to http://www.canada.com. Quite simple and straight forward. You can see another example in here http://www.maxmind.com/app/mod_geoip ( ignore the GeoIPDBFile because it will cause error ).