Formular sa nevynuluje po odoslani ajaxom/naja

ikoon
Člen | 80
+
0
-

Zdravim

Ospravedlnujem sa, nemam tu pri sebe teraz zdrojaky, tak len tak z hlavy…

Mam problem, mam formular (v snippete) s dvomi comboboxami + 1 hidden + tlacitko.
V actionNieco vytiahnemz DB info, ktore potrebujem do formulara, dam to do premennej presentera.
V dalsej metode formular, naplnim hodnotami. Doteraz vsetko OK.
Po kliknuti na tlacitko sa ajaxom odosle formular, ten spracujem a poslem redraw na snippet a snippetarea. Problem je, ze formular sa nevynuluje a hidden input nema ziadnu hodnotu. Ak v submitted metode dam $form->reset() tak sa formular vynuluje, nastavia comboboxy, ale hidden je prazdny.

Kde je problem?

ikoon
Člen | 80
+
0
-

Mam tam taketo nieco:

    public function actionDetail($id) {
        $this->product = $this->shopMan->getProduct($id);
    }

    protected function createComponentAddItem() {
        ...
        $form = new Form;
        $form->getElementPrototype()->class('ajax');
        $form->addSelect('size', null, $sizes)
            ->setRequired();
        $form->addSelect('count', null, $counts)
            ->setRequired();
        $form->addHidden('kod', $this->product->kod);
        $form->addSubmit('add');
        $form->onSuccess[] = [$this, 'addItemSubmitted'];
        return $form;
     }

     public function addItemSubmitted(Form $form) {
        $values = $form->getValues();
        ...
        $form->setValues([], true);
        $this->redrawControl('snipArea');
        $this->redrawControl('snipCart');
        $this->redrawControl('snipAddItem');
    }

{form addItem}
  <div class="custom-select" style="width:110px; float: left;">
    <select n:name="size" style="display: initial"></select>
  </div>
  <div class="custom-select" style="width:110px; float: left; margin-left: 5px;">
    <select n:name="count" style="display: initial"></select>
  </div>
  <input n:name="kod">
  <button n:name="add" type="submit" class="button-detail-kosik"><span>Vložiť do košíka</span></button>
{/form}

Pri prvom nacitani stranky Detail je vsetko OK, ale ked submitnem formular, tak sa nenastavi to hidden policko. Nejde to ani pri ajaxe (naja), ani bez ajaxu. Po submite je hidden policko prazdne.

Netusim v com to je, nikdy sa mi to nestalo.

Editoval ikoon (27. 5. 22:12)

m.brecher
Generous Backer | 814
+
+1
-

@ikoon

Problem je, ze formular sa nevynuluje

To je správná funkce Nette formulářů, musíš ručně formulář vynulovat.

Ak v submitted metode dam $form->reset() tak sa formular vynuluje, nastavia comboboxy, ale hidden je prazdny.

Ano, to je správně, $form->reset() vynuluje celý formulář včetně hidden prvku.

Standardně lidi po zpracování formuláře a uložení dat někam přesměrují, což řeší většinu problémů. Ty bys měl přesměrovat na ‚this‘, protože chceš pokračovat ve vkládání dat formulářem.

Nějak takhle:

public function addItemSubmitted(Form $form) {
        $values = $form->getValues();
        ...
        $form->setValues([], true);
        $this->redirect('this');
    }

Naja ajaxový redirect podporuje a vyřešíš problémy s nulováním formuláře. Navíc redirect je ověřený design pattern pro ukončení zpracování submitnutého formuláře.

Budeš ale muset po redirectu nějak dořešit překreslení košíku, košík můžeš překreslovat v dané akci vždy ve fázi render:

    public function renderDetail() {
        $this->redrawControl('snipCart');
    }
Zdeno1981
Člen | 115
+
0
-

@ikoon,

jde to udělat tak, že po odelsání formuláře ajaxem si znova naplniš ten hidden input


// reset formuláře
$form->reset();

// naplnění hidden inputu
$hiddenInputKod = $form['kod'];
if ($hiddenInputKod instanceof BaseControl) {
	$hiddenInputKod->setDefaultValue($this->product->kod);
}

pak překreslíš formulář

Editoval Zdeno1981 (28. 5. 13:00)

Kamil Valenta
Člen | 783
+
0
-

m.brecher napsal(a):

Ty bys měl přesměrovat na ‚this‘, protože chceš pokračovat ve vkládání dat formulářem.

Nějak takhle:

public function addItemSubmitted(Form $form) {
        $values = $form->getValues();
        ...
        $form->setValues([], true);
        $this->redirect('this');
    }

Jaký dává smysl odesílat form ajaxem, aby pak udělal redirect?

mystik
Člen | 298
+
+2
-

@KamilValenta Aby se pri neuspesnem odeslani (selhani validace) prekreslil jen snippet s formularem

m.brecher
Generous Backer | 814
+
+1
-

@KamilValenta, @ikoon

Jaký dává smysl odesílat form ajaxem, aby pak udělal redirect?

Měl jsem na mysli ajaxový redirect, kdy Nette v payload posílá url pro přesměrování a Naja pošle nový ajaxový GET požadavek na toto url. Tím se znovu vykoná celý request od začátku, ale stránka se znovu celá nestahuje. Je ale potřeba ještě dát pokyn k překreslení snippetu s formulářem – to jsem zapomněl dodat, nějak takhle:

    public function renderDetail(): void
    {
        if($this->isAjax()){
            $this->redrawControl('snipAddItem');  // snippet s formulářem
			$this->redrawControl('snipCart');   //  snippet s košíkem
        }
    }

Formulář by mohl pracovat i bez ajaxu, ale s ajaxem je to o něco příjemnější – stránka neroluje

ikoon
Člen | 80
+
0
-

Dakujem vsetkym, uz mi to chodi :)