2010-12-01 5 views
1

Ich benötige ein Start- und Endzeit-Widget in einem Formular.Symfony Forms Start- und Endzeit-Widget

d.h. der Benutzer wählt ein Datum aus und wählt dann die Start- und Endzeit aus.

Im Standard-Datums-Widget können Sie ein Datum und eine Uhrzeit auswählen, aber ich muss auch eine Endzeit auswählen können.

Haben Sie es schon einmal getan?

I 3 separate Widgets erstellen konnte:

  • Datum
  • Startzeit
  • Endzeit

Wenn das Formular gespeichert wird, werde ich auf das Objekt ein Update tun, um Kombiniere alle Werte zu einem. Zum Beispiel werde ich das Datum und die Startzeit hinzufügen und dann in das Feld "Startdatum" speichern und dann werde ich das Datum und die Endzeit hinzufügen und dann in das Feld "Enddatum" speichern. Es scheint jedoch ein sehr langatmiger Weg zu sein, etwas zu tun, was für einen Formularrahmen ziemlich trivial sein sollte.

So würden Sie es tun? Danke Leute!

+0

Also gibt es 2 db Felder, start_date und end_date, jeder Zeitstempel? –

+0

Yups, genau das.Das Datum für jeden wird gleich sein, aber die Zeiten für jeden werden anders sein (Hoffnung, die Sinn macht) – Flukey

Antwort

2

Ich denke, was Sie mit symfony Formen erreichen wollen, ist ziemlich einfach. Sie haben Recht, Sie benötigen drei separate Widgets und drei separate Validatoren, für diese genaue Situation gibt es keine Out-of-the-Box-Lösung.

In Ihrem Formular configure Methode würden Sie so etwas wie haben:

$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(), 
)); 

Nehmen wir an, dass das Objekt zwei Eigenschaften, wie Sie vorgeschlagen, beide sind Datetime-Felder.

In Ihrer Aktion würden Sie so etwas wie die folgenden können Sie die Datetime-Felder haben:

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

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

Edit: ein weiterer Vorschlag nicht die in der Zeit Widget sfWidgetFormTime gebaut verwenden, da es ziemlich hässlich aussehen kann. Sie können einfach ein normales Textfeld verwenden (mittig ausgerichtet mit maxlength = 5), und der Validierer sfValidatorTime funktioniert immer noch einwandfrei.

Hoffe, dass hilft.

+0

Hallo Mark, das ist so ziemlich wie ich es gemacht habe. Außerdem musste ich ein paar zusätzliche Bits hinzufügen (z. B. das Füllen der Felder, wenn Sie einen Datensatz bearbeiten usw.). Nehmen Sie trotzdem den Ruf des Bounty für seinen Beitrag! Vielen Dank! – Flukey

1

Ihre Anforderung klingt anwendungsspezifisch und nicht wirklich etwas, das Ihnen das Symfony Formularframework mit Out-of-the-Box helfen würde.

Ich würde mit Ihrem Vorschlag gehen, start_date und end_date aus der Ausgabe der drei Widgets zu generieren, oder wenn Ihre Anwendung Datum, start_time und end_time separat später zurückgeben muss, dann möglicherweise nur drei Werte getrennt speichern und manipulieren, wenn sie abgefragt werden .

+0

Hallo Tom. Ja, ich werde es so machen. Bei allem Respekt, Sie hätten gedacht, es wäre ein Out-of-the-Box-Widget. Eisenbahnunternehmen, Flughäfen, Fluggesellschaften, Hotelgesellschaften, Management usw. würden wahrscheinlich zu einem bestimmten Zeitpunkt ein "Startzeit" - und "Endzeit" -Widget verwenden. Wenn ich jedoch das Widget erstelle, werde ich den Quellcode freigeben, um anderen zu helfen. – Flukey

1

Also, ich habe den Code dafür gemacht und es funktioniert sehr gut. Ich habe alle unnötigen Widgets und Validatoren entfernt. Hier ist, wie ich es gemacht habe:

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(); 

    } 
}