1

Sorry for long text but my problem is long :-) I made grid like this

$this->widget('zii.widgets.grid.CGridView', array(
    'dataProvider'=>$model->search(),
    'filter'=>$model,
    'columns'=>array(
        array(
            'name'=>'title',
            'type'=>'raw',
            'value'=>'CHtml::link(CHtml::encode($data->title), $data->url)'
        ),
        array(
            'name'=>'create_time',
            'type'=>'raw',
            'value' => 'Yii::app()->dateFormatter->format("yyyy", $data->create_time)',
        ),
    ),
));

and then i want to filtering by date like title filtering, by textfield. I made controller with code

$model=new Post('search');

if(isset($_GET['Post']))
    $model->attributes=$_GET['Post'];
    $this->render('admin',array(
        'model'=>$model,
            ));

and search methode in model

public function search()
    {
        $criteria=new CDbCriteria;

        $criteria->compare('title',$this->title,$partialMatch=true);

        $criteria->compare('create_time',$this->create_time,$partialMatch=true);

        return new CActiveDataProvider('Post', array(
            'criteria'=>$criteria,
            'sort'=>array(
                'defaultOrder'=>'status, update_time DESC',
            ),
        ));
    }

i don't forget abount rules()

array('title, create_time', 'safe', 'on'=>'search')

I have got two records wiht today's date. Title filtering works fine but when i type '2015' in 'create_time' column filter textfield and press enter i get "no results found".

I tried this:

array(
        'name'=>'create_time',
        'type'=>'raw',
        'value' => 'Yii::app()->dateFormatter->format("dd MMMM yyyy", $data->create_time)',
        'filter' => CHtml::listData(Post::model()->findAll(array('order'=>'create_time')), 'create_time', 'create_time'),
        ),

and it's seems to work but in my database, create_time is integer(11) (required) and listdata values is number not date and represents full date, not only year. I controller i made array with unique year values from create_time record's values. Outputs array like $rok['2015'] => '2015'

$model_post = new Post;
$wyniki = $model_post::model() -> findAllBySql('SELECT create_time FROM tbl_post');
for($i=0;$i<count($wyniki);$i++)
{
    $rok_temp[$i] = Yii::app()->dateFormatter->format("yyyy", $wyniki[$i]->create_time);
    $rok[$rok_temp[$i]] = $rok_temp[$i];
}
$rok = array_unique($rok);

I send $rok to view and

array(
            'name'=>'create_time',
            'type'=>'raw',
            'value' => 'Yii::app()->dateFormatter->format("dd MMMM yyyy", $data->create_time)',
            'filter' => $rok,
            ),

and

$criteria->compare('create_time',Yii::app()->dateFormatter->format("yyyy", $this->create_time));

but then i get "no results found" when filtering. What i made wrong?

Bejkrools
  • 1,129
  • 2
  • 17
  • 38
  • How is `create_time` being set before your model is saved? – topher May 04 '15 at 06:11
  • `protected function beforeSave() { if(parent::beforeSave()) { if($this->isNewRecord) { $this->create_time=$this->update_time=time(); $this->author_id=Yii::app()->user->id; } else $this->update_time=time(); return true; } else return false; }` – Bejkrools May 04 '15 at 08:14

1 Answers1

1

Your time is stored as a UNIX timestamp. You therefore have to do some conversion on the input from the filter to change it to UNIX also. First, create a variable to hold the year in your model

class MyModel extends ... {
    public $create_year;
}

Then add this variable to your rules:

array('create_year', 'safe', 'on' => 'search')
array('create_year', 'numerical', 'integerOnly' => true)

Next add the conversion rules for the year to your search() i.e

public function search() {
    ...
    if ($this->create_year) {
        $criteria->addBetweenCondition('create_time',
            strtotime($this->create_year.'-01-01 00:00:00'),
            strtotime($this->create_year.'-12-31 23:59:59')
        );
    }
    ...
}

Lastly change your filter to a dropdown to reduce invalid entries:

'filter' => CHtml::activeDropDownList(
    $model, 
    'create_year',
    array_combine(range(1900, 2099), range(1900, 2099),
    array('prompt' => 'Any year')
)
topher
  • 14,790
  • 7
  • 54
  • 70
  • i made filter: `CHtml::dropDownList('create_year', $select, array(2013 => 2013, 2014 => 2014, 2015 => 2015), array('empty' => 'Dowolny') ),` – Bejkrools May 04 '15 at 10:54
  • model: `public $create_year;` rules: `array('title, status, create_time, create_year', 'safe', 'on'=>'search'), array('create_year', 'numerical', 'integerOnly' => true),` search: `if ($this->create_year) { $criteria->addBetweenCondition('create_time', time($create_year.'-01-01 00:00:00'), time($create_year.'-12-31 23:59:59') ); }` but still nothing happend when trying, even i don't get _no results found_. It seems to criteria not working. – Bejkrools May 04 '15 at 11:01
  • It has to be an `ActiveDropDownList` for [massive assignment](http://www.yiiframework.com/wiki/161/understanding-safe-validation-rules/#hh2) to work. – topher May 04 '15 at 11:10
  • Youre way with filter gives _Error 500 include(CActiveDropDownList.php): failed to open stream: No such file or directory_ :-( – Bejkrools May 04 '15 at 11:18
  • Now works only **Any year**, _no results found_ when other selected. For sure leatest create_time value is _1430736519_ and is from today. (i corrented your code, you forgotten about one `)` at `array_combine`) – Bejkrools May 04 '15 at 11:29
  • It should be `$this->create_year` not `$create_year`. The answer has been updated. – topher May 04 '15 at 11:35
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/76880/discussion-between-bejkrools-and-topher). – Bejkrools May 04 '15 at 11:38