- Magyar
- English
Alapszintű AHAH Drupal 6 alatt
Feladat: egy űrlapon adott egy szövegmező (például partner neve), valamint egy legördülő (például a hozzá tartozó szerződések). Az oldal újratöltése és többoldalas űrlap használata nélkül a szövegmező (partnernév) kitöltése után töltsük fel a legördülőt (szerződéseket) a szövegmező tartalma alapján.
Megvalósítás: szükségünk van két menüelemre, melyek egyrészt az űrlapot, másrészt az AHAH kérést kezelik.
function ahahdemo_menu() {
$items['ahahdemo'] = array(
'title' => 'AHAH Demo form',
'access arguments' => array('access content'),
'page callback' => 'drupal_get_form',
'page arguments' => array('ahahdemo_ahahdemo_form'),
);
$items['ahahdemo/js'] = array(
'access arguments' => array('access content'),
'page callback' => 'ahahdemo_ahahdemo_js',
'type' => MENU_CALLBACK,
);
return $items;
}
Az űrlapot a szokásos módon állítjuk elő: oldalt fogunk generáltatni, ahol a drupal_get_form() függvénynek adjuk át paraméterül azon saját függvényünk nevét, mely az űrlap adataival tér vissza.
Az AHAH kérés kezelésekor szintén "oldalt" állítunk elő, azonban ezt egyrészt nem jelenítjük meg a menüben (csak zavaró lenne), másrészt a teljes "oldalt" a saját függvényünk állítja elő.
Szükségünk lesz tehát az (üres) űrlap adatait összeállító függvényre is.
function ahahdemo_ahahdemo_form($form_state) {
$form = array();
$form['textfield1'] = array(
'#type' => 'textfield',
'#title' => t('Text field 1'),
'#ahah' => array(
'path' => 'ahahdemo/js',
'wrapper' => 'edit-dropdown1-wrapper',
'progress' => array(
'type' => 'none',
),
),
);
$form['dropdown1'] = array(
'#type' => 'select',
'#title' => t('Drop down 1'),
'#options' => array(t('< Empty >')),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
return $form;
}
A trükk a szövegmező #ahah elemében van, méghozzá többszörösen. A path elem mutatja meg, hogy a kliensoldali jQuery milyen elérési útra küldje el az űrlapot a háttérben (innen az AHAH első és utolsó betűje: Asynchronous és HTTP). A wrapper elem mutatja meg a megjelenített űrlap azon elemének azonosítóját (HTML id-jét), melynek tartalmát a visszakapott HTML-re kell cserélni (innen az AHAH középső két betűje: HTML és And). Ha textfield típusú űrlapelemhez rendeljük az #ahah elemet, akkor a kérés a szövegmező elhagyásakor fut le - ami nekünk pontosan megfelel.
A progress elem none értéke egy dokumentálatlan lehetőség: itt elvileg a throbber és a progress közül lehetne választani - előbbi hatására körbeforgó, utóbbiéra bitkolbász animgifet jelenítene meg a jQuery arra az időre, míg az AHAH kérés lefut. Mivel a none értéket nem ismeri a misc/ahah.js, ezért nem fog megjeleníteni semmit - így még kevésbé fogja kedvenc megrendelőnket zavarni a villódzás.
Egyetlen lépés van már csak hátra: az AHAH/jQuery kéréskor lefuttatandó PHP függvény.
function ahahdemo_ahahdemo_js() {
// Új elem felépítése.
$new_element = array(
'dropdown1' => array(
'#type' => 'select',
'#title' => t('Drop down 1'),
),
);
switch ($_POST['textfield1']) {
case 3:
$new_element['dropdown1']['#options'][3] = t('Three');
case 2:
$new_element['dropdown1']['#options'][2] = t('Two');
case 1:
$new_element['dropdown1']['#options'][1] = t('One');
default:
$new_element['dropdown1']['#options'][0] = t('< Empty >');
}
// Űrlap felépítése.
$form_state = array('submitted' => FALSE);
$form_build_id = $_POST['form_build_id'];
// Az új elem írja felül a régit - ha nem teszi, a Drupal Form API nem fog
// tudni róla, így nem fogja elfogadni az új választási lehetőségeket -
// illetve egész pontosan kitöltetlen lesz a
// $form_state['values']['dropdown1'].
if (!$form = form_get_cache($form_build_id, $form_state)) {
exit();
}
$form['dropdown1'] = $new_element;
form_set_cache($form_build_id, $form, $form_state);
$form += array(
'#post' => $_POST,
'#programmed' => FALSE,
);
// Űrlap újraépítése.
$form = form_builder('ahahdemo_ahahdemo_form', $form, $form_state);
// Új űrlapelem kibontása.
$new_form = $form['dropdown1'];
unset($new_form['#prefix'], $new_form['#suffix']); // Dupla csomagolás megakadályozása.
$new_form['#attributes']['class'] = empty($new_form[$delta]['#attributes']['class']) ?
'ahah-new-content' :
$new_form[$delta]['#attributes']['class'] .' ahah-new-content';
// Az esetleges üzenetek kerüljenek az új elem fölé.
$output = theme('status_messages') . drupal_render($new_form);
drupal_json(array('status' => TRUE, 'data' => $output));
}
A dolog lényege a következő: a Drupal Form API-ja nem enged olyan értéket beküldeni (legalábbis jelen példánál maradva a legördülőben nem), amely az űrlap összeállításakor nem szerepelt a lehetséges értékek között - márpedig az űrlap generálásakor nem tudhatjuk, hogy egy később bekérendő partnerhez melyik szerződés(ek) tartoz(nak) -, ezért a generált űrlapot nem csak megjeleníti, hanem gyorsítótárban (adatbázistáblában) tárolja is a Drupal. Ennek megfelelően nem elég generáltatni egy új legördülőt, mely a megfelelő értékeket tartalmazza, hanem azt a Drupal Form API tudomására is kell hozni, azaz elő kell bányászni a gyorsítótárból az űrlapot, a megfelelő részét felülírni, újraépíttetni az űrlapot (ezáltal felülírva a gyorsítótárban tárolt változatot), majd a megfelelő részét visszaküldeni a böngészőnek - s nem XML-ként (mint AJAX esetén), hanem HTML-ként, hogy kliensoldalon ne kelljen a kelleténél többet foglalkozni a feldolgozással.
A csatolt példa megvalósításban a szövegmező értéke 1, 2 vagy 3 lehet ahhoz, hogy a legördülőben változzon is az alapértelmezés.
(A bejegyzés megírásában ez a cikk volt segítségemre.)
| Csatolmány | Méret |
|---|---|
| 1.31 KB |

Hozzászólások
A cikkért ezer hála! Az oldal
A cikkért ezer hála!
Az oldal meg talán a legszebb magyar drupal oldal, amit láttam.