1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355
|
<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 24249 -->
<!-- Reviewed: no -->
<sect3 id="zend.controller.actionhelpers.autocomplete">
<title>AutoComplete</title>
<para>
Viele <acronym>AJAX</acronym> Javascript Bibliotheken bieten Funktionalitäten an für eine
automatische Vervollständigung wobei eine Auswahlliste von potentiell passenden Ergebnissen
angezeigt wird während der Benutzer tippt. Der <emphasis>AutoComplete</emphasis> Helfer
zielt darauf ab einfach akzeptierbare Ergebnisse zu solchen Methoden zurückzugeben.
</para>
<para>
Da nicht alle JS Bibliotheken automatische Vervollständigung auf die gleiche Art
implementieren bietet der <emphasis>AutoComplete</emphasis> Helfer einige grundsätzliche
abstrakte Funktionalitäten zu vielen Bibliotheken und konkrete Implementierungen für
individuelle Bibliotheken. Zurückgegebene Typen sind generell entweder
<acronym>JSON</acronym> Arrays von Strings, <acronym>JSON</acronym> Arrays von Arrays (mit
jedem Mitgliedsarray das ein assoziatives Array von Metadaten ist, das verwendet wird um
die Auswahlliste zu erstellen), oder <acronym>HTML</acronym>.
</para>
<para>
Die grundsätzliche Verwendung ist für jede Implementierung die selbe:
</para>
<programlisting language="php"><![CDATA[
class FooController extends Zend_Controller_Action
{
public function barAction()
{
// etwas Logik durchführen...
// Verschlüsseln und Antwort senden;
$this->_helper->autoCompleteDojo($data);
// oder explizit:
$response = $this->_helper->autoCompleteDojo
->sendAutoCompletion($data);
// oder einfach die Antwort der automatischen
// Vervollständigung vorbereiten;
$response = $this->_helper->autoCompleteDojo
->prepareAutoCompletion($data);
}
}
]]></programlisting>
<para>
Standardmäßig mach die automatische Vervollständigung folgendes:
</para>
<itemizedlist>
<listitem><para>Layouts und ViewRenderer ausschalten.</para></listitem>
<listitem><para>Die richtigen Antwort Header zu setzen.</para></listitem>
<listitem>
<para>
Antwort Body mit verschlüsselten oder formatierten automatisch vervollständigten
Daten setzen.
</para>
</listitem>
<listitem><para>Antwort senden.</para></listitem>
</itemizedlist>
<para>
Mögliche Methoden des Helfers beinhalten:
</para>
<itemizedlist>
<listitem>
<para>
<methodname>disableLayouts()</methodname> kann verwendet werden um Layouts und den
ViewRenderer auszuschalten. Typischerweise wird das innerhalb von
<methodname>prepareAutoCompletion()</methodname> aufgerufen.
</para>
</listitem>
<listitem>
<para>
<methodname>encodeJson($data, $keepLayouts = false)</methodname> verschlüsselt
Daten zu <acronym>JSON</acronym>, und aktiviert oder deaktiviert Layouts optional.
Typischerweise wird das innerhalb von
<methodname>prepareAutoCompletion()</methodname> aufgerufen.
</para>
</listitem>
<listitem>
<para>
<methodname>prepareAutoCompletion($data, $keepLayouts = false)</methodname> wird
verwendet um Daten im Antwortformat vorzubereiten wenn das für die konkrete
Implementation notwendig ist, wobei Layouts optional aktiviert oder deaktiviert
werden können. Der Rückgabewert variiert basierend auf der Implementierung.
</para>
</listitem>
<listitem>
<para>
<methodname>sendAutoCompletion($data, $keepLayouts = false)</methodname> wird
verwendet um Daten im Antwortformat zu senden was für die konkrete Implementierung
notendig ist. Sie ruft <methodname>prepareAutoCompletion()</methodname> und sendet
dann die Antwort.
</para>
</listitem>
<listitem>
<para>
<methodname>direct($data, $sendNow = true, $keepLayouts = false)</methodname> wird
verwendet wenn der Helfer als Methode des Helfer Brokers aufgerufen wird. Das
<varname>$sendNow</varname> Flag wird verwendet um festzustellen ob
<methodname>sendAutoCompletion()</methodname> oder
<methodname>prepareAutoCompletion()</methodname> aufgerufen werden muß.
</para>
</listitem>
</itemizedlist>
<para>
Aktuell unterstützt <emphasis>AutoComplete</emphasis> die folgenden Dojo und Scriptaculous
<acronym>AJAX</acronym> Bibliotheken.
</para>
<sect4 id="zend.controller.actionhelpers.autocomplete.dojo">
<title>AutoCompletion mit Dojo</title>
<para>
Dojo hat per se keinen AutoCompletion Wizard, hat aber zwei Wizards die AutoCompletion
ausführen können: ComboBox und FilteringSelect. In beiden Fällen benötigen Sie einen
Datenspeicher der QueryReadStore implementiert; für mehr Informationen über dieses
Thema siehe die <ulink
url="http://dojotoolkit.org/reference-guide/dojo/data.html">dojo.data</ulink>
Dokumentation.
</para>
<para>
Im Zend Framework kann ein einfaches indiziertes Array an den AutoCompletionDojo Helfer
übergeben werden, und er wird eine <acronym>JSON</acronym> Antwort zurückgeben die
passend für die Verwendung in so einem Speicher ist:
</para>
<programlisting language="php"><![CDATA[
// In der Controller Aktion:
$this->_helper->autoCompleteDojo($data);
]]></programlisting>
<example id="zend.controller.actionhelpers.autocomplete.dojo.example1">
<title>AutoCompletion mit Dojo und der Verwendung von Zend MVC</title>
<para>
AutoCompletion mit Dojo, über Zend <acronym>MVC</acronym>, benötigt verschiedene
Dinge: Erstellung eines Form Objekts für die Kombobox bei der man AutoCompletion
will, eine Controller Action für das anbieten der AutoCompletion Ergebnisse,
Erstellung eines eigenen QueryReadSote um die AutoCompletion Aktion damit zu
verbinden, und Erstellung des Javascripts das zur Initialisierung der
AutoCompletion auf der Serverseite zu verwenden ist.
</para>
<para>
Schauen wir uns zuerst das benötigte Javascript an. Dojo bietet ein komplettes
Framework für die Erstellung von <acronym>OOP</acronym> Javascript, so wie Zend
Framework für <acronym>PHP</acronym>. Teile davon sind die Möglichkeit
Pseudo-Namespaces zu erstellen indem die Verzeichnis Hirarchie verwendet wird. Wir
erstellen ein 'custom' Verzeichnis auf dem gleichen Level wie das Dojo Verzeichnis
das Teil der Distribution von Dojo ist. In diesem Verzeichnis, erstellen wir eine
Javascript Datei, <filename>TestNameReadStore.js</filename>, mit den folgenden
Inhalten:
</para>
<programlisting language="javascript"><![CDATA[
dojo.provide("custom.TestNameReadStore");
dojo.declare("custom.TestNameReadStore", dojox.data.QueryReadStore, {
fetch:function (request) {
request.serverQuery = { test:request.query.name };
return this.inherited("fetch", arguments);
}
});
]]></programlisting>
<para>
Diese Klasse ist einfach eine Erweiterung von Dojo's eigenem QueryReadStore,
welche selbst eine Abstrakte Klasse ist. Wir definieren einfach eine Methode mit
der angefragt werden soll, und verknüpfen Sie mit dem 'test' Element.
</para>
<para>
Als nächstes, erstellen wir das Form Element für das wir AutoCompletion wollen:
</para>
<programlisting language="php"><![CDATA[
class TestController extends Zend_Controller_Action
{
protected $_form;
public function getForm()
{
if (null === $this->_form) {
$this->_form = new Zend_Form();
$this->_form->setMethod('get')
->setAction(
$this->getRequest()->getBaseUrl() . '/test/process'
)
->addElements(array(
'test' => array('type' => 'text', 'options' => array(
'filters' => array('StringTrim'),
'dojoType' => array('dijit.form.ComboBox'),
'store' => 'testStore',
'autoComplete' => 'false',
'hasDownArrow' => 'true',
'label' => 'Your input:',
)),
'go' => array('type' => 'submit',
'options' => array('label' => 'Go!'))
));
}
return $this->_form;
}
}
]]></programlisting>
<para>
Hier erstellen wir einfach eine Form mit den 'test' und 'go' Methoden. Die 'test'
Methode fügt verschiedene spezielle, Dojo-spezifische Attribute hinzu: dojoType,
store, autoComplete, und hasDownArrow. Der dojoType wird verwendet um anzuzeigen
das wir eine ComboBox erstellen, und wir Sie zum Datenspeicher von 'testStore'
verbinden wollen (Schlüssel 'store') -- mehr dazu später. Die Spezifizierung von
'autoComplete' mit <constant>FALSE</constant> sagt Dojo das der erste passende
Eintrag nicht automatisch ausgewählt wird, aber stattdessen eine Liste von
Entsprechnungen angezeigt wird. Letztendlich, erstellt 'hasDownArrow' einen
Abwärtspfeil ähnlich einer Selectbox sodas Wir die Entsprechnungen zeigen und
verstecken können.
</para>
<para>
Fügen wir eine Methode hinzu um die Form anzuzeigen, sowie einen Endpunkt für die
Bearbeitung der AutoCompletion:
</para>
<programlisting language="php"><![CDATA[
class TestController extends Zend_Controller_Action
{
// ...
/**
* Startseite
*/
public function indexAction()
{
$this->view->form = $this->getForm();
}
public function autocompleteAction()
{
if ('ajax' != $this->_getParam('format', false)) {
return $this->_helper->redirector('index');
}
if ($this->getRequest()->isPost()) {
return $this->_helper->redirector('index');
}
$match = trim($this->getRequest()->getQuery('test', ''));
$matches = array();
foreach ($this->getData() as $datum) {
if (0 === strpos($datum, $match)) {
$matches[] = $datum;
}
}
$this->_helper->autoCompleteDojo($matches);
}
}
]]></programlisting>
<para>
in unserer <methodname>autocompleteAction()</methodname> machen wir eine Anzahl von
Dingen. Zuerst schauen wir darauf eine Post Anfrage durchzuführen, und das dort ein
'format' Parameter auf den Wert 'ajax' gesetzt ist; das hilft einfach störende
Anfragen zur Aktion zu reduzieren. Als nächstes prüfen wir auf den 'test'
Parameter, und vergleichen Ihn mit unseren Daten. (wir haben absichtlich die
Implementation von <methodname>getData()</methodname> hier ausgelassen -- es können
einfach jede Art von Datenquelle sein.) Letztendlich senden wir unsere
Entsprechungen zum AutoCompletion Helfer.
</para>
<para>
Jetzt da wir alle Teile des Backends haben, sehen wir uns an was wir benötigen um
es in unserem View Skript für die Startseite auszugeben. Zuerst müssen wir unseren
Datenspeicher einstellen, dann unsere Form darstellen, und letztendlich
sicherstellen das die richtigen Dojo Bibliotheken -- inklusive unserer eigenen
Datenspeicher -- geladen werden. Schauen wir uns das View Skript an, das die
Schritte kommentiert:
</para>
<programlisting language="php"><![CDATA[
<?php // Den Datenspeicher einstellen: ?>
<div dojoType="custom.TestNameReadStore" jsId="testStore"
url="<?php echo $this->baseUrl() ?>/unit-test/autocomplete/format/ajax"
requestMethod="get"></div>
<?php // Die Form darstellen: ?>
<?php echo $this->form ?>
<?php // Das Dojo-betreffende CSS einstellen das im
// HTML Head geladen werden soll: ?>
<?php $this->headStyle()->captureStart() ?>
@import "<?php echo $this->baseUrl()
?>/javascript/dijit/themes/tundra/tundra.css";
@import "<?php echo $this->baseUrl() ?>/javascript/dojo/resources/dojo.css";
<?php $this->headStyle()->captureEnd() ?>
<?php // Javascript einstellen das im HTML Head geladen werden soll,
// inklusive aller benötigten Dojo Bibliotheken: ?>
<?php $this->headScript()
->setAllowArbitraryAttributes(true)
->appendFile($this->baseUrl() . '/javascript/dojo/dojo.js',
'text/javascript',
array('djConfig' => 'parseOnLoad: true'))
->captureStart() ?>
djConfig.usePlainJson=true;
dojo.registerModulePath("custom","../custom");
dojo.require("dojo.parser");
dojo.require("dojox.data.QueryReadStore");
dojo.require("dijit.form.ComboBox");
dojo.require("custom.TestNameReadStore");
<?php $this->headScript()->captureEnd() ?>
]]></programlisting>
<para>
Beachte die Aufrufe zu den View Helfern wie headStyle und headScript; das sind
Platzhalter, welche dann in der <acronym>HTML</acronym> Head Sektion des Layout
View Skripts dargestellt werden können.
</para>
<para>
Wir haben jetzt alle Teil um mit Dojo AutoCompletion zu arbeiten.
</para>
</example>
</sect4>
<sect4 id="zend.controller.actionhelpers.autocomplete.scriptaculous">
<title>AutoCompletion mit Scriptaculous</title>
<para>
<ulink
url="http://wiki.script.aculo.us/scriptaculous/show/Ajax.Autocompleter">Scriptaculous</ulink>
erwartet eine <acronym>HTML</acronym> Antwort in einem speziellen Format.
</para>
<para>
Der Helfer der mit dieser Bibliothek zu verwenden ist 'AutoCompleteScriptaculous'.
Es muß einfach ein Array von Daten angegeben werden, und der Helfer wird eine
<acronym>HTML</acronym> Antwort erstellen die mit Ajax.Autocompleter kompatibel ist.
</para>
</sect4>
</sect3>
|