dhenet5254
(Redhen 07)
September 14, 2013, 12:49am
1
hi to all, i just wanna ask how can i search or filter on my cgrid using my custom column
this is my view:
array(
‘header’=>‘average’
‘value’=>’$data->getAverage()’
}
this is my model where i can get the value of average
public function getAverage
{
$average = Yii::app()->db->createCommand(‘select AVG(column) FROM your_table’)->queryScalar();
return $average;
}
note code above is for example only
my proble is how can i create a search or filter on my cgrid view?
konapaz
(Konapaz)
September 14, 2013, 2:16pm
2
Hi raiethan
The caclulation occurs for each record at the moment that CGridview displays the records.
So, it is no possible to sort or filter this column in this way
The best way to achieve that is by adding a column in your databse table and assign with the $averange value on before save event. Because you have already records with no calculated average value, make a method that initializes the new column for all old records.
Another way is by CArrayDataProvider
http://www.yiiframework.com/doc/api/1.1/CArrayDataProvider
but you have to caclulates the extra average column for all records for each request (make your webapp slow when a lot of records exist) So the first way is the best
softark
(Softark)
September 15, 2013, 12:26am
3
Hi raiethan,
As KonApaz says, CActiveDataProvider (and also CSqlDataProvider) uses SQL to search, filter and sort by some value. The value must be accessible from SQL.
We usually use a column in db for that, but if you can express the value in SQL then you can use it.
A getter method of AR can’t be used for that purpose, because the value should be calculated in SQL, before Yii constructs the AR objects as the result.
dhenet5254
(Redhen 07)
September 15, 2013, 1:27am
4
KonApaz:
Hi raiethan
The caclulation occurs for each record at the moment that CGridview displays the records.
So, it is no possible to sort or filter this column in this way
The best way to achieve that is by adding a column in your databse table and assign with the $averange value on before save event. Because you have already records with no calculated average value, make a method that initializes the new column for all old records.
Another way is by CArrayDataProvider
http://www.yiiframework.com/doc/api/1.1/CArrayDataProvider
but you have to caclulates the extra average column for all records for each request (make your webapp slow when a lot of records exist) So the first way is the best
i will try the first way sir… thank you so much…
dhenet5254
(Redhen 07)
September 15, 2013, 9:02am
5
softark:
Hi raiethan,
As KonApaz says, CActiveDataProvider (and also CSqlDataProvider) uses SQL to search, filter and sort by some value. The value must be accessible from SQL.
We usually use a column in db for that, but if you can express the value in SQL then you can use it.
A getter method of AR can’t be used for that purpose, because the value should be calculated in SQL, before Yii constructs the AR objects as the result.
thank you so much… in short sir the proper way is to create another column on my db and will add before save that will compute and save my average on my db…
softark
(Softark)
September 15, 2013, 4:18pm
6
For instance, let’s assume a model called Point.
The table that implements Point is something like this:
id ... PK
point_a ... decimal
point_b ... decimal
point_c ... decimal
Now you can think of the average value of point_a, point_b and point_c.
KonApaz’s suggestion is to add a new column, something like point_avg.
id ... PK
point_a ... decimal
point_b ... decimal
point_c ... decimal
point_avg ... decimal
You can calculate the average point in beforeSave().
// in Point.php
...
public function beforeSave()
{
$this->point_avg = ($this->point_a + $this->point_b + $this->point_c ) / 3;
return parent::beforeSave();
}
In this way, you can calculate and save the average every time you create or update Point.
dhenet5254
(Redhen 07)
September 16, 2013, 1:48am
7
in my case sir i follow your suggestion, but when i try to create it will save 0 and blank on my average and interpretation
public function beforeSave()
{
$this->average =
$divider = 0;
if($this->rating1 != 0 || $this->rating1 != null) $divider += 1;
if($this->rating2 != 0 || $this->rating2!= null) $divider += 1;
if($this->rating3 != 0 || $this->rating3 != null) $divider += 1;
if($this->rating4 != 0 || $this->rating4 != null) $divider += 1;
if($this->rating5 != 0 || $this->rating5!= null) $divider += 1;
if($this->rating6 != 0 || $this->rating6 != null) $divider += 1;
if($divider == 0) $divider = 1;
$avg = ($this->rating1 + $this->rating2 + $this->rating3+ $this->rating4 + $this->rating5 + $this->rating6) / $divider;
$this->interpretation =
$avg = ($this->interpretation);
if ($avg >= 96)
{
$remarks = "<font color='blue'>Outstanding</font>";
}
else if ($avg >= 91)
{
$remarks = "<font color='green'>Superior</font>";
}
else if ($avg >= 86)
{
$remarks = "<font color='indigo'>Very Satisfactory</font>";
}
else if ($avg >= 81)
{
$remarks = "<font color='orange'>Satisfactory</font>";
}
else if ($avg >= 76)
{
$remarks = "<font color='violet' >Minimally Santisfactory<font>";
}
else if ($avg <= 75)
{
$remarks = "<font color='red' >Needs Improvement</font>";
}
return parent::beforeSave();
}
softark
(Softark)
September 16, 2013, 2:08am
8
You are not saving the value of $avg to your AR object.
// $avg = ($this->rating1 + $this->rating2 + $this->rating3+ $this->rating4 + $this->rating5 + $this->rating6) / $divider;
$this->avg = ($this->rating1 + $this->rating2 + $this->rating3+ $this->rating4 + $this->rating5 +
And review your code for another local variable named $remarks.
dhenet5254
(Redhen 07)
September 16, 2013, 2:41am
9
softark:
You are not saving the value of $avg to your AR object.
// $avg = ($this->rating1 + $this->rating2 + $this->rating3+ $this->rating4 + $this->rating5 + $this->rating6) / $divider;
$this->avg = ($this->rating1 + $this->rating2 + $this->rating3+ $this->rating4 + $this->rating5 +
And review your code for another local variable named $remarks.
opps… sorry my bad… thank you so much…