Izrisovanje obrazcev
Videz obrazcev je lahko zelo raznolik. V praksi lahko naletimo na dva ekstrema. Na eni strani stoji potreba po izrisovanju
številnih obrazcev v aplikaciji, ki so si vizualno podobni kot jajce jajcu, in cenimo enostavno izrisovanje brez predloge
s pomočjo $form->render()
. Gre običajno za primer administrativnih vmesnikov.
Na drugi strani pa so raznoliki obrazci, kjer velja: vsak kos je original. Njihovo podobo najbolje opišemo z jezikom HTML v predlogi obrazca. In seveda poleg obeh omenjenih ekstremov naletimo na veliko obrazcev, ki se gibljejo nekje vmes.
Izrisovanje s pomočjo Latte
Sistem predlog Latte bistveno olajša izrisovanje obrazcev in njihovih elementov. Najprej si bomo pokazali, kako obrazce izrisovati ročno po posameznih elementih in s tem pridobiti popoln nadzor nad kodo. Kasneje si bomo pokazali, kako je mogoče takšno izrisovanje avtomatizirati.
Načrt Latte predloge obrazca si lahko pustite generirati s pomočjo metode
Nette\Forms\Blueprint::latte($form)
, ki ga izpiše na stran brskalnika. Kodo nato zadostuje s klikom označiti in
kopirati v projekt.
{control}
Najenostavnejši način, kako izrisati obrazec, je napisati v predlogi:
Vplivati na podobo tako izrisanega obrazca je mogoče s konfiguracijo Rendererja in posameznih elementov.
n:name
Definicijo obrazca v PHP kodi je mogoče izjemno enostavno povezati s HTML kodo. Zadostuje le dopolniti atribute
n:name
. Tako je enostavno!
Podobo končne HTML kode imate popolnoma v svojih rokah. Če atribut n:name
uporabite pri elementih
<select>
, <button>
ali <textarea>
, se njihova notranja vsebina samodejno
dopolni. Oznaka <form n:name>
poleg tega ustvari lokalno spremenljivko $form
z objektom risanega
obrazca in zaključna </form>
izriše vse neizrisane skrite elemente (enako velja tudi za
{form} ... {/form}
).
Ne smemo pa pozabiti na izrisovanje morebitnih sporočil o napakah. In to tako tistih, ki so se z metodo
addError()
dodala k posameznim elementom (s pomočjo {inputError}
), kot tudi tistih, dodanih
neposredno k obrazcu (vrača jih $form->getOwnErrors()
):
Bolj zapletene elemente obrazca, kot sta RadioList ali CheckboxList, je mogoče tako izrisovati po posameznih postavkah:
{label}
{input}
Ne želite pri vsakem elementu razmišljati, kateri HTML element zanj uporabiti v predlogi, ali <input>
,
<textarea>
itd.? Rešitev je univerzalna oznaka {input}
:
Če obrazec uporablja prevajalnik|, bo besedilo znotraj oznak {label}
prevedeno.
Tudi v tem primeru je mogoče bolj zapletene elemente obrazca, kot sta RadioList ali CheckboxList, izrisovati po posameznih postavkah:
Za izrisovanje samega <input>
v elementu Checkbox uporabite {input myCheckbox:}
. HTML atribute
v tem primeru vedno ločujte z vejico {input myCheckbox:, class: required}
.
{inputError}
Izpiše sporočilo o napaki k elementu obrazca, če ga ima. Sporočilo običajno zavijemo v HTML element zaradi stiliranja.
Preprečiti izrisovanje praznega elementa, če sporočila ni, je mogoče elegantno s pomočjo n:ifcontent
:
Prisotnost napake lahko ugotovimo z metodo hasErrors()
in glede na to nastavimo razred nadrejenemu elementu:
{form}
Oznake {form signInForm}...{/form}
so alternativa k
<form n:name="signInForm">...</form>
.
Samodejno izrisovanje
Zahvaljujoč oznakam {input}
in {label}
lahko enostavno ustvarimo splošno predlogo za kateri koli
obrazec. Postopoma bo iterirala in izrisovala vse njegove elemente, razen skritih elementov, ki se izrišejo samodejno ob
zaključku obrazca z oznako </form>
. Ime izrisovanega obrazca bo pričakovala v spremenljivki
$form
.
Uporabljene samozaključujoče parne oznake {label .../}
prikazujejo oznake, ki izhajajo iz definicije obrazca
v PHP kodi.
To splošno predlogo shranite na primer v datoteko basic-form.latte
in za izrisovanje obrazca jo zadostuje
vključiti ter predati ime (ali instanco) obrazca v parameter $form
:
Če bi pri izrisovanju enega določenega obrazca želeli poseči v njegovo podobo in na primer en element izrisati drugače, potem je najenostavnejša pot, da si v predlogi predpripravite bloke, ki jih bo mogoče kasneje prepisati. Bloki imajo lahko tudi dinamična imena, vanje je tako mogoče vstaviti tudi ime izrisovanega elementa. Na primer:
Za element npr. username
tako nastane blok input-username
, ki ga je mogoče enostavno prepisati
z uporabo oznake {embed}:
Alternativno je mogoče celotno vsebino predloge basic-form.latte
definirati kot blok, vključno s parametrom
$form
:
Zahvaljujoč temu bo njegov klic nekoliko enostavnejši:
Blok pri tem zadostuje uvoziti na enem samem mestu in to na začetku predloge postavitve:
Posebni primeri
Če potrebujete izrisati le notranji del obrazca brez HTML oznak <form>
, na primer pri pošiljanju odrezkov
(snippetov), jih skrijte s pomočjo atributa n:tag-if
:
Z izrisovanjem elementov znotraj vsebnika obrazca pomaga oznaka {formContainer}
.
Izrisovanje brez Latte
Najenostavnejši način, kako izrisati obrazec, je poklicati:
Vplivati na podobo tako izrisanega obrazca je mogoče s konfiguracijo Rendererja in posameznih elementov.
Ročno izrisovanje
Vsak element obrazca ima metode, ki generirajo HTML kodo polja obrazca in oznake. Lahko jo vračajo bodisi kot niz ali objekt Nette\Utils\Html:
getControl(): Html|string
vrne HTML kodo elementagetLabel($caption = null): Html|string|null
vrne HTML kodo oznake, če obstaja
Obrazec je tako mogoče izrisovati po posameznih elementih:
Medtem ko pri nekaterih elementih getControl()
vrne en sam HTML element (npr. <input>
,
<select>
ipd.), pri drugih cel kos HTML kode (CheckboxList, RadioList). V takem primeru lahko uporabite
metode, ki generirajo posamezne vnose in oznake, za vsako postavko posebej:
getControlPart($key = null): ?Html
vrne HTML kodo ene postavkegetLabelPart($key = null): ?Html
vrne HTML kodo oznake ene postavke
Te metode imajo iz zgodovinskih razlogov predpono get
, vendar bi bil boljši generate
,
ker pri vsakem klicu ustvari in vrne nov element Html
.
Renderer
Gre za objekt, ki zagotavlja izrisovanje obrazca. Tega je mogoče nastaviti z metodo $form->setRenderer
. Njemu
se preda nadzor ob klicu metode $form->render()
.
Če ne nastavimo lastnega rendererja, bo uporabljen privzeti izrisovalnik Nette\Forms\Rendering\DefaultFormRenderer. Ta elemente obrazca izriše v obliki HTML tabele. Izhod izgleda takole:
Ali uporabiti ali ne uporabiti za ogrodje obrazca tabelo je sporno in vrsta spletnih oblikovalcev preferira drugačen markup.
Na primer definicijski seznam. Prekonfiguriramo zato DefaultFormRenderer
tako, da obrazec izriše v obliki seznama.
Konfiguracija se izvaja z urejanjem polja $wrappers. Prvi indeks
vedno predstavlja območje in drugi njegov atribut. Posamezna območja ponazarja slika:

Standardno je skupina elementov controls
ovita s tabelo <table>
, vsak pair
predstavlja vrstico tabele <tr>
in par label
ter control
sta celici
<th>
in <td>
. Zdaj ovojne elemente spremenimo. Območje controls
vstavimo
v vsebnik <dl>
, območje pair
pustimo brez vsebnika, label
vstavimo v
<dt>
in na koncu control
ovijemo z oznakami <dd>
:
Rezultat je ta HTML koda:
V polju wrappers je mogoče vplivati na celo vrsto drugih atributov:
- dodajati CSS razrede posameznim tipom elementov obrazca
- razlikovati CSS razred lihih in sodih vrstic
- vizualno ločiti obvezne in neobvezne postavke
- določati, ali se sporočila o napakah prikažejo neposredno pri elementih ali nad obrazcem
Možnosti (Options)
Obnašanje Rendererja je mogoče nadzorovati tudi z nastavljanjem options na posameznih elementih obrazca. Tako je mogoče nastaviti napis, ki se izpiše poleg vnosnega polja:
Če vanj želimo umestiti HTML vsebino, uporabimo razred Html
Html element je mogoče uporabiti tudi namesto oznake:
$form->addCheckbox('conditions', $label)
.
Združevanje elementov
Renderer omogoča združevanje elementov v vizualne skupine (fieldsete):
Po ustvarjanju nove skupine ta postane aktivna in vsak na novo dodan element je hkrati dodan tudi vanjo. Tako je mogoče obrazec graditi na ta način:
Renderer najprej izrisuje skupine in šele nato elemente, ki ne pripadajo nobeni skupini.
Podpora za Bootstrap
V primerih najdete primere, kako konfigurirati Renderer za Twitter Bootstrap 2, Bootstrap 3 in Bootstrap 4
HTML atributi
Za nastavitev poljubnih HTML atributov elementov obrazca uporabimo metodo
setHtmlAttribute(string $name, $value = true)
:
Specifikacija tipa elementa:
Nastavitev tipa in drugih atributov služi le za vizualne namene. Preverjanje pravilnosti vnosov mora potekati na strežniku, kar zagotovite z izbiro ustreznega elementa obrazca in navedbo validacijskih pravil.
Posameznim postavkam v seznamih izbirnih gumbov ali potrditvenih polj lahko nastavimo HTML atribut z različnimi vrednostmi
za vsako od njih. Opazite dvopičje za style:
, ki zagotovi izbiro vrednosti glede na ključ:
Izpiše:
Za nastavitev logičnih atributov, kot je readonly
, lahko uporabimo zapis z vprašajem:
Izpiše:
V primeru izbirnih polj (selectbox) metoda setHtmlAttribute()
nastavlja atribute elementa
<select>
. Če želimo nastaviti atribute posameznim <option>
, uporabimo metodo
setOptionAttribute()
. Delujejo tudi zapisi z dvopičjem in vprašajem, navedeni zgoraj:
Izpiše:
Prototipi
Alternativni način nastavljanja HTML atributov temelji na urejanju predloge, iz katere se HTML element generira. Predloga je
objekt Html
in jo vrača metoda getControlPrototype()
:
Na ta način je mogoče modificirati tudi predlogo oznake, ki jo vrača getLabelPrototype()
:
Pri elementih Checkbox, CheckboxList in RadioList lahko vplivate na predlogo elementa, ki celoten element ovija. Vrača jo
getContainerPrototype()
. V privzetem stanju gre za „prazen“ element, tako da se nič ne izrisuje, a s tem, da
mu nastavimo ime, se bo izrisoval:
V primeru CheckboxList in RadioList lahko vplivate tudi na predlogo ločila posameznih postavk, ki ga vrača metoda
getSeparatorPrototype()
. V privzetem stanju je to element <br>
. Če ga spremenite v parni
element, bo posamezne postavke ovijal namesto ločeval. In dalje lahko vplivate na predlogo HTML elementa oznake pri posameznih
postavkah, ki ga vrača getItemLabelPrototype()
.
Prevajanje
Če programirate večjezično aplikacijo, boste verjetno potrebovali obrazec izrisati v različnih jezikovnih mutacijah. Nette Framework za ta namen definira vmesnik za prevajanje Nette\Localization\Translator. V Nette ni nobene privzete implementacije, lahko si izberete glede na svoje potrebe iz več pripravljenih rešitev, ki jih najdete na Componette. V njihovi dokumentaciji boste izvedeli, kako prevajalnik konfigurirati.
Obrazci podpirajo izpisovanje besedil preko prevajalnika. Predamo jim ga s pomočjo metode setTranslator()
:
Od te točke naprej se ne le vse oznake, ampak tudi vsa sporočila o napakah ali postavke izbirnih polj prevedejo v drug jezik.
Pri posameznih elementih obrazca je pri tem mogoče nastaviti drug prevajalnik ali prevajanje popolnoma izklopiti z vrednostjo
null
:
Pri validacijskih pravilih se prevajalniku predajajo tudi specifični parametri, na primer pri pravilu:
se kliče prevajalnik s temi parametri:
in torej lahko izbere pravilno obliko množine pri besedi znakov
glede na število.
Dogodek onRender
Tik preden se obrazec izriše, lahko pustimo poklicati našo kodo. Ta lahko na primer dopolni elementom obrazca HTML razrede za
pravilno prikazovanje. Kodo dodamo v polje onRender
: