domenica 24 febbraio 2008

Joomla 1.5: campo data con controllo calendario

Una risposta veloce ad un quesito ricevuto da un lettore (qualcuno usa il modulo per le domande / suggerimenti e, quando sono in grado, mi fa piacere rispondere).

Sembra proprio che la creazione di componenti per Joomla 1.5 sia un argomento 'caldo', la domanda in questo caso è come utilizzare il controllo standard calendario per gestire un campo data in un proprio componente.

Visto che si è già creato un componente per la gestione di un modulo di immissione dati, mi sembra inutile crere un altro esempio solo per questo problema.

Il punto di partenza sarà quindi l'ultima versione del componente MyForm (myform5.zip, scaricabile dal sito). Ecco la procedura passo passo per aggiungere al modulo un campo data (data di nascita) e consentire l'input all'utente tramite il calendario standard di Joomla (per intendersi quello con cui si imposta, ad esempio, la data di pubblicazione degli articoli).

Per brevità eviterò di riportare tutti i file per intero. Nel codice la parte da inserire o modificare è in blu, mentre sono in nero le parti preesistenti giusto per capire il punto esatto dove è stata fatta la modifica.

Inserimento del campo nel database

Il nuovo campo data deve essere inserito nel database, quindi bisogna modificare lo script sql di installazione.

File: install.sql
[...]/administrator/components/com_myform/

CREATE TABLE `#__myform` (
  ...
  `note` text NULL,
  `data_nasc` date NULL,
  `data` datetime NULL,
   PRIMARY KEY  (`id`)
) DEFAULT CHARSET=utf8;

Se avete una versione già installata del componente potete semplicemente aggiornare la tabella lanciando da phpmyadmin questa query

ALTER TABLE `jos_myform` ADD `data_nasc` DATE NULL;

Se avete un prefisso tabelle diverso da jos_ il nome della tabella va modificato opportunamente.

Aggiungere il campo alla classe Table

La classe Table deve essere modificata per riflettere la modifica fatta alla tabella del database

File: myform.php
[...]/administrator/components/com_myform/tables

class TableMyForm extends JTable {
  ...
  var $data_nasc = null;
  ...
  function check() {
    ...
    if (trim($this->data_nasc) == '') {
      $this->setError(JText::_('Inserire la Data di nascita.'));
      return false;
    }
    $d = explode('-', $this->data_nasc);
    if(count($d) != 3 || checkdate($d[1], $d[0], $d[2]) === false) {
      $this->setError(JText::_('Data di nascita non valida!'));
      return false;
    }
    $this->data_nasc = date('Y-m-d',mktime(0,0,0,$d[1],$d[0],$d[2]));
    return true;

  } //Fine check

Acquisiamo la data nel formato giorno-mese-anno più familiare all'utente e, se è valida, prima di uscire dalla funzione la convertiamo nel formato che si aspetta MySql (anno-mese-giorno).

Aggiungere il campo nella struttura del modulo

La struttura del modulo è definita nella classe Model. Aggiungiamo all'array fields la definizione per il nuovo campo data.

File: myform.php
[...]/components/com_myform/models/

class MyFormModelMyForm extends JModel {
var $form = array(
  'name' => 'myform',
  'id' => 'myform',
  'fields' => array (
     ...
     array('label'=>'Indirizzo','name'=>'myform[indirizzo]',
'id'=>'indirizzo', 'size'=>40),
     array('label'=>'Data Nascita', 'name'=>'myform[data_nasc]',
'id'=>'data_nasc', 'size'=>'9','type'=>'date'),
     ...
   )
);
...

Modifica funzione visualizzazione modulo

Dobbiamo gestire la visualizzazione del nuovo tipo di campo (date).

File: myform.php
[...]/administrator/components/com_myform/helpers/

...
switch($type) {
...
case 'date':
  if($fv && $ts=strtotime($fv)) {
    $fv = strftime('%d-%m-%Y', $ts);
  }
  $html .= JHTML::_('calendar', $fv, $field['name'], $field['id'], 
  '%d-%m-%Y', array('size'=>$field['size'])) .'<br />';
  break;
}
...

La classe JHTML contiene diverse funzioni per la generazione dell'html. Quella che abbiamo visto serve a creare un campo input con a fianco un'icona che attiva il calendario per l'inserimento della data. Gli argomenti sono

  • 'calendar' costante
  • data da inserire nel campo
  • attributo name del tag input per il campo data
  • attributo id del tag input per il campo data
  • formato data. Stesso formato della istruzione strftime poco sopra
  • array con attributi addizionali del tag input per il campo data

Modifica funzione visualizzazione elenco

Aggiungiamo anche una colonna all'elenco per la visualizzazione dei dati inseriti.

File: default.php
[...]/administrator/components/com_myform/views/myform/tmpl

...
$trh = '<thead><tr>
<th width="20">
    <input type="checkbox" name="toggle" value="" 
 onclick="checkAll(' . count($this->items) . ');" />
</th>
<th width="15%%">%s</th><th width="15%%">%s</th>
<th width="10%%">%s</th><th width="20%%">%s</th>
<th width="15%%">%s</th>
<th width="25%%">%s</th></tr></thead>';
$tr = '<tr>' . str_repeat('<td>%s</td>', 7) . '</tr>';
...
$html .= '<tfoot><tr><td colspan="7">' 
. $this->pagination->getListFooter()
. '</td></tr></tfoot>';
$html .= sprintf($trh,JText::_('Nome'),JText::_('Cognome'), 
JText::_('Telefono'),JText::_('Indirizzo'),JText::_('Data Nascita'), 
JText::_('Note'));
$i = 0;
foreach($this->items as $item) {
  $checked = JHTML::_('grid.id', $i, $item->id); 
  $dn = '';
  if($item->data_nasc) {
    $dn = strftime('%d %B %Y', strtotime($item->data_nasc));
  }
  $html .= sprintf($tr, $checked, $item->nome, $item->cognome, 
  $item->telefono, $item->indirizzo, $dn, $item->note);
  $i++;
}
...
Un'ultima cosa: l'icona del calendario viene visualizzata con un bordo che a me personalmente non piace granché. Se siete della stessa opinione e volete toglierlo il file da modificare è [...]/media/system/css/calendar-jos.css

eliminate la riga 10

 border: 1px solid #cccccc;
Abbiamo finito. Il campo data di nascita sarà visibile nel frontend e nel backend del componente.

4 commenti:

Manuel ha detto...

Ciau complimenti per la guida.

Ghiardo ha detto...

Sono Marco, l'autore della domanda. Il "campo data con controllo calendario" funziona perfettamente. Ti ringrazio per i tuoi suggerimenti, mi saranno sicuramente utili.
Ciao

Anonimo ha detto...

Ciao: qual'è la strada migliore per inserire il semplice calendario mensile in un modulo Jommla ?
Sono OT ?
TIA

Massimo ha detto...

A "memoria" non vedo controindicazioni a seguire per un modulo la stessa procedura che nell'articolo mostra come inserire il calendario in un componente.

Posta un commento

Nota. Solo i membri di questo blog possono postare un commento.