Yii: Добавляем ввод даты с помощью CJuiDatePicker

Yii: Добавляем ввод даты с помощью CJuiDatePicker Вешаем на поля ввода даты визуальный календарик CJuiDatePicker, чтобы пикать и выбирать дату, а не вводить её цифрами в формате, годном для MySQL.

Упрощаем ввод дат с помощью CjuiDatePicker (http://www.yiiframework.com/doc/api/1.1/CJuiDatePicker). В базе данных у нас есть, к примеру, поля - date_start и date_finish, оба MySQL формата 'datetime'.

используем CJuiDatePicker в Yii

В админке пользователь вручную вводит дату в поля input в формате "CCYY-MM-DD".

используем CJuiDatePicer в Yii для полей с датами

Боремся с неудобством с помощью класса CJuiDatePicker. Заменяем в виде наши textField:

<?php echo $form->labelEx($model,'date_start'); ?>
<?//php echo $form->textField($model,'date_start'); ?>
<?php $this->widget('zii.widgets.jui.CJuiDatePicker', array(
   'name' => 'date_start',
   'model' => $model,
   'attribute' => 'date_start',
   'language' => 'ru',
   'options' => array(
       'showAnim' => 'fold',
   ),
   'htmlOptions' => array(
       'style' => 'height:20px;'
   ),
));?>
<?php echo $form->error($model,'date_start'); ?>

И осталось пару методов в модель добавить:

protected function beforeSave() {
   if(parent::beforeSave()) {
       $this->date_start = date('Y-m-d', strtotime($this->date_start));//strtotime($this->date_start);
       return true;
   } else {
       return false;
   }
}


protected function afterFind() {
   $date = date('d.m.Y', strtotime($this->date_start));
   $this->date_start = $date;
   parent::afterFind();
}

Первый преобразует дату полученную от CJuiDatePicker в формат datetime для MySQL. Если вы храните дату в БД в формате числа (int), то надо убрать из beforeSave() обработку функцией date, то есть: date('Y-m-d', strtotime($this->date_start)).

А 'afterFind' наоборот из поля БД для отображения в поле формы преобразует дату в формат "12.05.2012".

CJuiDatePicker в Yii

И на всякий случай добавим правило в rules() модели, потому что в CJuiDatePicker человек всё-таки может вручную вводить цифры не соблюдая оговоренного формата:

...
array('date_start, date_finish', 'date', 'format'=>'dd.MM.yyyy'),
...

Кому будет интересно, подложите маску на поля дат, чтобы вообще жёстко ограничить ввод от пользователя.

Источник: loco.ru

almix
Разработчик Loco, автор статей по веб-разработке на Yii, CodeIgniter, MODx и прочих инструментах. Создатель Team Sense.

Вы можете почитать все статьи от almix'а.



Другие статьи по этой теме:

Комментарии (8)     Подпишитесь на RSS комментариев к этой статье.

8 комментариев

#616
cpentyc говорит:
August 21, 2012 at 09:25 am
А вы не вкурсе почему при неудачной валидации формы введенные данные не сохраняются?
#734
anton говорит:
December 25, 2012 at 07:18 pm
Спасибо, было полезно!
#785
Melon говорит:
February 27, 2013 at 07:04 pm
Нормально так, и достаточно просто. А я голову ломал.
#822
Павел говорит:
April 3, 2013 at 05:59 pm

Я перевод даты из одного формата в другой оформил в поведение. Дергаю в нужных мне моделях. На мой взгляд, так удобнее.

#901
Лена говорит:
July 1, 2013 at 11:08 am

Помогите разобраться, куда именно прописывать приведенные выше строчки кода? Я буквально вчера начала разбираться с yii. Задание у меня такое: нужна возможность ввода отпускного периода сотрудника и отправка его на рассмотрение по кнопке. С кнопкой пока ладно. А вот календари ваши подходят. Но в какие именно файлы прописывать код не понимаю.

#902
almix говорит:
July 1, 2013 at 11:58 am
Лена, в папке protected/views/... в нужном вам файле представления формы (например в "_form.php") заменяете textField на календарь (см. первый код в статье) и потом в соответствующей этому представлению модели вставьте функции преобразования даты в beforeSave и afterSave.
#905
Лена говорит:
July 2, 2013 at 09:51 am
Спасибо за столь оперативный ответ. В принципе добавить календарь получилось, вот только вместо русских букв у меня абракадабра.
#1078
Alex D говорит:
January 29, 2014 at 02:22 pm

Спасибо за пример, но хотел бы немного внести свои усовершенствования в медоты, а именно - сделать их более универсальными для того, чтоб можно было копи-пастить их в любую модель с любым количеством полей - пусть сам все обрабатывает и автоматом меняет:

protected function beforeSave() {
if(parent::beforeSave()) {
foreach($this->metadata->tableSchema->columns as $columnName => $column){
if ($column->dbType === 'date') $this->$columnName = date('Y-m-d', strtotime($this->$columnName));
}
return true;
}
else return false;
}

protected function afterFind() {
foreach($this->metadata->tableSchema->columns as $columnName => $column){
if ($column->dbType === 'date'){
$this->$columnName = Yii::app()->dateFormatter->format('dd.MM.yyyy',$this->$columnName);
}
}
parent::afterFind();
}

просто копи-пасте код в свою модель и все магически "превратится" ;)