Skip navigation


Setelah sekian lama terbengkalai, akhirnya saya melanjutkan postingan ini. Di postingan tersebut (dan postingan-postingan sebelumnya), saya menulis tentang bagaimana mengkustomisasi CJuiAutoComplete sesuai dengan kebutuhan. Tapi kelemahan dari implementasi sebelum-sebelumnya adalahautocompletetersebut terikat pada satucontroller dan agak repot untuk dipakai diview yang lain.

Agar dapat dengan mudah digunakan di view yang lain solusinya adalah dengan membungkus autocomplete tersebut menjadi sebuah Widget. Dengan demikian, untuk menggunakan autocomplete, kita cukup meletakkan kode widgetnya saja. Permasalahan dengan Widget ini adalah bagaimana cara mendapatkan data untuk autocomplete tersebut? Caranya mudah, yakni dengan menggunakan fitur ActionProvider pada Widget.

Pertama-tama kita membuat sebuah file UserLookupWidget.php yang berisi dua buah kelas.

<?php
/**
 * @filesource /protected/components/widget/userlookup/UserLookupWidget.php
 */
class UserLookupAction extends CAction {

        /**
         * Runs the widgets.
         */
        public function run() {

        }

}

/**
 * Widget for lookup action.
 */
class UserLookupWidget extends CWidget {

        /**
         * Runs the widgets.
         */
        public function run() {
        }

}

Selanjutnya kita masukkan kode untuk lookup yang sebelumnya ada di action actionLookup pada controller SiteController ke method run di class UserLookupAction.

class UserLookupAction extends CAction {

        /**
         * Runs the widgets.
         */
        public function run() {
                $term = $_GET['term'];
                $users = User::model()->findAll(array(
                    'condition' => 'firstName LIKE :firstName OR lastName LIKE :lastName',
                    'params' => array(
                        ':firstName' => "%$term%",
                        ':lastName' => "%$term%",
                    ),
                        ));
                $return = array();
                foreach ($users as $user) {
                        $return[] = array(
                            'label' => $user->firstName . ' ' . $user->lastName,
                            'value' => '',
                            'image' => $user->profilePicturePath,
                            'city' => $user->city,
                            'url' => $user->profilePage,
                        );
                }
                echo CJSON::encode($return);
        }

}

Setelah itu kita mengkonfigurasi ActionProvider dari widget UserLookupWidget.

class UserLookupWidget extends CWidget {

        const LOOKUP_ACTION = 'lookup';

        /**
         * Returns actions list for action provider.
         * @return array
         */
        public static function actions() {
                return array(
                    self::LOOKUP_ACTION => 'UserLookupAction',
                );
        }

}

Agar dapat menggunakan action yang diprovide oleh UserLookupWidget tersebut, kita harus membuat sebuah controller yang menjadi gerbang bagi si action

/**
 * @filesource /protected/controllers/AjaxController.php 
 */
class AjaxController extends Controller {

        public function actions() {
                Yii::import('application.components.widgets.userlookup.UserLookupWidget');
                return array(
                    'userlookup.' => array(
                        'class' => 'UserLookupWidget',
                    ),
                );
        }

}

Saat ini kita sebenarnya sudah bisa mengakses UserLookupAction melalu http://domain/ajax/userlookup.lookup?term=Bran. Tapi kita ingin menggunakan action tersebut untuk bisa dipakai oleh autocomplete. Sekarang kita akan meletakkan autocomplete di widget.

/**
 * Widget for lookup action. 
 */
class UserLookupWidget extends CWidget {

        const LOOKUP_ACTION = 'lookup';

        public $route = '/ajax/userlookup.';

        /**
         * Returns actions list for action provider
         * @return array 
         */
        public static function actions() {
                return array(
                    self::LOOKUP_ACTION => 'UserLookupAction',
                );
        }

        /**
         * Get URL for users lookup.
         */
        public function getLookupUrl() {
                return $this->controller->createUrl($this->route . self::LOOKUP_ACTION);
        }

        /**
         * Runs the widgets.
         */
        public function run() {
                $this->widget('zii.widgets.jui.CJuiAutoComplete', array(
                    'id' => $this->id,
                    'name' => 'user',
                    'sourceUrl' => $this->getLookupUrl(),
                    'options' => array(
                        'minLength' => '2',
                        'select' => &lt;&lt; array(
                        'style' => 'height:20px;'
                    ),
                ));

                Yii::app()->clientScript->registerScript($this->id, &lt;&lt;id}').data('autocomplete')._renderItem = function( ul, item ) {
	return $('<li></li>')
		.data('item.autocomplete', item)
		.append('<a><img /><h1>'+item.label+'</h1><h2>'+item.city+'</h2></a>')
		.appendTo(ul);
};
JS
                        , CClientScript::POS_READY);

                Yii::app()->clientScript->registerCss($this->id, &lt;&lt;&lt;CSS
        .userautocompletelink {height:52px;}
	.userautocompletelink img {float:left;margin-right:5px;}
	.userautocompletelink h1 {font-size:15px;padding:0px;margin:0px;font-width:bold;}
	.userautocompletelink h2 {font-size:12px;padding:0px;margin:0px;}
CSS
                );
        }

}

Perlu diperhatikan bahwa CJuiAutoComplete menggunakan ID dari UserLookupWidget. Selain itu CSS dan Script yang digenerate oleh clientScript menggunakan ID yang sama juga. Hal ini dilakukan agar tidak terjadi konflik jika terdapat dua atau lebih widget UserLookupWidget pada halaman yang sama.

Sekarang untuk meletakkan autocomplete tersebut hanya butuh sebuah line saja. Dan bisa diletakkan di mana saja.

<?php
/**
 * @filesource /protected/views/site/index.php
 */
$this->widget('application.components.widgets.userlookup.UserLookupWidget');
?>
<?php
/**
 * @filesource /protected/views/user/index.php
 */
?>
<?php
$this->widget('application.components.widgets.userlookup.UserLookupWidget');
?>
<div>
        <h1><?php echo $user->firstName . " " . $user->lastName; ?></h1>
        <h2><?php echo $user->city; ?></h2>
        <?php echo CHtml::image($user->profilePicturePath); ?>

</div>

Bisa dilihat contohnya di gambar bawah kalau autocomplete ini bisa diletakkan di mana saja.

Kode penuhnya bisa dilihat di sini.

**UPDATE**
Masih banyak yang bisa diperbaiki dari contoh ini. Misalnya konfigurasi end-point untuk controller masih bisa diperbaiki agar bisa dikonfigurasi dari controller sehingga lebih moduler. Lalu widget juga bisa ditambahkan konfigurasi untuk HTML dengan menambahkan atribut htmlOptions, dan lain-lain.

About these ads

3 Comments

  1. Mantap :D. Ane jadi pengen nongkrong di sini :D

  2. Reblogged this on erycamel.

  3. Reblogged this on Gabriel Evander and commented:
    Yii Framework


Berikan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Logout / Ubah )

Twitter picture

You are commenting using your Twitter account. Logout / Ubah )

Facebook photo

You are commenting using your Facebook account. Logout / Ubah )

Google+ photo

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s

Ikuti

Get every new post delivered to your Inbox.

Bergabunglah dengan 32 pengikut lainnya.

%d blogger menyukai ini: