B
B
Bogdan Pasechnik2015-04-10 09:07:30
Yii
Bogdan Pasechnik, 2015-04-10 09:07:30

What is the best way to handle date with datepicker in yii2?

Question exclusively on yii2.
yii\jui\DatePicker returns the date in the format dd.yyyy.MM. It is stored in the int field in the database. And of course it is necessary to convert the date.
What is the best way to do this, given that the form should work correctly.
- If the date is already selected, the field should be filled with the correct value
- An int value should be written to the database if the date field is filled and cleared if it was made empty
----------
Now I decide like this.

/**
 * @property integer $some_time - поле в базе
 */
class News extends ActiveRecord {

    public function rules() {
        return ;
    }

    public function getSomeTimeDate() {
        return $this->some_time? date('d.m.Y', $this->some_time) : '';
    }

    public function setSomeTimeDate($date) {
        $this->some_time= $date ? strtotime($date) : null;
    }
}
...
echo $form->field($model, 'someTimeDate')->widget('common\widgets\Datepicker', [
    'dateFormat' => 'dd.mm.yy',
])

And I'm working with the someTimeDate field. In this version, everything suits except for the need to write a getter and setter for the field.
The yii\validators\DateValidator has a timestampAttribute property that allows you to convert the date into the required format for the database. But I have not found a use for it. Because it is no longer needed for methods. And if you use the formatted date property, then it will not be filled with the value from the base.

Answer the question

In order to leave comments, you need to log in

4 answer(s)
V
vyachin, 2015-04-10
@vyachin

You will need to configure the validation www.yiiframework.com/doc-2.0/guide-tutorial-core-v... specify the format in which the date will come from the browser (format=>'php:dYm') and specify the name of the attribute in the database (timestampAttribute )

K
krypt3r, 2015-04-10
@krypt3r

Formatter

Q
qorp, 2016-04-29
@qorp

The topic was considered for a long time, but suddenly it will come in handy for someone, he himself faced such a task. Alternatively
Create a DateToTimeBehavior

<?php

namespace common\behaviors;

use yii\behaviors\AttributeBehavior;
use yii\base\InvalidConfigException;
 

class DateToTimeBehavior extends AttributeBehavior {

    public $timeAttribute;

    public function getValue($event) {

        if (empty($this->timeAttribute)) {
            throw new InvalidConfigException('Can`t find "fromAttribute" property in ' . $this->owner->className());
        }
        if (!empty($this->owner->{$this->attributes[$event->name]})) {
            $this->owner->{$this->timeAttribute} = strtotime($this->owner->{$this->attributes[$event->name]});
            return date('d.m.Y', $this->owner->{$this->timeAttribute});
        } else {
            if (!empty($this->owner->{$this->timeAttribute})) {
                $this->owner->{$this->attributes[$event->name]} = date('d.m.Y', $this->owner->{$this->timeAttribute});
                return $this->owner->{$this->attributes[$event->name]};
            }
        }
        
        return date('d.m.Y', time());
    }

}

In the model, we create a property for storing the date in the format 'dmY' , or another format convenient for you (the main thing is not to forget about validation). This behavior will write a value to the time field if we received something from the form. Otherwise, the date variable in the model will be initialized by the value in time.
... ... ...
use common\behaviors\DateToTimeBehavior;

... ... ...
   public $date;
... ... ...

And we connect the created behavior to our model
... ... ...
public function behaviors() {
        return [
            [
                'class' => DateToTimeBehavior::className(),
                'attributes' => [
                    ActiveRecord::EVENT_BEFORE_VALIDATE => 'date',
                    ActiveRecord::EVENT_AFTER_FIND => 'date',
                ],
                'timeAttribute' => 'time', //Атрибут модели в котором хранится время в int
            ],
        ];
    }
... ... ...

in view in activeField output
use kartik\date\DatePicker;

<?php $form = ActiveForm::begin(); ?>
 <?= $form->field($model, 'date')->widget(
       DatePicker::className()
    )?>
<?php ActiveForm::end(); ?>

R
Ruslan, 2016-06-07
@mitrm

in the view

if(!empty($model->end_at)){
    $model->end_at = date('d.m.Y H:i', $model->end_at);
}

In the model
/**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['start_at', 'end_at'], 'filter', 'filter' => function ($value) {
                if(!preg_match("/^[\d\+]+$/",$value) && $value > 0){
                    return strtotime($value);
                }
                else{
                    return $value;
                }
            }],
        ];
    }

And all

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question