Merge GridView Cells Or Columns in Row

Hi guys,

How to merge the row or cell in CGridView when the record is same? Pls help…

i need write what in CGridView option to make this work??

Example

Cell Merge CGridView

Hi guys,

How to implement the code from below to cgridview??


  $prev = '';

    $value = $dataProvider->data;


    foreach($value as $a)

    {


        if($prev != $a['department'])

        {


            echo $a['department'];

            echo "<br>";

        }

        else

            '';

        $prev = $a['department'];

Previous result:

name department

tom account

Kim account

James sale

Jim sale

Bob sale

Wanted result:

name department

tom account

Kim

James sale

Jim

Bob


 $this->widget('zii.widgets.grid.CGridView', array(

        'dataProvider' => $dataProvider,

        'columns' => array(

            array(

                'name' => 'name',

            ),

            array(

                'header' => t("user", "department"),

                'name' => 'department',

                'value' => '$data->department== "<same>" ? "" : $data->department',  //how to empty the value if the previous department value if same

            ),

You can assign a php function as a value in the CGridView:





'columns' => array(

            array(

                'name' => 'name',

            ),

            array(

                'header' => t("user", "department"),

                'name' => 'department',


                'value' => function($data,$row) {

                         

                         ... your php code here ...

                          $value = ....


                        return $value;      

                  }

               ),

            ...



$row is the row number (zero-based)

$data is the data associated with the current row

So something like this should do the job:




  $lastDepartment = null; //define a variable outside the CGridView widget in the view.


  $this->widget('zii.widgets.grid.CGridView', array(

   ....

 'columns' => array(

  array(

                'header' => t("user", "department"),

                'name' => 'department',

                'value' => function($data,$row) 

             {

               global $lastDepartment; //import the global variable


               if ($lastDepartment != $data->department) 

               {

                 $lastDepartment = $data->department;

                 return $data->department;

               } 

               else

                  return '';                                  

             }




Hi Joblo,

I try using the code in my cgridview but the line function($data,$row) got error. Don’t know need include what stuff inside??




'columns' => array(

            array(

                'name' => 'name',

            ),

            array(

                'header' => t("user", "department"),

                'name' => 'department',

                'value' => 

                   function($data,$row)    //red error line 

                   {

                     if ($row>0) //second row or greater 

                       {

                      $lastData=$this->grid->dataProvider->data[$row-1]; //the previous row

                      return $lastData->department != $data->department ? '' : $data->department;

                       } 

                      else

                      return $data->department;                   

                

                    }

               ),



Sorry, I have tested my first published code and ‘$this’ is unknown.

But in the meanwhile I have changed my answer (see above) and this should work - hope so.

Hi Joblo,

Need include ‘value’ => " php statement "

But now got new error.


Undefined variable: data 

For function($data,$row). $data need predefine first?

The php code should not be assigned as string, so don’t add apostroph, only the pure php-code.




  'value'=>function($data,$row) {return $data->department}, //test this first

  

  //not 'value'=>'function($data,$row) {...}' or 'value'=>"function($data,$row) {...}"




the line function($data,$row) always show error when i write this?? can tell me why?


array(

                'header' => t("user", "department"),

                'name' => 'department',

                'value' => 

    function($data,$row)   //red error line 


                {

                    global $lastDepartment; //import the global variable


                    if($lastDepartment != $data->department)

                    {

                        $lastDepartment = $data->department;

                        return $data->department;

                    }

                    else

                        return '';

               ),

Closing bracket ‘}’ of the function missing:




array(

                'header' => t("user", "department"),

                'name' => 'department',

                'value' => 

    function($data,$row)   //red error line 


                {

                    global $lastDepartment; //import the global variable


                    if($lastDepartment != $data->department)

                    {

                        $lastDepartment = $data->department;

                        return $data->department;

                    }

                    else

                        return '';

               } // <---------------- add this 

       ), //end array




It still the same error… Izzit work well at your side there??




'value' =>

                function($data,$row)   //red error line still got


                {

                    global $lastDepartment; 


                    if($lastDepartment != $data->department)

                    {

                        $lastDepartment = $data->department;

                        return $data->department;

                    }

                    else

                        return '';

                }

            ),

For me it works.

Did you test a simple code?




'columns' => array(

  array(

                'name' => 'department',

                'value' => function($data,$row) {return $data->department},

       )

 )



I do much more in a ‘value-function’ in a CGridView: db-query for detaildata and more … and it works.

For example, this is a working code:





$this->widget('zii.widgets.grid.CGridView', array(

		'id'=>'appointment-grid',

		'dataProvider'=>$dataProvider,

		'columns'=>array(

			array(

                                 'type'=>'raw',

                                 'name'=>'Contact',

				 'value'=>function($data,$row) {

			     	    return

			     		   '<div class="td-appointment-group"><b>'.$data->city . ' ' .$data->name .'</b><br/>'.

			     		   $data->Account_NAME . '<br/><br/>'.

			     		   $data->Account_EMAIL . '<br/>'.

			     		   'Phone: ' . $data->Account_PHONE1 . '<br/></div>';

			     		 

			     }

			  ),


			


		),

));



Hi Joblo,


For me it works.

Did you test a simple code?


'columns' => array(

  array(

                'name' => 'department',

                'value' => function($data,$row) {return $data->department},  // error line

       )

 ),

i just try use above code, same thing happens. Got error at ‘value’ => function($data,$row) {return $data->department}… i wonder why this will happens? Any people facing same problems?

hi guys,

Anyone know why this function will get error in cgridview?? for value properties…

i wonder why this will happens? Any people facing same problems? pls helpss


'columns' => array(

  array(

                'name' => 'department',

                'value' => function($data,$row) {return $data->department},  // error line

       )

 ),

closures (inline functions) are available only from PHP 5.3. earlier versions do not have support for this king of expressions. In PHP 5.2 you have to write it like this:




'columns' => array(

  array(

                'name' => 'department',

                'value' => '$data->department',  // error line

       )

 ),



There is one more thing you should be aware: $data points to an object when you provide CActiveRecordDataProvider. If you use CArrayDataProvider - $data will point to value of array element (depends on what you put in array). In case of CSqlDataProvider - $data is an associative array with column names as keys.

Hope one of this hints works for you.

Hi Redguy,


closures (inline functions) are available only from PHP 5.3. earlier versions do not have support for this king of expressions. In PHP 5.2 you have to write it like this:

actually i want write a function in “value”=> to set condition for it… So the code below can’t support in cgridview??




  $this->widget('zii.widgets.grid.CGridView', array(

   ....

 'columns' => array(

  array(

                'header' => t("user", "department"),

                'name' => 'department',

                'value' => function($data,$row) 

             {

               global $lastDepartment; //import the global variable


               if ($lastDepartment != $data->department) 

               {

                 $lastDepartment = $data->department;

                 return $data->department;

               } 

               else

                  return '';                                  

             }

),

Sorry, I didn’t think about the PHP version.

I have spent an hour to check other solutions, because I have to work with customized datacolumns too.

Maybe this works in PHP < 5.3 too (please let me know):

  1. Create the function as a protected method of your DepartmentController



class DepartmentController extends Controller

{	

	private $_lastDepartment;


        ...

 

        protected function gridGroupedDepartment($data,$row)

	{

		if($this->_lastDepartment != $data->department)

		{

			$this->_lastDepartment = $data->department;

			return $data->department;

		}

		else

			return '';

	}




  1. Call this method on evaluating the value-expression in the gridview



$this->widget('zii.widgets.grid.CGridView', array(

   ....

 'columns' => array(

    array(

                'header' => t("user", "department"),

                'name' => 'department',

                //call the method 'gridGroupedDepartment' of the controller

                //the params extracted to the method are $data (=the current rowdata) and $row (the row index)

                'value' => array($this, 'gridGroupedDepartment')

        ),




And the sideeffect is:

Implemented like this is more clean code, than implementing the function directly in the cgridview.

And it offers a lot of possibilities to customize datacells, because in the controller you have access to all data, Yii::app() … and more.

I think I will switch to this solution in my projects :slight_smile:

Maybe it’s worth a wiki tip article with some more examples.

Hi Joblo,

Really want say many thanks to you. Your code work fantastic. =) Agree with your suggestion… write a wiki article on it. Hope can solve other Yii developer too. Thanks again for your helps. You is the greatest helper.




And the sideeffect is:

Implemented like this is more clean code, than implementing the function directly in the cgridview.

And it offers a lot of possibilities to customize datacells, because in the controller you have access to all data, Yii::app() ... and more.

I think I will switch to this solution in my projects :-)

Maybe it's worth a wiki tip article with some more examples. 

Added wiki article CGridView: Render customized/complex datacolumns

Hi Joblo,

this method can implement on CDetailView?? Will it different with method use in CGridView?

The last example in the wiki article ( function gridAddress($data,$row)…)

renders (partial) the ‘actionView’ of the AddressController.

If you let gii generate the code of the Address model/controller there will be a CDetailView widget in ‘view.php’.

I have tested this, it works and means you have a CDetailView rendered into the CGridView cell.