2011-11-05 3 views
8

mio obiettivo: sostituire il predefinito torta Datepicker

ho odio la CakePHP FormHelper data-selettore predefinito selezionare gli elementi e mi piacerebbe utilizzare widget di jQuery UI Datepicker invece. Per degradare con garbo, voglio avere un campo data (abilitato con il widget) e una casella di selezione del time-pick vincolata ad incrementi di 15 minuti.Qual è il modo migliore per elaborare tipi di dati complessi in CakePHP?

In caso ho spiegato che male, ecco come appare:

date-picker sample

My Ideal Soluzione

Per ridurre al minimo la ripetizione, voglio mettere il codice HTML in un layout di elementi e di processo usando una funzione Behavior. In questo modo ho potuto fare qualcosa di simile al seguente:

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; 
} 

Il problema

Purtroppo, dal momento in cui arriva al callback beforeSave (o beforeValidate), il datepicker I campi & timepicker sono stati distrutti dalla funzione deconstruct del modello. deconstruct sembra essere alla ricerca di date & da segnalare nel modo in cui FormHelper le crea.

In breve, è alla ricerca di:

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

ma invece è trovare:

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

E perché non trova la struttura che si aspetta, io alla fine con questo:

[date_field] => 

So che posso avere input nascosti di aggiornamento jQuery con i campi con nome appropriato , ma questo non si degraderebbe bene.

attuale Soluzione

Quello che sto facendo, per il momento, sta lavando i dati attraverso la mia funzione comportamento prima di salvare - ma questo non si sente come il modo giusto per farlo:

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

Così ...............

Qual è il modo migliore per farlo? Inserirlo in beforeSave o beforeValidate sembra "il modo della torta", ma lo deconstruct mi uccide. Devo estendere AppModel e sovrascrivere deconstruct? Anche questo sembra brutto.

+0

Hai provato l'aggancio in 'beforeValidate'? – deceze

+0

@deceze si. 'Model :: save()' chiama '$ this-> set()' prima di chiamare uno dei callback 'before'. 'set' usa' deconstruct'. Il risultato è lo stesso usando 'beforeValidate' o' beforeSave' nel modello, appmodel sottoposto a override o comportamento – Farray

risposta

2

Io di solito faccio i miei campi data come campi di testo nella vista di ignorare l'uscita Helper modulo predefinito e quindi utilizzare jQuery selezione data (o qualunque sia il vostro selettore alternativa sarebbe) per impostare la data:

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

Ciò produrrebbe un tag tipico piuttosto che tutti i menu a discesa.

Poi, nella funzione BeforeSave del mio modello, a cambiare il formato a MySQL data formattata:

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

(ricordarsi di tornare vero in BeforeSave)

Questo funziona con un adeguato tipo di dati datetime nel database e suona come quello che stai cercando di fare.

+0

Conosci un buon datetepeper allora? Sarei contento di usare una combinazione jQuery datepicker/timepicker che popola 1 campo di input, ma l'unico plugin integrato che ho visto [utilizza slider] (http://trentrichardson.com/examples/timepicker/) e non lo sono terribilmente affezionato. [Lì] (http://fgelinas.com/code/timepicker/) [sono] (http://haineault.com/media/jquery/ui-timepickr/page/) [altri] (http: // code. google.com/p/jquery-timepicker/), ma sembrano affidarsi a un campo di tempo discreto, che mi riporta al mio problema originale di avere 2 campi. – Farray

+0

La soluzione più semplice è un selettore di date a 1 campo, ma se è necessario disporre di un campo a due, perché non rendere nascosto il campo data, creare un campo data e ora e fare in modo che concatenano i risultati nel campo data al termine. Tutto ciò che accadrebbe in javascript e si finisce con un singolo campo di date inviato a Cake. –