[Best Practice] Yii CGridView update/create in popup with iframe

In Yii wiki, there are some articles about this topic.

http://www.yiiframework.com/wiki/263/cgridview-update-create-records-in-a-cjuidialog/

http://www.yiiframework.com/wiki/216/update-delete-model-with-cjuidialog-works-in-cgridview/

But there are so much modification in controllers, and the the UI logic is coded in controller. I think the expansibility is not good enough. Now based on the wiki/263, I create my own.

Step 1 – generate an iframe-layout (layouts/iframe.php)

Same as http://www.yiiframework.com/wiki/263/cgridview-update-create-records-in-a-cjuidialog/

Step 2 – render CGridView
modify

//--------------------- begin new code --------------------------
 'buttons'=>array(
    'update'=>array(
        'url'=>'$this->grid->controller->createUrl("update", array("id"=>$data->primaryKey,"asDialog"=>1,"gridId"=>$this->grid->id))',
        'click'=>'function(){$("#cru-frame").attr("src",$(this).attr("href")); $("#cru-dialog").dialog("open");  return false;}',
     ),
 ),
//--------------------- end new code --------------------------

to

//--------------------- begin new code --------------------------
 'buttons'=>array(
    'update'=>array(
    'url'=>'$this->grid->controller->createUrl("update", array("id"=>$data->primaryKey,"asDialog"=>1,"gridId"=>$this->grid->id))',
    'click'=>'function(){'
              . '$("#cru-frame").attr("src",$(this).attr("href")); '
              . '$("#cru-dialog").unbind("close"); '
              . '$("#cru-dialog").bind("close", function(){$.fn.yiiGridView.update("'. $this->grid->id . '"); $("#cru-frame").attr("src","");});'
              . '$("#cru-dialog").dialog("open");'
              . 'return false;'
              . '}',
),
 ),
//--------------------- end new code --------------------------

Step 3 – change Controller
Change

if (!empty($_GET['asDialog']))
            {
                //Close the dialog, reset the iframe and update the grid
                echo CHtml::script("window.parent.$('#cru-dialog').dialog('close');window.parent.$('#cru-frame').attr('src','');window.parent.$.fn.yiiGridView.update('{$_GET['gridId']}');");
                Yii::app()->end();
            }

to

if (!empty($_GET['asDialog']))
{
      //Close the dialog, reset the iframe and update the grid
      echo CHtml::script("window.parent.$('#cru-dialog').dialog('close');");
      Yii::app()->end();
}

That is the key point, the controller only take responsibility for closing the dialog. What should be done after dialog closing is defined in the view. And then the controller can be reused in more ajax context without changing controller. Hope it can help. 

Yii PDO.php error: failed to open stream – Two Solutions [Solved]

There are two options for you when you suffer the following error,
include(PDO.php): failed to open stream: No such file or directory

1. recompile the php build
2. Use PDO equivalent module of Yii framework

recompile the php build
Use phpinfo() to check if the compile parameter –enable-pdo and –with-pdo-mysql is enable. If they are disabled, you have to recompile your php.

Use PDO equivalent module of Yii framework
a) download http://www.yiiframework.com/extension/phppdo
b) configure in main.php

'db'=>array(
    'connectionString' => 'mysql:host=localhost;dbname=YouDBname',
    'class'=>'application.extensions.PHPPDO.CPdoDbConnection',
    'pdoClass' => 'PHPPDO',
    'emulatePrepare' => true,
    'tablePrefix' => 'xxx_',
    'username' => 'xxxx',
    'password' => 'xxxx',
    'charset' => 'utf8',
),

CGridView filter with relational field [Solved]

Model:
1. defined filter property in model

var $a = "";
var $b = "";

2. configure rules for properties

array('......., a, b', 'safe', 'on'=>'search');

3. define relation in function relations()

public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'xxx' => array(self::HAS_ONE,  'xxxModel', array('...' => '....')),
);
}

4. add codes in function search()

$criteria->compare('xxx.ax',$this->a);
$criteria->compare('xxx.bx',$this->b);

View

'dataProvider'=>$model->with("xxx")->search(),

2. define column display form

array(
'name' => 'a',
'value' => '$data->xxx->ax',
'filter' => array("$array_for_drop_down_list"),
),
array(
'name' => 'b',
'value' => '$data->xxx->bx',
'filter' => array(1 => "Set", 0 => 'Not Set'),
),

Code hint:
1. The two properties are only used to store the search condition from UI form.
2. The CDbCriteria is not changed in function search().

yii breadcrumbs remove home

Yii framework API: http://www.yiiframework.com/doc/api/1.1/CBreadcrumbs

Application Scene
Yii breadcrumbs display the Home link automatically and the home link is the application’s home page link, when you setup a subdomain and want the home link to be the www domain, you may want to disable the default home link.

Step 1


<?php if(isset($this->breadcrumbs)):?>
    <?php $this->widget('zii.widgets.CBreadcrumbs', array(
                            'links'=>$this->breadcrumbs,
                            'homeLink' => false,
              )); ?><!-- breadcrumbs -->
<?php endif?>

Step 2

$this->breadcrumbs = array(
    'Menu1'=>array('post/view', 'id'=>12),
    'Menu2',
);