Jelenlegi hely

Drupal 7 űrlapok sminkelése

CSÉCSY László képe

Az űrlapok sminkelése alapjában nem változott a Drupal 6 óta, de van néhány dolog, amit másképp kell csinálni. Feladatunk a következő űrlap megjelenítése:
Nevem [vezetéknév] [keresztnév] és [kor] éves vagyok.
A szögletes zárójelek szövegmezőket jelentenek, melyekben először a fenti szöveg jelenik meg, rájuk klikkelve a szöveg eltűnik, s ha a szövegmező elhagyásakor üres, akkor vissza kell bele írni a szöveget. Mindehhez szükségünk lesz az űrlap sminkelésére, jQuery/JavaScript és CSS csatolására. Mivel most sminkeléssel foglalkozunk, ezért nem megyünk bele például olyan részletekbe, hogyan kell modult létrehozni, vagy hogyan kell CSS-t/jQueryt használni.

1. lépés: az űrlap URL-hez kapcsolása

Ehhez a hook_menu()-t kell megvalósítani.

function form_theme_menu() {
  $menu['form_theme'] = array(
    'title' => 'Theming Forms',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('form_theme_form'),
    'access callback' => TRUE,
  );
  return $menu;
}

2. lépés: űrlap definíciója

Három szövegmezőre lesz csak szükségünk, hozzájuk csatolva a megfelelő CSS-t és JS-t.

function form_theme_form() {
  $form['first_name'] = array(
    '#type' => 'textfield',
  );
  $form['last_name'] = array(
    '#type' => 'textfield',
  );
  $form['age'] = array(
    '#type' => 'textfield',
    '#maxlength' => 3,
  );
  $path = drupal_get_path('module', 'form_theme');
  $form['#attached'] = array(
    'css' => array('type' => 'file', 'data' => $path . '/form_theme.css'),
    'js' => array('type' => 'file', 'data' => $path . '/form_theme.js'),
  );
  return $form;
}

3. lépés: sminkfüggvény regisztrálása

Ehhez a hook_theme()-et kell megvalósítani.

function form_theme_theme() {
  return array(
    'form_theme_form' => array(
      'render element' => 'form'
    ),
  );
}

Mint látszik, a Drupal 6-ban használatos 'arguments' helyett Drupal 7-ben 'render element' van, és ez is csak egyetlen paramétert definiál. Az elnevezések viszont ugyanúgy fontosak, mint korábban: ha a 'form_theme_form' azonosítójú űrlapot szeretnénk sminkelni, akkor a hook_theme()-ben a 'form_theme_form' kulccsal kell regisztrálni, amely a theme_form_theme_form() függvény meghívásához vezet.

4. lépés: sminkfüggvény megírása

Drupal 7-ben a következő dolgokat kell figyelembe venni sminkfüggvények írásánál:

  • A függvény egyetlen, $variables nevű paramétert kap, melyben a 'form' kulcs alatt szereplő tömb az űrlap definíciója.
  • Minden űrlapelemet keresztül kell hajtani a drupal_render() függvényen, amely az űrlapdefiníciós tömbből HTML-t készít (egyéb varázslatok mellett).
  • A sminkfüggvény végén minden, korábban feldolgozatlan űrlapelemet keresztül kell hajtani a drupal_render_children() függvényen, hogy a fennmaradt és rejtett elemek a helyükre kerüljenek. (Minden Drupal űrlapnak tartalmaznia kell rejtett elemeket, melyek nélkül az egész űrlaposdi nem működne.) A Drupal 6 idején ezt is a drupal_render() segítségével csináltuk, de ez a Drupal 7-ben végtelen ciklushoz, azaz üres képernyőhöz vezet, ráadásul mindenféle hibaüzenet nélkül.

Lássuk tehát a sminkfüggvényünket.

function theme_form_theme_form($variables) {
  $form = $variables['form'];
  $output = '<h2>' . t('Please enter your information below') . '</h2>';
  $output .= '<div id="personal_details">';
  $output .= '<span>' . t('My name is') . '</span>';
  $output .= drupal_render($form['first_name']);
  $output .= drupal_render($form['last_name']);
  $output .= '<span>' . t('and I am') . '</span>';
  $output .= drupal_render($form['age']);
  $output .= '<span>' . t('years old.') . '</span>';
  $output .= '</div>';
  $output .= drupal_render_children($form);
  return $output;
}

Először elkülönítjük az űrlapdefiníciót a változók közül, hogy a továbbiakban ne kelljen annyit gépelni. A kódban sosem használunk magyar szövegeket, hanem minden szöveget angolul írunk be, és keresztülhajtunk a t() függvényen, ami a fordításért felel. A és elemek később a CSS elkészítésében segítenek majd.

Az űrlap sminkelésével ezennel készen is vagyunk, de a bevezetőben leírt feladatot még nem teljesítettük: az űrlapunk se nem néz ki, se nem működik úgy, ahogy azt elvárjuk. Ehhez még CSS és JS mágiára van szükség.

5. lépés: CSS és JS fájlok létrehozása

A 2. lépésben csatoltuk az űrlaphoz a CSS és JS fájlokat – de még nem hoztuk létre őket. Íme a theme_form.css:

#personal_details span, #personal_details div {
  float:left;
}
#personal_details .form-item-first-name, #personal_details .form-item-last-name {
  width:115px;
}
#edit-first-name, #edit-last-name {
  width:100px;
}
#personal_details .form-item-age {
  width:50px;
}
#edit-age {
  width:35px;
}
#personal_details span {
  margin-right:5px;
  padding-top:5px;
}

Elég egyértelmű, ugye? Lássuk a theme_form.js tartalmát is:

(function($) {
  Drupal.behaviors.formTheme = {
    attach: function() {
      var defaults = [];
      defaults["#edit-first-name"] = Drupal.t("First Name");
      defaults["#edit-last-name"] = Drupal.t("Last Name");
      defaults["#edit-age"] = Drupal.t("Age");
      var element;
      for (element in defaults) {
        if (defaults.hasOwnProperty(element)) {
          $(element).val(defaults[element]).css("color", "grey").focus(function() {
            var key = "#" + $(this).attr("id");
            if ($(this).val() === defaults[key]) {
              $(this).css("color", "black").val("");
            }
          }).blur(function() {
            if ($(this).val() == "") {
              var key = "#" + $(this).attr("id");
              $(this).css("color", "grey").val(defaults[key]);
            }
          });
        }
      }
    }
  };
}(jQuery));

A teljes kódot egy névtelen függvénybe zárjuk, hogy elkerülhessük a jQueryn kívüli JavaScript könyvtárakkal való névtér-ütközéseket. A Drupal 7-ben így kell eljárni, bár valójában ez a technika már a Drupal 6-ban is működik.
A Drupal 6-ban a Drupal.behaviors minden eleme egy-egy függvény volt, melyek a dokumentum elkészülésekor futottak le. A Drupal 7-ben a Drupal.behaviors minden eleme egy-egy objektum, melynek attach eleme az a függvény, melynek a dokumentum elkészülésekor kell lefutnia.
A lényegi részben először létrehozunk egy üres tömböt, majd minden űrlapelem számára feltöltjük az alapértelmezett szöveggel. Ezek a szövegek szintén nem magyarul íródnak a kódba, hanem az angol változatukból a Drupal.t() állítja elő a magyar szöveget – ez a fentebb már említett t() függvény (drupalos) JavaScript megfelelője.
A ciklusban végigmegyünk a feldolgozandó űrlapelemeken. Minden űrlapelem lényegi feldolgozó kódját egy if ()-be zárjuk, mivel a tömbben levő minden elemnek lesz egy prototípus eleme is. Ha ez nem érthető, nem baj: másoljuk csak le, jobban fognak tőle futni a for (A in B) típusú ciklusaink.
Először is létrehozunk az űrlapelemben egy helyőrzőt, másodszor a helyőrző szövegszínét CSS segítségével szürkére állítjuk, harmadszor az onfocus és onblur eseményekhez hozzákapcsoljuk a megfelelő (névtelen) függvényünket.
Az onfocus eseménykor meghívandó függvényünk ellenőrzi, hogy az alapértelmezett helyőrző szöveg megegyezik-e az űrlapelemben levő szöveggel; ha igen, kitörli, és a szövegszínt feketére állítja – így a beírt szöveg fekete lesz, míg az alapértelmezés szürke marad.
Az onblur eseménykor meghívandó függvényünk ugyanezt csinálja pepitában: ellenőrzi, hogy az űrlapelem üres-e; ha igen, beleírja az alapértelmezett helyőrző szöveget, majd a színét szürkére állítja.

…és már végeztünk is. Van egy űrlapunk, amit a sminkfüggvény segítségével a szájunk íze szerint jelenítettünk meg, hozzácsatolva a megfelelő CSS és JS varázslatokat is.

Fenti írás Jay cikkének laza fordítása.

Technológia: