Advanced CGridview issues - custom button using php and html

You are viewing revision #6 of this wiki article.
This is the latest version of this article.
You may want to see the changes made in this revision.

« previous (#5)

This wiki shows about how to make a custom column or how to pass php-Yii-html code in CButtonColumn (as a button)

This code could be used also for bootstrap/booster CGridview

In this example will use the bootstrap and will make a javascript button that toggles between enable and disable situations

First of all you have to exends the TbButtonColumn so create the ExTbButtonColumn.php in protected/components and add this code

Yii::import('bootstrap.widgets.TbButtonColumn');

class ExTbButtonColumn extends TbButtonColumn {

	//override the renderButton to use custom php expression
    protected function renderButton($id, $button, $row, $data) {
        if (isset($button['visible']) && !$this->evaluateExpression($button['visible'], array('row' => $row, 'data' => $data)))
            return;

        if (isset($button['html'])) {
            echo $this->evaluateExpression($button['html'], array('data' => $data, 'row' => $row));
            return;
        } else
            parent::renderButton($id, $button, $row, $data);
    }

    //make a javascript button to toggle between enable and disable situations
	//Note that enable/disable column could be an integer (1=enable,0=disable) or maybe a char or anything you want, for example 'Y'=enable,'N'=disable
	//So, we have an extra array parameter to give the ability to programmers to modify this. 
    public function activeToggleButtonIconBoolean($attribute,$isEnable,$endis=array('enabled'=>1,'disabled'=>0)) {
         
        return CHtml::tag('span', array(
                    'onclick' => "var a = $(this).parent().find('.enable-button-input').val();
                        if (a=='".$endis['enabled']."') {
                                 $(this).parent().find('.disabled-icon-boolean').show();
                                 $(this).parent().find('.enabled-icon-boolean').hide();
                                 $(this).parent().find('.enable-button-input').val('".$endis['disabled']."');
                        } else {
                                 $(this).parent().find('.disabled-icon-boolean').hide();
                                 $(this).parent().find('.enabled-icon-boolean').show();
                                 $(this).parent().find('.enable-button-input').val('".$endis['enabled']."');
                                }",

                      'style'=>'cursor:pointer',
                        ), $this->iconBoolean($isEnable==$endis['enabled']) .
                        $this->iconBoolean($isEnable!=$endis['enabled'],false) .
                        CHtml::hiddenField($attribute, $isEnable, array('class' => 'enable-button-input'))
        );
	}

    public function iconBoolean($bool, $visible = true) {
        return $bool ? CHtml::tag('div', array('class' => 'enabled-icon-boolean', 'style' => 'font-weight:bold; color:green; display:' . ($visible == true ? 'block' : 'none')), '√') : CHtml::tag('div', array('class' => 'disabled-icon-boolean', 'style' => 'font-weight:bold; color:red; display:' . ($visible == true ? 'block' : 'none')), '×');
    }

}

2) In your 'bootstrap.widgets.TbGridView' (or CGridView) widget of your view

a) replace the 'class' => 'bootstrap.widgets.TbButtonColumn', (or 'CButtonColumn') with 'class' => 'ExTbButtonColumn',

b) add in the same widget the setting 'template' => '{published}{view}{update}{delete}'

c) also set

...
'buttons'=>array(
'view',
'update',
'delete',
'published'=>array(
   'html'=>'"<span>".$this->activeToggleButtonIconBoolean("yourModelName[your_enable_attribute]",$data->your_enable_attribute,array("enabled"=>"Y","disabled"=>"N"))."</span>";',)
   //Note that enable/disable column could be an integer (1=enable,0=disable) or maybe a char or anything you want, for example 'Y'=enable,'N'=disable
),
...

alternative set also you could use the iconbuttonboolean to seperated cgridview column (as usually does) making your own class (yourClass) that contains activeToggleButtonIconBoolean and iconBoolean method as static.

Finally use it like that (replace '$this->' with 'self::' in php code)

$this->widget('bootstrap.widgets.TbGridView', array(
	'columns' => array(
				...
				array(
					
					'name' => 'your_enable_attribute',
					'value'=>'yourClass::activeToggleButtonIconBoolean("yourModelName[your_enable_attribute]",$data->your_enable_attribute);',)
				),
				...

To save each row using update column via Ajax you have to prevent the default http request (for example the update link) and send all the row data-columns using custom ajax post request.

check this to see how to do that http://www.yiiframework.com/wiki/658/update-cgridview-row-separately-using-ajax-request/