去掉三个<select>
元素并允许用户只在常规<input type="text">
控件中键入日期的标准方法是什么?
要求包括:
- 日期格式必须为D/M/Y
- 必须正确打印现有日期
- 无法中断日期验证
我找不到任何合理的文档,只是在论坛线程中由像我这样一无所知的用户编写的黑客xD
澄清:请注意CakePHP标记。我已经知道如何用普通PHP处理日期了。我需要关于精确的CakePHP机制的帮助,我可以使用它来调整框架的默认功能(我真正的意思是调整而不是覆盖)。
到目前为止,我已经在模型中添加了这个:
public $validate = array(
'fecha' => array(
array(
'rule' => 'notEmpty',
'required' => true,
),
array(
'rule' => array('date', 'dmy'),
),
)
);
我在视图中组成了这样的字段:
echo $this->Form->input(
'Foo.fecha',
array(
'type' => 'text',
)
);
但我所能做的就是读取和验证用户输入:它不会正确打印以前的日期,也不会正确存储新的日期。
以下是我的发现摘要。似乎合适的机制是使用模型回调方法在两种日期格式之间切换:
- 数据库格式,例如:
2012-08-28
- 显示格式,例如:
28/08/2012
步骤:
- 在
AppModel
中添加两个实用程序方法,以在我的自定义格式(也称为"显示格式")和MySQL的默认格式(也称"DB格式")之间进行转换 - 在我的模型中添加一个
afterFind()
过滤器,当从DB中读取时,它会转换为显示格式 - 将表单控件渲染为
'type' => 'text'
- 将
'rule' => array('date', 'dmy')
验证规则添加到模型内部的字段中 - 在我的模型中添加一个
beforeSave()
过滤器,在保存之前将其转换为DB格式
这些步骤可以用实现afterFind()
和beforeSave()
回调以及可能的其他一些回调(如beforeFind()
)的行为来封装。该行为可以直接应用于AppModel
,并负责遍历数据数组以在两种格式之间转换日期(如果模型有一个附加表)。代码不是琐碎的,而是可以完成的,它使一切都透明。
缺点:
- 只生成MySQL代码(但是,它不是已经只生成MySQL了吗?)
- 使本地化变得困难
- 如果你需要计算日期,你会发现自己有人类可读的字符串
能够使用三种格式将更加坚如磐石:
- 数据库格式,例如:
2012-08-28
- 显示格式,例如:
28/08/2012
- PHP内部格式,例如Unix时间戳或
DateTime
对象
遗憾的是,CakePHP核心并不是为此而设计的,如果你试图以这种方式实现它,一切都会变得太复杂。
唯一可能的方法是让用户键入他想做的任何事情,然后在他想提交表单或其他东西时检查其有效性。或者更好的方法是使用jQuery日期选择器。
如果您将使用助手编写输入字段,formhelper
的input
方法有一个type
选项。试试这个,例如:
<?php
echo $this->Form->input('birth_dt', array(
'type' => 'text',
'label' => 'Date of birth',
));
编辑:(阅读您的评论后)
如果是这样,解决方案可以是在提交表单后验证输入值或者使用ajax验证。