Виджет времени начала и окончания форм Symfony - PullRequest
1 голос
/ 02 декабря 2010

Мне нужно иметь виджет времени начала и окончания в форме.

т.е. пользователь выбирает дату, а затем выбирает время начала и окончания.

В стандартном виджете даты вы можете выбрать дату и время, однако мне также нужно иметь возможность выбрать время окончания.

Кто-нибудь из вас делал это раньше?

Я мог бы создать 3 отдельных виджета:

  • Дата
  • Время начала
  • Время окончания

Когда форма будет сохранена, я обновлю объект, чтобы объединить все значения в одно. Например, я получу дату и добавлю к ней время начала, а затем сохраню в поле «start_date», а затем получу дату и добавлю к ней время окончания, а затем сохраню в поле «end_date». Однако кажется, что это очень долгий способ сделать что-то, что должно быть довольно тривиально для каркаса форм.

Это как ты это сделал? Спасибо, ребята!

Ответы [ 3 ]

2 голосов
/ 06 декабря 2010

Я думаю, что вы хотите достичь с помощью форм Symfony, довольно легко. Вы правы, вам нужны три отдельных виджета и три отдельных валидатора, для этой конкретной ситуации не существует готового решения.

В вашем методе настройки формы у вас будет что-то вроде:

$this->setWidgets(array(
  'date' => new sfWidgetFormDate(),
  'time_start' => new sfWidgetFormTime(array('label' => 'Start Time', 'with_seconds' => false)),
  'time_finish' => new sfWidgetFormTime(array('label' => 'End Time', 'with_seconds' => false)
));

$this->setValidators(array(
  'date' => new sfValidatorDate(),   // by default outputs in format Y-m-d
  'time_start' => new sfValidatorTime(),  // by default outputs in format H:i:s
  'time_finish' => new sfValidatorTime(),
));

Предположим, что у объекта есть два свойства, как вы и предполагали, оба являются полями даты и времени.

В вашем действии вам нужно что-то вроде следующего для установки полей даты и времени:

$values = $this->form->getValues();

$object->setStartDateTime(sprintf('%s %s', $values['date'], $values['time_start']));
$object->setFinishDateTime(sprintf('%s %s', $values['date'], $value['time_finish']));

Редактировать: другое предложение не использовать встроенный виджет времени sfWidgetFormTime, поскольку он может выглядеть довольно уродливо. Вы можете просто использовать обычное текстовое поле (выровненное по центру, с maxlength = 5), и валидатор sfValidatorTime все равно будет работать идеально.

Надеюсь, это поможет.

1 голос
/ 06 декабря 2010

Итак, я сделал код для него, и он работает очень хорошо. Я удалил все ненужные виджеты и валидаторы. Вот как я это сделал:

class VisitForm extends BaseVisitForm
{
  private function getMinutes()
  {
     $minutes = array();

     for($i = 0; $i < 60; $i = $i + 5)
     {
       $minutes[$i] = sprintf('%02d', $i);
     }
     return $minutes;   
  }

  public function configure()
  {

      $this->setWidgets(array(
      'id'            => new sfWidgetFormInputHidden(),
      'date'            => new sfWidgetFormJQueryDate(array('date_widget' => new sfWidgetFormDate(array('years' => $years, 'can_be_empty'=> false)), 'image' => '/images/icons/calendar.png', 'format'=>'%day%/%month%/%year%')),
      'start_time'    => new sfWidgetFormTime(array('with_seconds' => false,'can_be_empty'=> false, 'default' => '08:00', 'minutes'=> array_combine($this->getMinutes(), $this->getMinutes()))),
      'end_time'          => new sfWidgetFormTime(array('with_seconds' => false,'can_be_empty'=> false, 'default' => '08:00', 'minutes'=> array_combine($this->getMinutes(), $this->getMinutes())))

    ));

    $this->setValidators(array(

      'start_time'    => new sfValidatorTime(),
      'end_time'      => new sfValidatorTime(),
      'date'            => new sfValidatorDate(),
    ));

    $this->widgetSchema->setNameFormat('visit[%s]');

    $this->errorSchema = new sfValidatorErrorSchema($this->validatorSchema);
  }

 protected function doUpdateObject($values)
  {     
    $this->getObject()->setStartDate(sprintf("%s %s", $values['date'], $values['start_time']));
    $this->getObject()->setEndDate(sprintf("%s %s", $values['date'], $values['end_time']));

    parent::doUpdateObject($values);
  }

  public function updateDefaultsFromObject()
  {
    if(!$this->getObject()->isNew())
    {
        $this->setDefault('date', $this->getObject()->getDateTimeObject('start_date')->format('Y-m-d'));
        $this->setDefault('start_time', $this->getObject()->getDateTimeObject('start_date')->format('H:i'));
        $this->setDefault('end_time', $this->getObject()->getDateTimeObject('end_date')->format('H:i'));
    }
    parent::updateDefaultsFromObject();

  }
}
1 голос
/ 02 декабря 2010

Ваше требование звучит специфично для конкретного приложения, а не совсем то, что фреймворк форм Symfony поможет вам в готовом виде.

Я бы пошел с вашим предложением генерировать start_date и end_date из выходных данных трех виджетов, или если вашему приложению нужно позже возвращать date, start_time и end_time отдельно, то возможно просто сохранить три значения отдельно и манипулировать ими при запросе.

...