1 Hoofdstuk 4 Formulieren en waarden posten naar een view Waarden posten naar een view in een Zend-project gaat heel anders dan dat je gewend bent. Om...
Waarden posten naar een view in een Zend-project gaat heel anders dan dat je gewend bent. Om dit mechanisme te leren, kunnen we het beste een eenvoudige oefening doen met een controller en de bijbehorende view. Leeropdracht 4.1 a. Maak met zf een action addAction() in de controller ProductenController. b. Maak in addAction() een array met daarin productgegevens. In figuur 1 zie je de code.
Figuur 1 Het is de bedoeling dat deze array met inhoud naar het view van de action addAction() wordt verzonden. Om dit te doen heeft de controller ProductController een attribuut view . Dit attribuut overerft de controller van de klasse Zend_Controller_Action. De klasse Zend_Controller_Action is een klasse in het ZF. Het attribuut view kan data van een action in een controller naar het bijbehorende view sturen. In figuur 2 zie je hoe dit in zijn werk gaat.
Figuur 2 Verklaring van de coderegel $this->view->productData=$product; . $this view productData $product
De controller zelf (ProductenController) Het object view dat de controllerklasse overerft van de klasse Zend_Controller_Action . Een object dat naar de view wordt verzonden. Het object is in dit geval een array. De array $productData kan dan in de view add.phtml worden gebruikt De array met waarden.
1
c. Maak de controller af zoals je in figuur 2 ziet. d. Open de view add.phtml in je editor. e. Verander de code in deze view zoals je in figuur 3 ziet.
Figuur 3
De view ($this) heeft nu een attribuut $productData, waarin de array uit addAction() van de controller ProductenController staat. Deze array wordt in een variabele $data gezet. Met echo worden nu de data in de array op het scherm geplaatst.
Dit mechanisme van data versturen vanuit een action in een controller naar een view kunnen we natuurlijk ook toepassen door gebruik te maken van een formulier met textboxen en een knop. In deze lesbrief wordt op vier manieren getoond hoe je een form kunt samenstellen.
2
Manier 1: een form maken in het .phtml bestand. Dit is verreweg de eenvoudigste manier om een form te maken, maar ook de minst professionele, onoverzichtelijke en onveilige manier. Het is wel de manier die de meesten kennen. Je bouwt een form in het .phtml bestand zoals je bent gewend in een gewoon .html bestand. In figuur 4 zie je een voorbeeld hiervan.
Figuur 4 Het is een eenvoudig form met drie teksboxen, een knop en voor de tekstboxen een tekst. Als je dit form in een browser toont, dan krijg je figuur 5.
3
f.
Verwijder of comment de code in de body van de action addAction() in de controller ProductenController. g. Verwijder of comment de code uit de view add.phtml en vervang deze door de code in figuur 4. Let op: neem deze code letterlijk over! h. Run de applicatie met de controller producten en de action add. Als het goed is dan moet je het formulier van figuur 5 te zien krijgen.
Figuur 5 In de view add.phtml zie je de volgende regel: $form->setMethod('post'); Hiermee geef je aan dat het attribuut method van het form de waarde post heeft. $form->setAction('saveadd'); Hiermee geef je aan dat, nadat je op de (submit) knop drukt, het programma verdergaat in de action saveaddAction(). Deze action moet nog worden gemaakt. $form->addElement('text','username') Hier wordt een textbox op het form gepaatst waarvan het attributen name en id de waarde 'id' heeft. Deze regel is dus vergelijkbaar met de volgende tag in een .html-bestand:
7
$username=$this->getElement(username); In deze regel sla je de zojuist gemaakte tekstbox even op in een variabele $username. Dit doe je om dit element verder te bewerken in de volgende regel.
$username->setLabel('Vul hier het username in'); De tekstbox wordt verder bewerkt. Met de methode setLabel() voeg je een stukje begeleidende tekst aan de tekstbox toe. ` $username->setAttrib('class', 'addelement'); Het attribuut class van de textbox krijgt de waarde 'addelement' . Hier wordt dus de HTML code van de textbox als volgt:
$this->view->addForm=$form; Je zet het zojuist opgebouwde form nu in de view die behoort bij de action addAction(). In deze view moet je dan het form weergeven door de variabele addForm te echoën.
Figuur 10
8
d. Wijzig de view add.phtml zodat je het in de action addAction() opgebouwde form kunt weergeven (echo het object addForm in de view). In figuur 11 zie je het resultaat als je de controller ProductenController en de action addAction() aanroept.
Figuur 11 Je kunt nu wat in de tekstboxen van het formulier iets invullen en de ingevulde waarden posten. In de code heb je aangegeven dat de post naar de action saveadd gaat met: $form->setAction('saveadd'); Dit betekent dat na een druk op de knop, het progamma verdergaat met de action saveaddAction() . Deze action moet nog worden gemaakt. e. Maak met behulp van zf een action saveaddAction() in de controller UserController. f.
Voorzie de view saveadd.phtml van code, zodat de ingevoerde waarden in het form in die view te zien zijn. Test de applicatie.
Zoals je ziet in figuur 11 is de opmaak van het formulier niet echt fraai. Voorlopig houden we dit even zo. In leeropdracht 4.3 leer je hoe je het form eruit laat zien als in figuur 9.
9
Manier 3: een form maken in aparte methode in de controller. In figuur 10 zie je dat de hele code voor het opstellen van het form in de action addAction() staat. Deze manier verdient niet bepaald de schoonheidsprijs. Het is de bedoeling van een action dat daar zoveel mogelijk de code belandt die te maken heeft met het aanspreken van views en models. Het opbouwen van een form behoort daar niet bij. Daarom bouwen we het form op in een aparte methode die we getAddForm() noemen. Let op: deze methode is geen action met een daaraan gekoppelde view. Deze methode maak je dus niet aan met zf. g. Maak een methode getAddForm() in de controller UserController . Plaats deze methode boven de action addAction(). h. Knip en plak de code voor het maken van het formulier (regel 18 tm 39 in figuur 10) in de body van de methode getAddForm() . De methode getAddForm() moet het form geven als het wordt aangeroepen. Aan het eind van de code binnen getAddForm() moet dus nog een returnstatement komen. i.
Pas de code in de methode getAddForm() aan, zodat deze methode het form geeft als het wordt aangeroepen.
In de action addAction() staat nu alleen nog de regel: $this->view->addForm=$form; Deze regel moet nog even worden aangepast. In plaats van $form in deze regel, moet je de methode getAddForm() aanroepen j.
Pas de action addAction() aan, zodat het form-object wordt verzonden naar de view door het de methode getAddForm() toe te passen.
De rest van de code hoeft niet gewijzigd te worden. Test de applicatie.
Manier 4: een form maken in een aparte Form klasse Een nog fraaiere manier om een form te maken is door gebruik te maken van een aparte Form klasse. Deze Form klasse kun je ook weer met zf maken. In dit geval gaan we de Form klasse Addfrm maken. Dit gaat met zf als volgt: zf create form Addfrm k. Maak een Form klasse Addfrm .
Als je nu in de mappenstructuur van je project kijkt, dan zie je dat er in de map application een nieuwe map met de naam forms is gemaakt, en in deze map een bestand Addfrm.php (zie figuur 12)
10
Figuur 12 Als je het bestand Addfrm.php opent, dan krijg je de code van figuur 13 te zien.
Figuur 13 Toelichting op de code De naam van de klasse lijkt nogal ingewikkeld, maar heeft alles met het autoload-mechanisme van ZF te maken. In ZF maak je namelijk geen gebruik van include files. Regels als: Include_once 'application/forms/Addfrm.php'; zal je in een ZF-project niet tegenkomen. In plaats daarvan kun je een bepaald bestand in een ander bestand toepassen door een soort padverwijzing te gebruiken waarin niet het teken "/ " of " \" een rol speelt, maar het teken "_" . Zo betekent Application_Form het pad …/application/forms/ De notatie met "_" ben je al tegengekomen in de controller ProductenController: class ProductenController extends Zend_Controller_Action Hier wordt verwezen naar een klasse in ZF.
11
Zend_Controller verwijst naar de map Zend/Controller in ZF. Action verwijst naar het bestand Zend/Controller/Action.php met daarin de klasse Zend_Controller_Action (ga dit na). Het laatste deel van dit pad verwijst dus altijd naar een bestand met daarin de klasse.
Als je deze notatie consequent toepast, dan kun je zonder te includen elke klasse in ZF of binnen het project benaderen. Dus: Application_Form _Addfrm verwijst de naar de map …/application/forms/ met daarin het bestand Addfrm.php , waarin de klasse Application _Form_Addfrm staat. Weer terug naar de Form klasse (zie figuur 13). Je ziet dat de klasse Application_Form _Addfrm een subklasse van de klasse Zend_Form is. Je kunt dus in de Application_Form _Addfrm dus properties en methodes van de klasse Zend_Form gebruiken zonder de klasse Zend_Form te instantiëren. Je kunt een methode als addEelement() dus binnen de klasse Application_Form _Addfrm gewoon aanroepen met : $this->addEelement(); In de klasse Application_Form _Addfrm moet je het formulier in de methode init() opbouwen, zie figuur 14.
Figuur 14
12
Je ziet dat de methode addElement() op een andere manier wordt gebruikt dan dat je gewend bent. Uiteraard is de manier die in figuur 10 is gebruikt ook toepasbaar. De manier zoals gebruikt is in figuur 14 is echter wat compacter. Je ziet dat naast het type en de naam van een element, ook de attributen van een element in een array als parameter van de methode addElement() wordt meegegeven. l.
Voorzie de methode init() van de klasse Application_Form _Addfrm van code, zoals in figuur 14.
We gaan vervolgens een instantie van de klasse Application_Form _Addfrm in de action addAction() naar de bijbehorende view verzenden. In figuur 15 zie je hoe dit in z'n werk gaat.
Figuur 15 m. Wijzig de code in de action addAction() volgens figuur 15 en controller de werking van de applicatie.
In de volgende leeropdracht gaan we wat doen aan de opmaak van het formulier dat je in leeropdracht 4.2 hebt gemaakt. Dit is wat minder eenvoudig dan wanneer het formulier gecreëerd is in de view zelf.
13
Leeropdracht 4.2
Figuur 16 Als het goed is krijg je in de laatste opdracht een standaardform te zien dat er uitziet als het form in figuur 11. We gaan dit fom stylen zodat je zoiets als in figuur 16 krijgt. Daarom gaan we eerst het label (de tekst boven de tekstboxen in figuur 11) en de tekstbox van het element in een de cellen van een HTML tabel zetten. Dit is niet zo eenvoudig. Om dit te kunnen moet je weten wat decorators zijn. Decorators zijn objecten onderdeel uitmaken van forms en elementen. Een voorbeeld van een decorator is het Label dat voor een tekstbox staat. Met de methode setLabel() kun je de tekst bij deze decorator aanpassen. Zo kent elk form drie standaard decorators en elk element vijf standaard decorators.
14
De standaard decorators van een form zijn: Form HtmlTag FormElements De standaard decorators van een element zijn: ViewHelper Errors Description HtmlTag Label Het is ook mogelijk een eigen gemaakte decorator toe te voegen aan een element. Dat gaan we straks doen. Maar nu eerst de standaard decorators. De decorators van een form In figuur 17 zie je hoe de decorators van een form georganiseerd zijn.
Figuur 17 Bij het instantiëren van de klasse Zend_Form of een subklasse daarvan, wordt een form gemaakt dat er als volgt uitziet:
Figuur 18
15
De decorator Form zorgt voor de tags . De decorator HtmlTag zorgt voor de tags
en
. De decorator FormElements zorgt ervoor dat de elementen in het form zichtbaar zijn (als deze eraan zijn toegevoegd.
n. Toon de view add.phtml in een browser. Bekijk de paginabron, en stel vast dat de structuur van het form is zoals in figuur 18. Het is nu de bedoeling dat we de decorator HtmlTag van het form gaan wijzigen in de tags
en
. Het attribuut id van deze table moet addtable worden. Met andere woorden, de code voor het form wordt: Figuur 19
Dit wordt gedaan met de volgende code:
In deze code zie je de drie decorators (FormElements, HtmlTag en Form) in een array. De decorators FormElements en Form worden niet veranderd. De decorator HtmlTag wordt gewijzigd. o. Wijzig de decorator HtmlTag van het form zodat het form de structuur van figuur 19 krijgt. p. Toon de view add.phtml in een browser. Bekijk de paginabron, en stel vast dat de structuur van het form is zoals in figuur 19.
16
De decorators van een element In figuur 20 zie hoe de decorators van een element georganiseerd zijn.
Figuur 20 Bij het creëren van een element wordt de volgende code gegenereerd:
Figuur 21
De tags voor de decorators Errors en Description zijn niet gegenereerd, omdat die niet zijn ingesteld.
De decorator Label zorgt voor de tags
. Met de methode setLabel() van een element kun je de tekst tussen de