首页 > 解决方案 > Yii2 gridview 日期范围选择器过滤器不起作用

问题描述

我已将 kartik-v 日期范围选择器添加到我的网格视图中,但在我选择日期后过滤器无法工作。小部件的占位符将显示所选日期,但网格视图中的结果不匹配。网格视图中的结果显示所有数据。

视图中的代码:

<?= GridView::widget([
    'options' => ['class' => 'table-sm'],
    'filterModel' => $searchModel,
    'dataProvider' => $dataProvider,
    'summary' =>'',
    'columns' => [
        [
            'attribute' => 'price',
            'value' => function ($model) {
                return number_format($model->price, 3);
            },
            'contentOptions' => ['class' => 'text-right']
        ],
        [
            'attribute' => 'date',
            'contentOptions' => ['class' => 'text-right'],
            'filter' => DateRangePicker::widget([
                'name'=>'date_range_2',
                'presetDropdown'=>true,
                'convertFormat'=>true,
                'includeMonthsFilter'=>true,
                'attribute' => 'date',
                'model' => $searchModel,
                'pluginOptions' => ['locale' => ['format' => 'Y-m-d']],
                'options' => ['placeholder' => 'Select Date']
            ])
        ],
    ]
]); ?>

下面的代码是我的 $searchModel 部分。
更新:

public function rules()
{
    return [
        [['id'], 'integer'],
        [['name', 'date'], 'safe'],
        [['price'], 'number'],
    ];
}

/**
 * {@inheritdoc}
 */
public function scenarios()
{
    // bypass scenarios() implementation in the parent class
    return Model::scenarios();
}

/**
 * Creates data provider instance with search query applied
 *
 * @param array $params
 *
 * @return ActiveDataProvider
 */
public function search($params)
{
    $query = Lme::find()->orderBy([
        'date' => SORT_DESC
    ]);

    // add conditions that should always apply here

    $dataProvider = new ActiveDataProvider([
        'query' => $query,
        'sort' => false //['defaultOrder' => ['date' => SORT_DESC]]
    ]);

    $this->load($params);

    if (!$this->validate()) {

        return $dataProvider;
    }

    // grid filtering conditions
    $query->andFilterWhere([
        'id' => $this->id,
        'price' => $this->price,
        'date' => $this->date,
    ]);

    $query->andFilterWhere(['like', 'name', $this->name]);


    return $dataProvider;
    }

标签: gridviewyii2kartik-v

解决方案


DateRangePicker 本身为您提供了一个带有范围的字符串,因此一个简单的 where 子句'date' => $this->date不起作用。Kartik V.kartik\daterange\DateRangeBehavior在包中提供了一个行为kartik-v/yii2-date-range

我以以下方式成功使用它。请注意,我的时间戳属性是timestamp_visit.

在视图中:

echo GridView::widget([
...
    'columns' => [
        [
            'attribute' => 'timestamp_visit',
            'format' => [
                'datetime',
                'medium'
            ],
            'width' => '60px',
            'filterType' => GridView::FILTER_DATE_RANGE,
            'filterWidgetOptions' => [
                'model' => $searchModel,
                'convertFormat' => true,
                'pluginOptions' => [
                    'timePicker' => true,
                    'timePickerIncrement' => 1,
                    'timePicker24Hour' => true,
                    'locale' => [
                        'format' => $searchModel::TIME_FORMAT,
                    ]
                ]
            ]
        ],
    ...
    ]

在搜索模型中:

<?php
...
use kartik\daterange\DateRangeBehavior;

class ...Search extends ....
{
    const TIME_FORMAT = 'Y-m-d H:i:s';

    /**
     * @var string Start date filled up by DateRangeBehavior
     */     
    public $timestampVisitStart;

    /**         
     * @var string End date filled up by DateRangeBehavior
     */         
    public $timestampVisitEnd;
...

       public function rules()
    {
        return [
            [['timestamp_visit'], 'match', 'pattern' => '/^.+\s\-\s.+$/'],
            ...
        ];
    } 
    public function behaviors()
    {
        return [
            [
                'class' => DateRangeBehavior::class,
                'attribute' => 'timestamp_visit',
                'dateStartAttribute' => 'timestampVisitStart',
                'dateEndAttribute' => 'timestampVisitEnd',
                'dateStartFormat' => self::TIME_FORMAT,
                'dateEndFormat' => self::TIME_FORMAT,
            ]
        ];
    }
...
    public function search($params)
    {
        $query = self::find();

        $dataProvider = new ActiveDataProvider([
            'query' => $query
        ]);

        $dataProvider->sort = new Sort([
            'defaultOrder' => [
                'timestamp_visit' => SORT_DESC,
                'id' => SORT_DESC,
            ]
        ]);
...
        if ($this->timestampVisitStart) {
            $query->andWhere(['>=', "timestamp_visit", $this->timeToUTC($this->timestampVisitStart)]);
        }
        if ($this->timestampVisitStart) {
            $query->andWhere(['<=', "timestamp_visit", $this->timeToUTC($this->timestampVisitEnd)]);
        }

        return $dataProvider;
   }

   /**
     * Convert string time in format $format to UTC time format for SQL where clause
     * @param string $time Time in format $format
     * @param string $format Format of $time for the function date, default 'Y-m-d H:i:s'
     */
    private function timeToUTC($time, $format='Y-m-d H:i:s')
    {
        $timezoneOffset = \Yii::$app->formatter->asDatetime('now', 'php:O');
        return date($format, strtotime($time.$timezoneOffset));
    }
}

推荐阅读