Jelenlegi hely

Dátummezővel 6-ról 7-re

CSÉCSY László képe

Feladat: ÉÉÉÉ-HH-NN formátumú dátum felvitelére szolgáló szövegmező biztosítása; JS támogatás megléte esetén a szövegmező melletti gombra ugorjon fel egy naptár, amelyben 1000 és 2050 közötti tetszőleges évszám kiválasztható legyen és a hónapnevek rövidítései magyarul jelenjenek meg. Megmutatom a Drupal 6-ban alkalmazott megoldást is, hogy aztán láthatóvá váljék, miben egyszerűsödik a helyzet Drupal 7-ben.

function mymodule_form_builder() {
  // ...
  $form['mydate'] = array(
    '#title' => t('Date'),
    '#type' => 'textfield',
    '#element_validate' => array('mymodule_form_date_validate'),
    '#default_value' => $default_value,
    '#maxlength' => 10,
    '#size' => 10,
  );
  jquery_ui_add('ui.datepicker');
  jquery_ui_add('i18n/ui.datepicker-hu');
  drupal_add_js("$('#edit-mydate').datepicker({changeMonth: true, changeYear: true, yearRange: '1000:2050', showOn: 'button'}).datepicker('option', 'dateFormat', 'yy-mm-dd').datepicker($.datepicker.regional['hu']);", 'inline', 'footer');
  drupal_add_css(drupal_get_path('module', 'jquery_ui') . '/jquery.ui/themes/default/ui.datepicker.css');
  return $form;
}
 
function mymodule_form_date_validate($element, &$form_state) {
  // No need to check an empty field: that's perfectly valid.
  if (!$element['#value']) {
    return;
  }
  if (!preg_match('/^[1-9][0-9]{3}-(0[1-9]|1[12])-(0[1-9]|[12][0-9]|3[01])$/', $element['#value'])) {
    form_error($element, t('This date is invalid.'));
  }
  else {
    list($year, $month, $day) = explode('-', $element['#value']);
    if (!checkdate($month, $day, $year)) {
      form_error($element, t('This date is invalid.'));
    }
  }
}

Röviden: Drupal 6-ban a jquery_ui.module szállítja a szükséges JS mágiát, annak minden függőségével (lokalizáció, CSS) együtt. Látszik, hogy eléggé szájbarágósan mindent a tudtára kell adni. Jöjjön a Drupal 7-es változat.

function mymodule_form_builder() {
  // ...
  drupal_add_library('system', 'ui.datepicker');
  $form['mydate'] = array(
    '#title' => t('Date'),
    '#type' => 'textfield',
    '#element_validate' => array('mymodule_form_date_validate'),
    '#default_value' => $default_value,
    '#maxlength' => 10,
    '#size' => 10,
    '#attached' => array(
      'js' => array(
        drupal_get_path('module', 'mymodule') . '/ui.datepicker-hu.js' => array('type' => 'file'),
        "(function ($){\$('#edit-mydate').datepicker({changeMonth: true, changeYear: true, yearRange: '1000:2050', showOn: 'button'}).datepicker($.datepicker.regional['hu'])})(jQuery);" => array('type' => 'inline', 'scope' => 'footer'),
      ),
    ),
  );
  return $form;
}

Az ellenőrző függvény nem változott, így azt nem másoltam be újra – ezen kívül viszont majdnem minden. A jQuery.UI bekerült a Drupal 7 magba, ezért a drupal_add_library() szépen be tudja húzni a szükséges JS és CSS fájlokat a megfelelő módon. A lokalizáció viszont nem került be a magba, így azt külön hozzá kell csatolni az űrlaphoz. A jQuery beépítésének/használatának módja is megváltozott: lehetővé vált más, a $ jellel dolgozó könyvtárak használata is – cserébe minden jQuery kódunknak a szájába kell rágni, honnan s hogyan szerezze meg a jól megszokott $ objektumot. Az utolsó, a kódban kevéssé, de a használatban igen hamar szembetűnő változás, hogy a jQuery.datepickernek már nem kell megadni a dátumformát – sőt nem is szabad: ha megadjuk, az űrlap megjelenése után a szövegmező azonnal kiürül, azaz eltűnik belőle az alapértelmezés is – ami sok esetben igen zavaró lehet. Cserébe az alapértelmezett(?) dátumforma pont megfelelő is számunkra.

Technológia: 

Hozzászólások

A date_popup modulban (Date modul része, JQuery UI-ra épül ez is) van egy "date_popup" form element.

…bár egyelőre még nem nyerte el teljesen a tetszésemet:

# Notice: Undefined offset: 1 date_range_years() függvényben (/home/boobaa/drupal/d7/sites/all/modules/contrib/date/date_api/date_api.module 1849 sor).
# Warning: mb_strlen() expects parameter 1 to be string, array given drupal_strlen() függvényben (/home/boobaa/drupal/d7/includes/unicode.inc 442 sor).

Ráadásul ha csak erre van szükségem belőle, akkor egy kicsit overkillnek tűnik. Meglátjuk, lesz-e a foltozáshoz energia.