Nastavení defaultní hodnoty radioList po odeslání formu, BUG NETTE?

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

Ahoj, už se pár hodin peru s jedním problémem a opravdu už mi došly nápady, tudíž si skoro začínám myslet, že jsem narazil na bug Nette. Udělal jsem kvůli tomu i rychlou ukázku.

O co jde:
mám nějakou komponentu, pro krokové formuláře, jenže při přepínání stepů po submitu formuláře se nanstavují values u RadioListů.. Vím, že setDefaultValue() se neprovede při submitu, tudíž volám ->setValue() ale ani tak se neprovede..

Živá ukázka: ZDE

Přikládám i kód

Presenter:

    protected function createComponentStepForm(){
        $form = new Form();
        $form->addGroup('první krok');
        $container = $form->addContainer('container_1');
        $container->addText('textinput','Text');
        $container->addSubmit('send1','Další')->setValidationScope([$container]);

        $form->addGroup('Druhý krok');
        $container_2 = $form->addContainer('container_2');
        $container_2->addRadioList('radiolist','RadioList',[1=>'První',2=>'Druhá',3=>'Třetí'])->setValue(1);

        $stepForm = new StepForm();
        $stepForm->setForm($form);
        return $stepForm;
    }

StepForm.php

class StepForm extends Control
{
    private $form;

    private $steps;

    private $currentStep = 1;


    public function setForm($form)
    {
        $this->form = $form;
        foreach ($form->components as $container) {
            if ($container instanceof Container) {
                $counter = count($this->steps) + 1;

                $group = $container->getCurrentGroup();
                $this->steps[$counter] = $group;
            }
        }

    }


    public function handleStep($position)
    {
        $this->changeStep($position);
    }


    public function changeStep($position)
    {
        $this->currentStep = $position;
    }


    protected function createComponentForm()
    {
        $form = $this->form;
        $form->onSuccess[] = [$this, 'saveForm'];
        return $form;
    }


    public function saveForm($form)
    {
        $this->changeStep($this->currentStep + 1);
    }


    public function render()
    {
        $template = $this->template;
        $template->setFile(__DIR__ . '/StepForm.latte');

        $template->steps = $this->steps;
        $template->currentStep = $this->currentStep;
        $template->render();
    }


}

StepForm.latte

{form form}

{var $group = $steps[$currentStep]}
    <fieldset>
        <legend>{$group->getOption('label')}</legend>

        {foreach $group->controls as $item}
            {$item->label}
            {$item->control}
        {/foreach}

    </fieldset>
    <a n:href="Step! 2">Přejít ručně na druhý krok</a>
{/form}

Editoval kleinpetr (7. 4. 2015 14:10)

greeny
Člen | 405
+
0
-

Formulář doporučuju rozdělit na dva různé a data si předávat přes session. Takhle by se vícestupňové formuláře řešit neměly.

F.Vesely
Člen | 369
+
0
-

Podle me je to takhle:

  1. Ty odesles formular, ale pouze data z prvniho kroku, inputy z druheho kroku se vubec neposlou
  2. Vytvori se formular, radiolist si nastavi hodnotu na 1
  3. Na vytvoreny formular se zavola setValues(), kde se pro kazdy prvek formulare kontroluje, jestli ma nejaka data z kroku 1. Jelikoz tam pro radiolist zadna data nejsou, tak se nastavi hodnota na null.
kleinpetr
Člen | 480
+
0
-

To by dávalo smysl, pokud se tedy ->setValues() volá automaticky ? Dalo by se tedy nějak nstavit submit buttonu aby odesílal data pouze ze scope, který má nastaven ? díky

Editoval kleinpetr (7. 4. 2015 14:22)

kleinpetr
Člen | 480
+
0
-

Ano to bych sice měl, ale při zpracovávní nevím kolik kroků bude, protože si ten form načítám z API.. Ale každopádně používám session následovně: v metodě onSuccess() si vždy uložím data z odeslaného kroku, pokud jsem na posledním kroku, odešlu si všechna data ze session do presenteru a tam s nimi pracuji.

F.Vesely
Člen | 369
+
0
-

Ano, setValues() se vola automaticky a az pote se zavola onSuccess(). Ty vlastne chces mit vsechny kroky v jednom formulari v presenteru, ale v sablone to zase nechces a chces mit vice formularu. Udelej si control, tam mej x formularu a podle tlacitek si vykresluj ten, nebo ten.

kleinpetr
Člen | 480
+
0
-

Ok, tak jsem to předělal na jednotlivé formuláře, ale jak jsem říkal tak nevím kolik těch formulářů je, takže nemůžu jednotlivé komponenty vytvářet ručně, takže jsem to udělal asi takhle: v komponente mam promenou protected $steps = []; ve které jsou vytvořené objekty formulářů (kroků) a nyní vytvořím komponentu protected function createComponentStep(){return $this->steps[$this->session->currentStep]} a v šabloně potom {control step} to už tedy funguje, jenže když se pak formulář odešlě tak v metodě onSuccess() mu nastavím session->currentStep++; a zde je zase problém, protože nejprve se vytvoří komponenta a až potom se zavolá onSuccess(), tudíž se mi nevykreslí komponenta další, ale zůstane ta stejná. Jak by se to dalo řešit ? tedy kromě $this->redirect('this') :D díky

Editoval kleinpetr (7. 4. 2015 16:48)

greeny
Člen | 405
+
+3
-
kleinpetr
Člen | 480
+
0
-

Super ! díky moc, sice mi na mě phpStorm řve že očekával \Nette\ComponentModel\IContainer a dostal callable což je divný :) ale funguje