AJAXem upravený formulář odešle pouze původní neupravený formulář

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Ekimik
Člen | 6
+
0
-

Zdravím,
poněvadž se mi nikde na fóru nepodařilo najít řešení mého problému, obracím se na vás s prosbou o pomoc, nasměrovaní či poučení, že takhle to nejde. Titulek může znít trochu hrozivě, ale pokusím se svůj problém co nejlépe vysvětlit, tak tedy:

Rád bych umožnil uživatelům svojí aplikace přidávat lidi, kteří se účastní nějaké aktivity. Vytvořil jsem si tedy základní kostru formuláře s jedním selectboxem a odesílacím tlačítkem, to je základní stav, který má uživatel k dispozici. Rovněž jsem se pokusil implementovat přidávání více lidí k dané aktivitě pomocí AJAXu. Uzavřel jsem tedy formulář do snippetu, vytvořil handle*() funkci, která se stará o překreslení formuláře (respektive vytváří formulář nový se 2-ma,3-mi,4-mi, … selectboxy). Formulář v této handle funkci ukládám do proměnné presenteru a v render*() funkci jej předávám do šablony. Dosud je vše ok, ale když se pak v šabloně AJAXem upravený formulář pokusím vyplnit a odeslat, při dumpnutí odeslaných dat v callbacku onSuccess[] formuláře dostanu pouze onu kostru formuláře, tedy jeden vyplněný select, ač jsem si jich přidal pomocí AJAXu třeba 5.

Rád bych vás požádal o radu, co dělám špatně, případně pokud toto nebude a ani nemůže fungovat, tak o menší osvětu proč tomu tak je. Pokud by to bylo možné preferoval bych řešení pomocí AJAXu, avšak již mám v podstatě připravené náhradní řešení, takže pokud nepůjde realizovat tato funkcionalita přes AJAX nebude to žádná katastrofa.

Pro úplnost používám:

  • Nette 2.0.9
  • PHP 5.3.13
  • nette.ajax.js v1.2.2 od Vojtěcha Dobeše

Pro „úplnou“ úplnost nějaký kód:

Hadle funkce starající se o překreslení formuláře

public function handleAddWorker($rows) {
    if ($this->isAjax()) {
        // indetifikátor akce
        $this->actionFlag = "addWorkers";

        // kolik zobrazit selectů
        $this->rows = intval($rows);

        // překreslení formuláře
        $this->workersForm = $this->createComponentManageWorkersForm();

        // invalidace snippetu
        $this->invalidateControl("manageWorkers");
    }
}

Předání formuláře do šablony:

if($this->workersForm === NULL){
    $this->workersForm = $this->createComponentManageWorkersForm();
}
$this->template->manageWorkersForm = $this->workersForm;

Vytvoření samotných selectboxů jsem svěřil metodě, kterou jsem si vytvořil v jednom z modelů své aplikace, zde úvádím definici metody včetně dokumentačních komentářů:

/**
 * Funkce, která do požadovaného (formuláře) přidává definovaný počet selectboxů
 * @param \Nette\Application\UI\Form $component
 * @param array $workersList - položky selectboxu (předpřipravené funkcí prepareDataForSelectList)
 * @param int $inputCount - kolik selectů a textboxů přidat
 * @param array | NULL $values - pokud je potřeba přidat defaultní hodnoty (for cyklus pro přidávání selectů začíná od 1, proto indexy pole musí také začínat od 1)
 * @return \Nette\Application\UI\Form - upravená komponenta
 */
public function addTaskWorkersInputs(\Nette\Application\UI\Form $component, $workersList, $inputCount, $values = NULL) {
    for ($index = 1; $index <= $inputCount; $index++) {
        $component->addSelect("taskWorker$index", "Pracovník:", $workersList)
                ->setPrompt("Vyberte pracovníka")
                ->setRequired("Vyberte prosím pracovníka ze seznamu $index.")
                ->setAttribute("class", "span12")
                ->setDefaultValue(($values !== NULL) ? $values[$index]["select"] : "");
    }

    return $component;
}
vvoody
Člen | 910
+
0
-

No evidentne pri odoslaní formu nemá aplikácia poňatia aký bol parameter rows pri poslednom handleAddWorker requeste. Nevymýšľaj koleso.

edit: človeče :D továrničky createComponent nikdy nevolaj priamo! Komponentu si pýtame vždy cez array access nad nadradenou komponentou (presenterom)

$this['manageWorkersForm'];

Potom nemusíš robiť takéto hlúposti

if($this->workersForm === NULL){
    $this->workersForm = $this->createComponentManageWorkersForm();
}
$this->template->manageWorkersForm = $this->workersForm;

Editoval vvoody (1. 10. 2013 23:39)

Ekimik
Člen | 6
+
0
-

@vvoody díky za informace a postřčení, pomohlo mi to. :)