Přeskočit přímo na text


Jak na našeptavač (autocomplete) s více parametry

Stalo se vám někdy, že jste potřebovali předávat funkci, která generuje „nápovědu“ pro textové políčko s automatickým doplňováním více parametrů? Mě se to přihodilo zrovna dneska …

DISCLAIMER: Jen pro Drupal geeky!

Vytvořil jsem u příslušného elementu ve formuláři parametr #autocomplete_path, jak se praví v dokumentaci k Drupal Forms API (FAPI). Vytvořil routu v hook_menu pro autocomplete callback. Vytvořil jsem dokonce už samotnou funkci na napovídání… a teprve při psaní hlavičky funkce mi to došlo. Jak sakryš přidat další parametr kromě části vyhledávaného řetězce? Potřeboval jsem totiž předat ještě jeden parametr z formuláře, který ovlivňuje vyhledávání. A to bohužel Drupal nepodporuje.

Bez trocha Javascriptu to nepůjde, to mi už bylo jasné, bude nutné vytvořit handler, který při změně podmínek formuláře dynamicky změní URL autocomplete elementu.

Podíval jsem se přes Firebug na DOM jestli nevykoukám, kde můžu URL změnit… Nic jsem rychle neobjevil – přišel čas na strejdu Googla. Po chvíli googlení jsem se dostal na toto vlákno na Stackoverflow: How to dynamically reconfigure Drupal’s jQuery-based autocomplete at runtime?. Zde je celkem pěkně popsána inicializace autocomplete. Zaujal mě zde však celkem nenápadný komentář od Johna Fialy: „Note that this is pretty much what the location module does – have a look at location_auto­complete.js for the juicy details. – John Fiala Dec 9 at 22:43“.

Modul Location obsahuje dvě provázaná pole země (selectbox ) a provincie (textové pole s našeptávačem). Když se změní země, vymaže se obsah pole provincie a našeptávač by měl (logicky) začít nabízet provincie z aktuálně nastavené země.

Stáhnul jsem tedy modul Location a jal se studovat, jak to tedy dělá… No a po 30 min bylo hotovo :-) Níže je výpis stěžejních pasáží kódu.

Výpis location.module řádek 634–671:

<?php case ‚province‘:
drupal_add_js(dru­pal_get_path(‚mo­dule‘, ‚location‘) .‚/location_au­tocomplete.js‘);
$country = $a5[‚country‘] ? $a5[‚country‘] : variable_get(‚lo­cation_default_cou­ntry‘, ‚us‘);
return array(
‚#type‘ ⇒ ‚textfield‘,
‚#title‘ ⇒ t(‚State/Provin­ce‘),
‚#autocomplete_pat­h‘ ⇒ ‚location/auto­complete/‘. $country,
‚#default_value‘ ⇒ $obj,
‚#size‘ ⇒ 64,
‚#maxlength‘ ⇒ 64,
‚#description‘ ⇒ NULL,
// Used by province autocompletion js.
‚#attributes‘ ⇒ array(‚class‘ ⇒ ‚location_auto_pro­vince‘),
‚#required‘ ⇒ ($a4 == 2),
);

case ‚country‘:
// … vypuštěno
return array(
‚#type‘ ⇒ ‚select‘,
‚#title‘ ⇒ t(‚Country‘),
‚#default_value‘ ⇒ $obj,
‚#options‘ ⇒ $options,
‚#description‘ ⇒ NULL,
‚#required‘ ⇒ ($a4 == 2),
// Used by province autocompletion js.
‚#attributes‘ ⇒ array(‚class‘ ⇒ ‚location_auto_cou­ntry‘),
);
}
break; ?>

Výsek kódu je z funkce která parametrizovaně generuje formulářová políčka lokace. Zde je dobré všimnout si přidání souboru s javascriptem, nastavení výchozí #autocomplete_path a označení elementů třídami ‚location_auto_cou­ntry‘ a ‚location_auto_pro­vince‘.

Následuje mírně zjednodušený výpis location_auto­complete.js:

(Značek „php“ si nevšímejte, jde skutečně o javascript, ale jinak mi to nešlo vložit)

<?php Drupal.behavi­ors.location = function(context) {
$(‚select.loca­tion_auto_cou­ntry:not(.loca­tion-processed)‘, context).chan­ge(function(e) {
var obj = this;
// mírně zjednodušeno
var input = $(‚.location_au­to_province‘); // políčko s provincií
if (input && input.length) {
//Unbind events on province field and empty its value
input.unbind()­.val('');
input.each(fun­ction(i) {
//Get the (hidden) *-autocomplete input element
var input_autocomplete = $(‚#‘ + this.id + ‚-autocomplete‘);
// Update autocomplete url
input_autocom­plete.val(input_au­tocomplete.val()­.substr(0, input_autocom­plete.val().las­tIndexOf(‚/‘) + 1) + $(obj).val());
// Mark as not processed.
input_autocom­plete.removeClas­s(‚autocomple­te-processed‘);
});
// Reprocess.
Drupal.behavi­ors.autocomple­te(document);
}
}).addClass(‚lo­cation-processed‘); }; ?>

Kód pracuje ve jmenném prostoru Drupal.behaviors, což je standardní cesta, jak v Drupalu přiřazovat elementům stránky nějaké chování. Jak je vidět skriptík se spustí při kliknutí na výběr země (select.locati­on_auto_country). Poté se vyhledá políčko s provincií (location_auto_pro­vince) a uloží se do proměnné input.

Provincie je vymazána (val('')), jsou odstřiženy všechny akce (unbind). Poté je vyhledán skrytý prvek s našeptávačem, který je uložen do proměnné input_autocom­plete. Zde konečně dochází ke změně URL: na konec URL se přidává parametr získaný jako hodnota z formulářového prvku s výběrem země.

Nyní zbývá už jen našeptavač zinicializovat. Odstraní se třída autocomplete-processed, která by opětovné inicializaci zabránila a následně se připojí našeptávač k prvku znovu: Drupal.behavi­ors.autocomple­te(document), v tomto případě se jako argument předává celý HTML dokument.

A to je vše ;-)

POZNÁMKA: „Správnější“ cestou jak přiřazovat opětovně Drupal.behaviors je použít funkci Drupal.attachBe­haviors(contex­t). Tím dosáhneme připojení všech „behaviors“ k prvku/části dokumentu, který předáme jako argument. Spuštěním Drupal.behavi­ors.autocomple­te(context) dosáhneme pouze připojení „autocomplete“ (a ničeho jiného).

About the authornení
 

Nice page

You are nice page…

Poslat nový komentář

  • You can use Texy! to format and alter entered content.
  • Povolené HTML značky: <em> <strong> <b> <i> <br> <code> <ul> <ol> <li> <pre> <pre class="php">
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>. Beside the tag style "<foo>" it is also possible to use "[foo]".

Více informací o možnostech formátování

Hledat

Přihlášení

Bezpečnost Drupalu

Z hlediska bezpečnosti je Drupal na velmi vysoké úrovni, díky propracovanému systému hlášení, prověřování a řešení možných problémů.

Čtěte více a odebírejte bezpečnostní aktuality

Poslední komentáře

Kdo je online

Momentálně je online 3 uživatelé a 4 hosté.

Online uživatelé

Support

Psychologie - poradenství