Změna pořadí prvků ve formuláři při rozšíření vlastního formuláře
- Tomáš Votruba
- Moderator | 1114
Mám vlastní formulářovou třídu loginForm
(v ní inputy
login
, password
a submit
).
Chci přidat jeden input uprostřed, tím pádem ho ale
automaticky dostanu na konec, za submit. To ne!
(Rád bych ho měl mezi pod password
.)
Jde tento problém vyřešit bez ručního renderu?
Editoval Schmutzka (3. 4. 2012 22:46)
- Jan Tvrdík
- Nette guru | 2595
Mělo by to být řešitelné pomocí ručního volání nízkoúrovňové
funkce addComponent
s vyplněným třetím parametrem.
- Tomáš Votruba
- Moderator | 1114
Díky, teď mi ale vzniká dilema. Zmínění postup půjde v případě,
kdy prvky vytvářím v __construct()
.
Já je ale vytvářím až v „attached“ https://api.nette.org/…orm.php.html#54,
abych mohl využít settery pro nastavení např. délky hesla.
$form = new loginForm($this->user); // může být v configu, konstatní
$form->passwordLength = 10; // může být všude jiné, proto přes setter
Mohl bych sice ono číslo předat přes konstruktor, ale když mám těchto nastavitelných položek např. 10, bylo by to nepraktické.
Jak tedy mít možnost přidat prvek tam, kam potřebuji, a zároveň mít možnost využívat settery?
- Ascaria
- Člen | 187
Přečetl jsem si to několikrát, abych nenapsal nějakou odpověď úplně mimo, ale co třeba:
class loginForm
{
public function __construct($parent = null, $name = null)
{
parent::__construct($parent, $name);
// tady je to už attachlé a tak můžeš "attached" mít už v konstruktoru
}
}
public function createComponentForm($name)
{
$form = new loginForm($this, $name, $this->user);
$form->passwordLength = 10; // již attachlý form
}
Editoval Ascaria (4. 4. 2012 1:18)
- Tomáš Votruba
- Moderator | 1114
@Ascaria: Jak by se v tomto případě aplikovala podmínka na délku hesla?
- Jan Tvrdík
- Nette guru | 2595
Nějak nechápu, v čem je problém. Proč by to v attached nemělo fungovat?
- Tomáš Votruba
- Moderator | 1114
Jan Tvrdík napsal(a):
Nějak nechápu, v čem je problém. Proč by to v attached nemělo fungovat?
Attached probíhá až při připojení k presenteru. Ještě před ní mohu využít právě settery. Jestli tomu zatím správně rozumím, pořadí je:
__construct
setters
attached
Přičemž u 2) mohu přidat prkvy, ale zároveň ještě neexistují ty uvnitř třídy, které se vytvoří až ve 3). Proto nemůžu prvku v kroku 2) určit pořadí.
Napadlo mne obecné zadání, které snad k pochopení postačí.
Rozšiřuji loginForm
a potřebuji:
1) přidat prvek mezi existující prvky
2) nastavit všechny položky jako povinné (zřejmě pomocí
setteru)
Napadl mne pseudokód:
$form = new LoginForm;
// settery
$form->setter1 = TRUE;
$form->setter2 = TRUE;
// připojím prvky, které jsou v definované ve třídě
$form->attach();
// připojím prvky navíc a už si mohu vybrat kam
$form->addText("something", "Fill me:")
Editoval Schmutzka (4. 4. 2012 12:50)
- Jan Tvrdík
- Nette guru | 2595
Pořád nechápu problém. Dejme tomu, že nyní přidáváš prvek
foo
na konec takto.
$form->addText('foo');
Pokud chceš přidat prvek mezi prvky name a password, tak volání addText() nahradíš takto:
$component = new Nette\Forms\Controls\TextInput();
$form->addComponent($component, 'foo', 'password');
- Tomáš Votruba
- Moderator | 1114
Ano, to řeší bod 1) již od začátku. Zároveň potřebuji i bod 2), ptám se tedy jak to zkombinovat.
Uvnitř třídy loginForm
je něco jako:
public function attached() {
parent::attached();
$this->addText("name", "Váše jméno, prosím");
$this->addText("email", "Váš email, prosím");
$this->addText("size", "Vaše velikost, prosím");
}
if($this->allRequired) { // dostanu přes setter
$this["name"]->setRequired();
$this["email"]->setRequired();
$this["size"]->setRequired();
}
- Tomáš Votruba
- Moderator | 1114
Tak má idea potřebuje ještě jednu věc, existuje nějaký callback na toto?
$form = new LoginForm;
$form->addText("..."); // callback na pokus přidání control
- davidm
- Člen | 81
To asi neexistuje :) ale jestli ho potrebujes tak si poded form a pridej si ho do addComponent ne?
public function addComponent(Nette\ComponentModel\IComponent $component, $name, $insertBefore = NULL)
{
$this->schmutzkovoCallback();
parent::addComponent($component, $name, $insertBefore);
}
- Tomáš Votruba
- Moderator | 1114
davidm napsal(a):
To asi neexistuje :) ale jestli ho potrebujes tak si poded form a pridej si ho do addComponent ne?
public function addComponent(Nette\ComponentModel\IComponent $component, $name, $insertBefore = NULL) { $this->schmutzkovoCallback(); parent::addComponent($component, $name, $insertBefore); }
To zní pěkně, ale chtěl bych to přímo pro addText
,
addSubmit
etc., resp. pro první přidání prvku.
Tedy nejlépe v konstruktoru BaseControl
(od kterého tyto třídy
dědí), ale v rámci potomka třídy Forms
, jinak bych musel
všechny prvky nutit dědit můj BaseControl
a to by bylo
šílené.
- Tomáš Votruba
- Moderator | 1114
Jo, promiň, už jsem nedokončil myšlenku :).
Napsal jsem si medotu moveBefore,
která umístí nový prvek tam, kam je potřeba. V něm se volá metoda build
v níž jsou přidávány nové prvky. Je tedy zaručeno, že při pohybu je
již formulář složen.
využije se v případě, kdy vytváříš samostatný formulář).
Asi takto:
MyPresenter.php
protected function createComponentLoginForm()
{
$form = new LoginForm;
$form->passwordLength = 10;
$form->addText("code", "Napiš 'code9'"); // připojím nový prvek
$form->moveBefore("code", "login"); // přemístím úplně na začátek
return $form;
}
Build u LoginForm.php může vypadat takto
Snad to je srozumitelné :).