Validace prvku formuláře před jeho odesláním

jedlicka
Člen | 61
+
0
-

Ahoj,

měl bych dotaz, jak udělat validaci ještě před odesláním formuláře (Submit).

Mám ve formuláři např. textový input (třeba kód zboží) a po zadání nějakého textu bude okamžitě validovat (zjišťovat), že už daný text (kód zboží) v DB neexistuje. Jde mi o to, aby uživatel nevyplnil celý formulář, a až při jeho odeslání mu validace řekli, že pod zadaným kódem už zboží existuje, takže to vyplnil zbytečně.

Díky za každou radu, jak toto udělat.

Martin

MajklNajt
Člen | 470
+
0
-

Ahoj, na toto si budeš musieť napísať vlastnú obsluhu, t.j. navesit napr. na onchange event ajaxovú požiadavku na nejaký signál (handleNieco), v ktorom zistíš existenciu, a príp. vrátiš response s chybou

Toanir
Člen | 57
+
+1
-

Ahoj,

Jen dodám že Nette formuláře data do vrací zpět do fieldů, pokud v obsluze neprovedeš přesměrování. Můžeš si třeba vyzkoušet odeslat formulář, na kterej nenavěsíš onSuccess. Po odeslání formuláře bys měl vidět data v inputech přesně, jak jsi je vyplnil.

Myslím že kontrolu existence kódu by se dala řešit následovně


class ProductPresenter {

  public function actionNew() {
    $productForm = $this['productForm'];

    $productForm->onSubmit[] = function($form, $values) {
      if($this->productService->codeExists($values['code']) {
        $form['code']->addError('Produkt s tímto kódem již existuje');
      }
    };
    $productForm->onSuccess[] = function($form, $values) { /* ulož nový produkt */ };
  }

  public function actionEdit(string $productCode) {
    $productForm = $this['productForm'];

    $productForm->onSubmit[] = function($form, $values) use ($productCode){
      if($productCode !== $values['code'] && $this->productService->codeExists($values['code']) {
        $form['code']->addError('Jiný produkt s tímto kódem již existuje');
      }
    };
    $productForm->onSuccess[] = function($form, $values) { /* aktualizuj produkt $productCode */ };
  }

  public function createComponentProductForm() {
    $form = new Form();
    $form->addText('code');
    $form->addText('title');
    $form->addSubmit('Uložit');

    return $form;
  }

}

Když formulář obsahuje chyby, neměl by se provést onSuccess callback a v tom případě bys měl mít vyhráno, kdy ti hodnoty zůstanou ve formuláři

MajklNajt
Člen | 470
+
0
-

@Toanir tiež riešenie, zrejme aj elegantnejšie, no môže nastať use-case, kedy bude mať vo formulári nepovinné polia a pri zadaní kódu a nejaké onchange submitu mu to padne do success, ale ako hovorím, záleží od druhu formulára

Šaman
Člen | 2632
+
0
-

Já to pochopil tak, že pokud už daný prvek v db existuje, vůbec není potřeba ten formulář vyplňovat (dejme tomu chci vložit knihu, ale pokud zadám ISBN a o už v db je, pak vůbec nic vyplňovat nebudu).
V takovém případě je řešením opravdu jen ajaxové volání nějaké handle… metody. Anebo bez js dvoustupňový formulář: zadám ISBN a odešlu, následně se mi buď předvyplní inputy záznamem z db (editační formulář), nebo zůstanou prázdné (vytvářecí formulář).

Editoval Šaman (23. 4. 2020 19:19)

jedlicka
Člen | 61
+
0
-

@Toanir Díky moc, tohle řešení se mi ještě bude hodit. ;-)
@Šaman Ano, přesně tak jsem to myslel. Ten ajax mě napadl, jen jsem nevěděl, zda to nelze udělat nějak elegantně rovnou pomocí validací v nette formuláři.

Díky moc všem.

Toanir
Člen | 57
+
0
-

Svůj příklad vnímám jako takovej baseline v rámci standardních možností poskytnutých od Nette. Určitě, kdybych měl spoustu volnýho času (haha), bych se šťoural v možnostech jak zpříjemnit UX například předejitím přenačtení stránky.

Nejjednodušśí se imho nabízí pomocí naja nebo jiných ajaxových možností odeslat formulář ajaxem a při chybě ho překreslit.

Kdybych měl ještě víc času se v tom šourat, pořádně bych nastudoval možnosti netteForms.js, jestli nemáme k dispozici třeba nějaký validování při změně hodnoty / při ztrátě focusu fieldu

Jestli na něco přijdete, určitě se prosím podělte :)
(( je možný že je to v dokumentaci, do tý teď nekoukám protože „jen“ prokrastinuju v práci zatímco čekám až mi doběhnou testy :P ))

Kamil Valenta
Člen | 752
+
0
-

Vyhovovat by mohl i dvoukrokový formulář, kdy v prvním kroku mám jen input na číslo zboží a v druhém kroku dostanu buď prázdný form na insert, nebo vyplněný na edit.
Mohlo by to být efektivnější, pokud např. číslo zboží nemá pevný počet znaků a nebylo by úplně zřejmé, kdy XHR vykonat. Navěšovat to na opuštění inputu se mi zdá matoucí.

Toanir
Člen | 57
+
0
-

<filosofický-offtopic>
Dvoukrokový formuláře / případy užití podle mě nejsou vůbec cash money by default. Jednak nejsou svižný a druhak se musíš vypořádat například se situací, kdy chtějí dva uživatele provést první krok se stejným kódem. Osobně se snažím více-krokým řešením vyhýbat ale taky můžou mít někdy opodstatnění.

Kdy validovat (jestli při změně nebo při focusOut) je imho otázka návrhu / vkusu. Myslím že i frontendový frameworky nechávají volbu na programátorovi s rozumným defaultním nastavením. Teď vycházím ze znalosti stařičkého angularjs, kde jsem se s tím právě setkal (anebo si prd pamatuju :P).

Myslím že oba přístupy mají svoje místa použití a teď od oka s amatérským citem pro UX bych onChange dal s drobným debouncem právě na validaci použitelnosti takovýho kódu, jako se bavíme v tomto tématu.

Naopak, kdybych dělal heslo a ověření hesla, validaci ověření bych dal na focusOut, aby se chyba „hesla se neshodují“ nezobrazovala v průběhu psaní. Případně bych na tu kontrolu navěsil i onChange a zobrazoval zelenou fajfku když se hesla shodují.

Tak by se to líbilo mě ale třeba by mi skuteční UXáci vysvětlili, že to je úplně jinak :P
</filosofický-offtopic>

Editoval Toanir (27. 4. 2020 12:44)