Yii Framework Forum: CGridView totals row under header - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

CGridView totals row under header ...not footer! Rate Topic: ***** 1 Votes

#1 User is offline   alexb 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 15
  • Joined: 04-May 10

Posted 12 July 2010 - 02:46 PM

Hi guys,

I have a little problem. I can't seem to figure out how to render an additional row in CGridView, which would show the totals of each column. Now, I know that this can be easily achieved by rendering it as a footer, but would like to know if there's a way to make it show as the second row of the grid (just under the header)...?!

Thanks in advance :)
0

#2 User is offline   charris66 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 13
  • Joined: 09-October 09
  • Location:BC, Canada

Posted 12 July 2010 - 07:34 PM

This is possible, although you may have to iterate through all of the rows twice to calculate the totals. The reason is that the rendering of the table header is finished before the table body rendering is started, and is during the table body rendering that you can calculate totals based on the values from each row that is rendered.

If this is okay (iterating twice), you can create a new class that you will put in your 'components' directory that extends from CGridView. In that file, copy the renderTableHeader() function from CGridView, and modify it to add an extra row in the <thead>. See CGridView::renderTableBody() and CGridView::renderTableRow() for ways to access the data from each row.

Make sure to add the line Yii::import('zii.widgets.grid.CGridView'); at the top of your extended class so that Yii can import the CGridView parent class.

For example, your file may be called CGridViewWithTotals.php and the code would be similar to:

<?php

Yii::import('zii.widgets.grid.CGridView');

class CGridViewWithTotals extends CGridView
{
	/**
	 * Renders the table header. Adds a 'totals' row.
	 */
	public function renderTableHeader()
	{
		[Your code here]
	}
}


An alternative way would be to calculate the totals in the table footer as before, and then use javascript to 'yank' the row from the footer and 're-place' it into the header.
0

#3 User is offline   alexb 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 15
  • Joined: 04-May 10

Posted 14 July 2010 - 03:37 PM

I appreciate your help charris66 ;-)

My issue is actually a little simpler. I already have the totals for each column, I was just inquiring whether there is a quick and easy way to just "move" the footer to the top, so that it appears just under the header (ie. I want the totals row to come right after the header row). Or do I need to extends the CGridView class or something...

Please let me know...

Thanks again!
0

#4 User is offline   charris66 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 13
  • Joined: 09-October 09
  • Location:BC, Canada

Posted 14 July 2010 - 04:57 PM

No problem alexb ;-)

So what you can do is set the 'footer' property of the column to the calculated total. By default this will place the total at the end of the table.

<?php

$this->widget('CGridViewWithTotals', array(
	'id'=>'my-grid',
	'dataProvider'=>$model->search(),
	'emptyText'=>'No items found.',
	'ajaxUpdate'=>false,
	//'filter'=>$model,
	'columns'=>array(
		array(
			'name'=>'field1',
			'footer'=>$total,
		),
	),
));

?>


Now you will have to extend CGridView and modify renderTableHeader() as before. Although this is breaking the semantic properties by placing the footer in the header, we won't worry about that for now.

	public function renderTableHeader()
	{
		if(!$this->hideHeader)
		{
			echo "<thead>\n";

			if($this->filterPosition===self::FILTER_POS_HEADER)
				$this->renderFilter();

			echo "<tr>\n";
			foreach($this->columns as $column)
				$column->renderHeaderCell();
			echo "</tr>\n";

			if($this->filterPosition===self::FILTER_POS_BODY)
				$this->renderFilter();
			 
			if($this->getHasFooter())
			{
				echo "<tr>\n";
				foreach($this->columns as $column)
					$column->renderFooterCell();
				echo "</tr>\n";
			}

			echo "</thead>\n";
		}
		else if($this->filter!==null && ($this->filterPosition===self::FILTER_POS_HEADER || $this->filterPosition===self::FILTER_POS_BODY))
		{
			echo "<thead>\n";
			$this->renderFilter();
			echo "</thead>\n";
		}
	}


You could also override CGridView::renderTableFooter() if you don't want the totals to be displayed there as well.
1

#5 User is offline   alexb 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 15
  • Joined: 04-May 10

Posted 15 July 2010 - 08:53 AM

Thanks, this is exactly what I wanted to achieve!
0

#6 User is offline   charris66 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 13
  • Joined: 09-October 09
  • Location:BC, Canada

Posted 15 July 2010 - 10:47 PM

No probs. B)
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users