Kombinované / zlúčené formuláre
- Tomas P
- Člen | 27
Rad by som sa opytal, ci je technicky mozne, mat viac formularov naprogramovanych spolocne, v jednom createComponent*Form() za nasledujucich podmienok (polozky su [A-Z][0–9]):
spolocna cast formulara
S1, S2*, S3*…
FormA
A1, A2*..
FormB
B1, B2*…
FormC
C1*, C2…
SUBMIT (spolocny)
Frontend:
Uzivatel ma vzdy vidiet spolocnu cast… a potom si vyberie ako pokracuje, ale
nema to byt viacstrankovy formular, ale na tej istej stranke… napr radio
button + javascript, alebo iba prepinanie tw. bootstrap tabov a pod.
Problem:
Je problem s validaciou povinnych poli. Chcem ich mat oznacene ako povinne (aby
sa vykreslovali spravne), ale ich automaticku validaciu chcem v pripade
vyplnania inej sekcie potlacit.
Je to mozne? Ako sa to robi?
Ak nie, mate nejake napady?
- duskohu
- Člen | 778
Ahoj, v podstate si to urob ako jeden formular, ale prvky tam budes pridavat podla toho ako chces.Pridas si tam ovladacie prvky napr. : buttonA, buttonB, buttonC a samozrejme buttonSend, kazdy bude mat svoje spracovanie na prve 3 naviazes ->setValidationScope(FALSE) aby ti formular nevalidovalo a v metodach budes pridavat do formulara dalsie prvky a nasledne invalidujes snippet. cize sa ti formular prekresli. Este som to takto nepotreboval riesit tak predpokladam ze este budes musiet riesit nejake doladovacky.
- duskohu
- Člen | 778
Pisem z hlavy
protected function createComponentForm()
{
$form = new Form;
$form->addText('for-all', 'Text');
$form->addSubmit('formA', 'formA')
->setValidationScope(FALSE)
->onClick[] = callback($this, 'processFormA');
$form->addSubmit('formB', 'formB')
->setValidationScope(FALSE)
->onClick[] = callback($this, 'processFormB');
$form->addSubmit('formC', 'formC')
->setValidationScope(FALSE)
->onClick[] = callback($this, 'processFormC');
$form->addSubmit('send', 'Send')
->setValidationScope(FALSE)
->onClick[] = callback($this, 'processSend');
return $form;
}
public function processFormA(Form $form){
$this['form']->addText('for-a', 'Text');
$this->invalidateControl();
}
public function processSend(Form $form){
// send
}
- Tomas P
- Člen | 27
Tyjo, super, vdaka… to je presne co potrebujem.
Skoda ze v SubmitButton.php je len todo :-)
<?php
public function setValidationScope($scope)
{
// TODO: implement groups
$this->validationScope = (bool) $scope;
...
?>
A ked pouzijem invalidateControl so snippetom, musim to mat poriesene ajaxom? Mne nevadi reload ak to bude vyzerat rovnako a zapamata si to hodnoty co uz raz boli vyplnene.
Dik za priklad, vela to ozrejmilo.
Hlavny submit ale asi dam do processFormA/B/C() a uz s validaciou, aby sa form
nedal poslat este pred doplnenim A/B/C.
Velmi pekne dakujem.
- Tomas P
- Člen | 27
Hmm…
nejak mi to nechce v poslednom kroku zavolat submit handler… je
to divne.
prepinanie formularov funguje spravne … dokonca sa ani nescitaju polozky z A/B/C, co ma milo prekvapilo, som sa bal ze uz bude formular v parametri process*() vacsi, ale nie je.
Problem mam ale s tym, ze ked kliknem na zaverecny submit (pridany dielcim
submitom), formular sa iba reloadne a zostane sice vyplneny (pamata si hodnoty),
ale nezavola sa moj handler.
Skusal som v dielcom process*() pridat aj onSuccess[], ale to sa aplikovalo
vzdy po kazdom stlaceni.
Toto je kod (je to s nejakym placeholder textom ohladne mena, originalne to potrebujem na nieco ovela vacsie :-) ).
<?php
public function createComponentServiceForm()
{
$form = new Form;
$form->addText('firstname', 'Jméno')
->setRequired('Vyplňte jméno');
$form->addText('lastname', 'Příjmení')->setRequired('Příjmení');
$form->addSubmit('a', 'first')
->setValidationScope(false)
->onClick[] = callback($this, 'processA');
$form->addSubmit('b', 'second')
->setValidationScope(false)
->onClick[] = callback($this, 'processB');
$form->addSubmit('c', 'third')
->setValidationScope(false)
->onClick[] = callback($this, 'processC');
return $form;
}
public function processA(Nette\Forms\Controls\SubmitButton $button)
{
$form = $button->getForm();
$form->addText('title_before', 'Titul před jménem')
->setRequired('Titul před jménem');
$form->addSubmit('submit', 'submit')
->onClick[] = callback($this, 'serviceSubmit');
}
public function processB(Nette\Forms\Controls\SubmitButton $button)
{
$form = $button->getForm();
$form->addText('title_after', 'Titul za')
->setRequired('Titul za');
$form->addSubmit('submit', 'submit')
->onClick[] = callback($this, 'serviceSubmit');
}
public function processC(Nette\Forms\Controls\SubmitButton $button)
{
$form = $button->getForm();
$form->addText('middle_name', 'Další jméno')
->setRequired('Další jméno');
$form->addSubmit('submit', 'submit')
->onClick[] = callback($this, 'processForm');
}
public function processForm(Nette\Forms\Controls\SubmitButton $button)
{
dump($button);
exit;
}
?>
Neviem ci nezavolanie mojho handleru je sposobene chybou kodu alebo je to bug, alebo sa tlacitka nesmu pridavat v handleroch onClick… neviem ani ako by som to debugoval, kedze to nevola to co chcem.
--
Potom som si povedal, ze este nieco vyskusam…
<?php
public function createComponentServiceForm()
{
//...
$form->onSuccess[] = callback($this, 'processFullForm');
}
// ostatne sa nemenili
public function processFullForm(Form $form)
{
if ($form->submitted === true) {
$this->flashMessage('submit button');
} else {
$button = $form->submitted->name;
$this->flashMessage($button);
}
return;
}
?>
tu uz je jednoznacne co sa ma vykonat v zaverecnom submit handleri.
onClick
posledneho tlacitka sa stale nevola.
Problem je, ze ked si dumpnem $form->getValues()
, tak chyba to
co som pridal onClick funkciou. Takze je to stale nepouzitelne :-(
- duskohu
- Člen | 778
Hmmm, to bude preto lebo ked sa formular spracuvava v processForm tak neobsahuje polozky ktore sa mu pridali v A,B, alebo C, tym padom dumpnes len zakladne polozky. Este ma napadlo toto, len neviem ci je to ciste.
protected function attached($presenter)
{
if ($presenter instanceof Presenter) {
/** @var Form $form */
$form = $this['form'];
$form->addSubmit('submit', 'submit')
->onClick[] = callback($this, 'processForm');
}
parent::attached($presenter);
}
/**
* FORM Page
* @return Form
*/
protected function createComponentForm()
{
$form = new Form;
$form->addText('firstname', 'Jméno');
$form->addText('lastname', 'Příjmení');
$form->addSubmit('submitByA', 'first')
->setValidationScope(FALSE)
->onClick[] = callback($this, 'processA');
$form->addSubmit('submitByB', 'second')
->setValidationScope(FALSE)
->onClick[] = callback($this, 'processB');
$form->addSubmit('submitByC', 'third')
->setValidationScope(FALSE)
->onClick[] = callback($this, 'processC');
return $form;
}
/**
* @param Form $form
*/
private function setAForm($form)
{
$form->addText('title_before', 'Titul před jménem');
$form->addHidden('formType')
->setValue('A');
}
public function processA(\Nette\Forms\Controls\SubmitButton $button)
{
$form = $this['form'];
$this->setAForm($form);
}
public function processForm(\Nette\Forms\Controls\SubmitButton $button)
{
$form = $button->getForm();
$values = $form->getHttpData();
if ($values['formType']) {
$this->setAForm($form);
}
dump($values);
}
- Tomas P
- Člen | 27
jj, toto (7.) ma tiez napadlo.
ze by som v tom finalnom handleri podla niecoho co je v tom povodnom formulari (teda addHidden() v createComponentForm) zavolal rozsirenie formulara jednou z processA/B/C funkcii. A snad tym ze samotny HTTP POST data obsahuje, ze by sa mi tam objavili.
prislo mi to ale dost skarede, tak asi spravim 3 formulare a bude to len trosku menej user friendly ale zato naprogramovane pouzitim normalnych, zdokumentovanych postupov. v kode mozem mat jednotlive casti rozdelene vo funkciach a tak ako pises v dalsom poste, si to len poskladam.
skoda ze to nette nevie (ciastocne obmedzenie validacie), ked budem mat cas by som sa na to mal pozriet, ci je to skutocne tak velky problem. v Drupal7 to je aj s kopou inych veci, ktore mi v nette chybaju :-(.
Inak podla tychto zisteni mam pocit ze v nette nielen ze nejde spravit to co som chcel ja (tj. obmedzit validationScope), ale nefunguju ani viacstrankove formulare nijak jednoducho…
- duskohu
- Člen | 778
Takze mi to nedalo. Funkcne riesenie:
/** @persistent */
public $type;
protected function createComponentForm()
{
$form = new Form;
$form->addText('firstname', 'Jméno');
if ($this->type == 'a') {
$form->addText('lastname', 'Příjmení');
$form->addSubmit('submit', 'submit');
$form->onSuccess[] = callback($this, 'processForm');
}
return $form;
}
public function processForm(Form $form)
{
$values = $form->getValues();
dump($values);
}
latte:
{control form}
<a n:href="this type=>a">aaaa</a>