在CakePHP中处理复杂数据类型的最佳方法是什么?

时间:2011-11-05 04:20:37

标签: cakephp date cakephp-2.0

我的目标:替换默认蛋糕日期选择器

讨厌默认的CakePHP FormHelper日期选择器选择元素,我想改用jQuery UI Datepicker小部件。为了优雅地降级,我希望有一个日期字段(使用小部件启用)和时间选择器选择框约束为15分钟增量。

如果我解释得不好,这就是它的样子:

date-picker sample

我的理想解决方案

为了尽量减少重复,我想将HTML放在布局元素中并使用Behavior函数处理它。通过这种方式,我可以执行以下操作:

view.ctp

echo $this->element( 'datepicker', array( 'data' => $data ) );

model.php

$actsAs = array( 'Datepicker' );

function beforeSave( $options ){
    $this->parseDatepickers();  //behavior function would alter $this->data
    return true;
}

问题

不幸的是,当它到达beforeSave(或beforeValidate)回调时,日期选择器& timepicker字段已被模型的deconstruct函数破坏。 deconstruct似乎正在寻找日期&时间以FormHelper创建它们的方式报告。

简而言之,它正在寻找:

[date_field] => Array
(
    [year] => 2011
    [month] => 11
    [day] => 11
    [hour] => 8
    [min] => 00
    [meridian] => pm
)

但相反它的发现:

[date_field] => Array
(
    [datepicker] => 11/11/2011
    [timepicker] => 8:00 pm
)

因为它没有找到它所期望的结构,所以我最终得到了这个:

[date_field] =>

我知道我可以使用适当命名的字段更新jQuery更新隐藏输入,但这不会很好地降级。

当前解决方法

目前我正在做的是在保存之前通过我的行为功能清洗数据 - 但这并不是正确的做法:

$this->request->data = $this->Event->fixDates( $this->data );
$this->Event->save( $this->data );

所以...............

最好的方法是什么?将它放在beforeSavebeforeValidate似乎"蛋糕方式",但deconstruct杀了我。我是否需要扩展AppModel并覆盖deconstruct?这看起来也很难看。

1 个答案:

答案 0 :(得分:2)

我通常在视图中将我的日期字段作为文本字段覆盖默认的Form Helper输出,然后使用jQuery日期选择器(或任何您的替代选择器)来设置日期:

echo $this->Form->input('date', array('type' => 'text', 'class' => 'datepicker'));

这将输出一个典型的标签,而不是所有的下拉。

然后,在我的模型的beforeSave函数中,我将格式更改为MySQL格式化日期:

$this->data['Model']['date'] = date('Y-m-d G:i:s', strtotime($this->data['Model']['date']));

(记得在beforeSave中返回true)

这适用于数据库中正确的datetime数据类型,听起来就像你想要做的那样。