Zachycení akce formuláře v přesenteru před createComponent
- Jabqooo
- Člen | 3
Zdravím,
nikde jsem tu nenašel odpověď, tak se zkusím zeptat takto.
Mám formulář s dynamickým přidáváním firem (obsahující kontakt,
adresu, Ičo, …) pomocí tlačítka. Formulář má ještě jedno tlačítko
pro uložení. Uložení probíhá ok, ale přidání formuláře mi bohužel
nefunguje. Respektive nevím jak docílit toho abych v presenteru přidal
další název (pro další kontejner – firmu) před createComponent.
Na vytváření formuláře mám továrničku které předávám callback, počet firem a názvy kontejnerů pro jednotlivé firmy(oddělovačem je čárka). Poprvé se počet firem přidá podlě $count a následně bych chtěl aby to bylo podle počtu v $name. Zde jsou názvy kontejnerů plus by zde měl být nový název nového kontejneru.
`
<?php
public function create(array $callback, $count, $name)
{
class FormFirmFactory extends Object
{
$form = new Form;
//for add firm
if ($name !== null) {
$names = explode(',', $name);
} else {
$names = [];
}
$formNames = $form->addHidden('names');
$form->addHidden('onlyadd');
if (count($names) > 0) {
foreach ($names as $nam) {
$this->addComponent($nam, $form);
}
$formNames->setValue($nam);
} else {
for ($i = 1; $i <= $count; $i++) {
$nam = 'firm' . substr(md5($i), -4);
$names[] = $nam;
$this->addComponent($nam, $form, $i);
}
$formNames->setValue(implode(',', $names));
}
$form->addSubmit('submitAddFirm', 'Přidat firmu');
$form->addSubmit('submitFirm', 'Uložit a pokračovat');
$form->onSuccess[] = $callback;
return $form;
}
private function addComponent($name, Form $form, $i = null)
{
$firmContainer = $form->addContainer($name);
$firmContainer->addText('name', "Název")
->setHtmlId('name')
->addRule(Form::MAX_LENGTH, 'Max length is %d', 64)
->addConditionOn($form['onlyadd'], $form::NOT_EQUAL, '1')
->addRule(Form::FILLED);
$firmContainer->addText('address', "Adresa")
->addCondition(Form::FILLED)
->addRule(Form::MAX_LENGTH, 'Max length is %d', 250);
$firmContainer->addText('in', "IČO")
->addRule(Form::MAX_LENGTH, 'Max length is %d', 10);
$firmContainer->addText('tin', "DIČ")
->addRule(Form::MAX_LENGTH, 'Max length is %d', 12);
$firmContainer->addText('contact', "Kontakt");
}
}
?>
`
Pokud přidám tlačítkem firmu tak se odešle formulář, presenter zachytí signál v metodě submitFirm, kde jsem chtěl vytvořit další jméno pro kontejner firmy. Ale to už je komponenta vytvořena, takže je to pozdě. A komponenta se vytvoří stejná jako předtím. A při dalším kliknutí jsou tam logicky hodnoty z minula.
`
<?php
final class NewDocumentPresenter extends BasePresenter
{
/** @var string @persistent */
public $firms;
public function submitFirm(Form $form)
{
$values = $form->getValues(true);
if($values['onlyadd'] == '1') {
$this->names = $values['names'] . ($values['names'] ? ',' : '') . 'firm' . substr(md5(date("d.m.Y G:i:s")), -4);
$this->redrawControl();
} else {
//tady je ukladani
}
}
protected function createComponentFirm()
{
$form = $this->firmService->getFirm([$this, 'submitFirm'], $this->names, $this->count);
$form->onError[] = function ($form) {
$this->redrawControl();
};
return $form;
}
}
?>
`
Mohl by mi prosím někdo poradit jak by se toto mělo řešit. Potřebuji nějak zjistit, že uživatel chce přidat firmu (stisklo se tlačítko přidat firmu) ještě před tím, než se zavolá createComponent.
Kód jsem očesal od zbytečností, aby byl přehlednější. zde je ještě
část ze servisy, která se volá z presenteru. Šablonu mi přijde zbytečné
sem dávat, ale pokud si myslíte opak, není problém dodat ;-).
`
<?php
public function getFirm($callback, $names, $count)
{
$firmFactory = new FormFirmFactory();
return $firmFactory->create($callback, $count, $sides);
// mimo toto se zde ještě načítají ještě nějaké hodnoty a doplňují defaultní hodnoty pro prvky formuláře
}
?>
`
Ješte jednou díky za jakoukoliv radu, zavařil jsem se na tomhle na půl dne.
- Jiří Nápravník
- Člen | 710
Nevím, jestli to úplně chápu, ale mrkni na Kdyby\Replicator ten řeší dynamický počet položek.
- Jabqooo
- Člen | 3
Ahoj, díky ale asi kvůli této jedné prkotině nebudou přidávat do
produkčního softu závislost na Kdyby replikatoru.
Proto mě zajímalo jak vyřešit (pokud to tedy nějak jde) zachycení
odeslaného formu presenterem dřív, než se zavolá createComponent.
Jestli to dobře chápu životní cyklus, tak se odeslaný form zachytí
v handle a createComponent pokud ho poprvé potřebuji. Tzn, pokud mám
v šabloně toto:
<form n:name=firm class=„form ajax“> …
, tak jsem čekal že createComponen se provede v render, ale očividně je to dřív než v handle. Takže se create component potřebuje již někde dřív a nebo něco dělám blbě (což nevylučuji).
Samozřejmě by to šlo ohekovat tak, že si data z formuláře uložím nejen po stisknutí tlačítka uložit, ale i po stisknutí tlačítka přidat. Ale to je podle mě špatné řešení a tak se tomu snažím vyhnout.
- Jabqooo
- Člen | 3
Nakonec jsem to vyřešil tak, že v metodě submitFirm volám metodu,
která do formu přidá další komponentu s firmou.
Nevěděl jsem že v okamžiku, kdy handle zachytí submit a createComponent
již vytvořil form, tak mohu ještě do formu v klidu hrabat ;-). Jo a názvy
jednotlivých komponent z formu si nakonec ukládám do session.
`
<?php
public function submitFirm(Form $form)
{
$values = $form->getValues(true);
if($values['onlyadd'] == '1') {
$newName = 'firm' . substr(md5(date("d.m.Y G:i:s")), -4);
$this->formFirmFactory->addComponent($newName, $form)
$this->redrawControl();
} else {
//tady je ukladani
}
}
?>
`