Pridani komponenty do formulare
- Martin Bubík
- Člen | 13
potreboval bych do formulare „LogIn“ pridat komponentu „FieldUser“ kterou chci pouzit ve vice formularich, studoval jsem par prikladu a mam za to, ze by to melo fungovat tak jak to mam napsano nize, ale pise mi to error kteremu nerozumim:
Nette\InvalidStateException
Component ‚fieldUser‘ already has a parent.
<?php
use Nette\Application\UI\Form,
Nette\Forms\Controls\TextInput,
Nette\Security\AuthenticationException;
class CoursePresenter extends BasePresenter {
public function createComponentFieldUser() {
$field = new TextInput('Uživatel:', 20);
$field->setRequired('Zadejte uživatelské jméno.')
->addRule(Form::MIN_LENGTH, 'Uživatelské jméno musí mít nejméně %d znaků.', 5)
->addRule(Form::MAX_LENGTH, 'Uživatelské jméno může mít maximálně %d znaků.', 10);
return $field;
}
public function createComponentLogIn() {
$fieldUser = $this->getComponent('fieldUser');
$form = new Form;
$form->addComponent($fieldUser, 'user');
$form->addPassword('password', 'Heslo:')
->setRequired('Zadejte heslo.');
$form->addCheckbox('remember', 'Přihlásit trvale na tomto počítači');
$form->addSubmit('send', 'Přihlásit');
$form->onSuccess[] = callback($this, 'submitLogIn');
return $form;
}
public function submitLogIn(Form $form) {
....
}
}
?>
Neporadil by nekdo kde mam chybu a jak to mam zapsat?
- vvoody
- Člen | 910
Urob si BaseForm (extends Nette\Application\UI\Form) a v nom si vytvor metodu:
public function addFieldUser($name = 'user', $label = 'Uživatel:', string $cols = 20, $maxLength = NULL){
$field = new Nette\Forms\Controls\TextInput($label, $cols, $maxLength);
$field->setRequired('Zadejte uživatelské jméno.')
->addRule(Form::MIN_LENGTH, 'Uživatelské jméno musí mít nejméně %d znaků.', 5)
->addRule(Form::MAX_LENGTH, 'Uživatelské jméno může mít maximálně %d znaků.', 10);
return $this[$name] = $field;
}
potom uz len:
public function createComponentLogIn() {
$form = new BaseForm;
$form->addFieldUser();
...
}
- Martin Bubík
- Člen | 13
diky za info, tvuj priklad je jen o malo slozitejsi nez moje reseni ktere taky funguje jak je popsano vyse, staci jen prepsat:
<?php
public function createComponentLogIn() {
$fieldUser = $this->getComponent('fieldUser');
...
}
?>
na
<?php
public function createComponentLogIn() {
$fieldUser = $this->createComponentFieldUser('fieldUser');
...
}
?>
s tim ze metoda createComponentFieldUser se muze jmenovat jinak, protoze se pouziva jako bezna funkce. Nicmene vic by se mi libilo kdyby to fungovalo jako normalni komponenta, tohle je takovy muj zkusebni projekt tak se to snazim naucit a pochopit, ale tohle mi nejde do hlavy proc to nefakci tak jak to mam napsano vyse. Kazdopadne diky za odezvu.
Editoval Martin Bubík (27. 6. 2012 20:20)
- Vojtěch Dobeš
- Gold Partner | 1316
Důvod, proč prvně uvedený příklad nefunguje, je ten, že komponenta
fielfUser
je automaticky připojena k instanci třídy, v níž
je definovaná její továrnička – v tomto případě tedy k presenteru.
Jak nad tím přemýšlím, možná je to klíčové uvědomit si, že metoda
createComponent...
je pouze továrničkou, sama ještě komponentu
nedefinuje.
Řešením v tvém případě by bylo podědit si TextInput
do
třídy třeba FieldUser
. A v továrničce formuláře pak
nevolat getComponent()
, ale přímo new FieldUser
.
- Martin Bubík
- Člen | 13
Aha, tak to jsem nevedel, ze getComponent() mi to rovnou nekam
pripojuje…
Mel jsem za to ze to udela teprve addComponent() nad objektem formulare.
Ted uz mi dava smysl ta chybova hlaska.
Chtel jsem se puvodne vyhnout tomu, vytvaret pro kazde pole samostatnou tridu, ale nakonec jsem to tak udelal jak si psal a ono to je asi opravdu logictejsi a porad lepsi nez opakovat stejny kod v ruznych formularich.
Dekuji za objasneni.
- Vojtěch Dobeš
- Gold Partner | 1316
Úplně na vysvětlenou – automatické připojení k rodiči proběhne
hned po return $field;
. Nette si totiž zjistí, jestli už je
komponenta připojená, a pouze pokud ještě ne, provede automatické
připojení na třídu obsahující továrničku. Viz Připojení
komponenty k rodiči