分割日期时间值时的智能

时间:2010-10-06 20:38:34

标签: datetime cakephp-1.3

我的Event模型中有一个日期时间值。不是Cake的自动输入的默认美学的忠实粉丝,我将创建自己的。我的理解,虽然只是从阅读中得知,但是Cake提供了一些关于在保存时连接日期时间值的智能。具体来说,它将检测日期时间值的月,日,年,小时,分钟和子午线子部分,并在保存时自动组合它们。

我更感兴趣的是,但没有证据表明,这是一个更简单的细分。我想用日期部分的日期选择器和默认时间输入,你猜对了,时间。 Can Cake能做到吗?我试过了它并没有用,但我不确定这是因为我做错了什么还是没有合适的东西。

我当然可以毫不费力地自己做这件事,但是如果Cake已经有了这个内置功能并且我只是没有正确解锁它,那么一些努力比没有努力更多。

感谢。

1 个答案:

答案 0 :(得分:0)

通过源代码访问,特别是Model::deconstruct()告诉我,Cake的本地智能并没有这么深入。它期望由其自己的日期时间输入提供的完整组件粒度(即,月,日,年,小时,分钟和子午线的单独日期时间组件)。我想要更好的用户体验,所以我想使用日期选择器将整个日期存储为单个组件。要做到这一点,我必须发挥创意。

我选择做的是覆盖Model::deconstruct()方法以将日期分解为其组件。这里有一些代码可以帮助可视化我希望部署的解决方案:

# 
# In my form (views/events/_form.ctp)
# When rendered, the input names resolve to data[Event][start_time][date], 
# data[Event][start_time][hour], data[Event][start_time][minute], 
# data[Event][start_time][meridian]
# 
<div class="input datetime required">
  <?php echo $this->Form->input( 'Event.start_time.date', array( 'type' => 'text', 'label' => 'Start Time', 'div' => false, 'class' => 'date' ) ) ?>
  <?php echo $this->Form->input( 'Event.start_time', array( 'type' => 'time', 'label' => false, 'div' => false, 'class' => 'time', 'empty' => true ) ) ?>
</div>

# 
# In my model (/models/event.php)
# 
function deconstruct( $field, $data ) {
  $type = $this->getColumnType( $field );

  if( in_array( $type, array( 'datetime', 'timestamp' ) ) ) {
    if( isset( $data['date'] ) && !empty( $data['date'] ) ) {
      $date = date( 'U', strtotime( $data['date'] ) );

      if( $date ) {
        $data['month'] = date( 'm', $date );
        $data['day']   = date( 'd', $date );
        $data['year']  = date( 'Y', $date );
      }
    }
  }

  # Now the date is broken down into components that the
  # well-vetted parent method expects. Let it do the heavy 
  # lifting.
  return parent::deconstruct( $field, $data );
}

为清楚起见,我已经排除了创建选择器本身的javascript代码。这是一个应用于data[Event][start_time][date]字段的简单jQuery UI行为,与解决方案没有密切关系。可以说,当date文本框收到焦点时,会出现一个非常漂亮的日历。

在我的情况下,我还有几个具有日期时间属性的模型,所以我最终将deconstruct()覆盖移到我的AppModel,所以我可以在整个过程中使用它。 DRY。