Validace formuláře při výběru datumu
- Rndoom04
- Člen | 75
Zdravím všechny,
přicházím s dalším dotazem, který Vy zkušenější vyřešení
raz, dva.
Mám formulář, kde mimo jiné uživatel vyplňuje datum. Potřebuji ale, aby si mohl vybrat datum např. mezi 1.5.xxxx a 20.7.xxxx.
Mám tedy pro zjednodušení:
$form->addText("datum","Datum")
->setAttribute("class","form-control")
->setRequired(true);
Kalendář se zobrazuje skrze jQuery, kde si správce může zadat datumy v tomto povoleném rozmezí, které jsou už obsazené. Dám příklad (není to reálné). Člověk A pořádá něco. To něco je přístupné od 1.5.xxxx do 20.7.xxxx (každý rok). Pokud si někdo rezervuje nějaký z těchto termínů, obsadí se (v administraci přidá datum, který je obsazený), protože může objednávku někdo udělat i po telefonu. Tento datum nepůjde z kalendáře vybrat (o to se stará jQuery – tahá datumy z json souboru) – přidávám screen (https://ibb.co/mztB7yX) a pak je validace i ze strany PHP. Avšak rád bych, aby staticky nebylo možné vybírat datumy před spuštěním a po ukončení.
Zkoušel jsem validaci jako u čísel, ale bezúspěšně, naprostá ignorace, jako by tam žádné pravidlo nebylo. Asi takto:
$range1 = strtotime("1.5.2020");
$range2 = strtotime("20.7.2020");
$form->addText("datum","Datum")
->setAttribute("class","form-control")
->setRequired(true)
->addRule(Form::RANGE, 'Nějaký text bla bla',[(int)$range1,(int)$range2]);
Může mě někdo pošťouchnout, jak přidat takovou validaci? :) Děkuji za každou radu. :)
Edit: Zkoušel jsem do toho json souboru přidat i datumy před spuštěním a po ukončení (aby nešly vybírat) a funguje to. Ale lepší řešení by bylo přes tu validaci si myslím. :)
Editoval Rndoom04 (11. 5. 2020 2:57)
- Šaman
- Člen | 2667
Přes událost onValidate
. https://doc.nette.org/…s/validation#…
Chybu i tady můžeš přidat ke konkrétnímu poli. Máš k dispozici hodnoty
celého formu a můžeš si vytvořit libovolně složitou podmínku.
A nezapomeň, že ti input datum
vrací text. Takže ani to
addRule
co jsi zkoušel nedává smysl.
- Rndoom04
- Člen | 75
Šaman napsal(a):
Přes událost
onValidate
. https://doc.nette.org/…s/validation#…
Chybu i tady můžeš přidat ke konkrétnímu poli. Máš k dispozici hodnoty celého formu a můžeš si vytvořit libovolně složitou podmínku.A nezapomeň, že ti input
datum
vrací text. Takže ani toaddRule
co jsi zkoušel nedává smysl.
Právě vím, že to vrací text, proto jsem už spíš jen zkoušel, co to „zkousne“. Sekci, co jsi mi poslal, jsem asi nějakým způsobem přeskočil, protože ji vidím poprvé. Je to přesně to, co hledám. Moc děkuji! :)
- Polki
- Člen | 553
@Rndoom04 Taky mě to nebavilo řešit. :) Tak používám tuhle knihovnu. Pokud používáš Nette3, tak ve verzi 3.0.2 má na toto přímo Rule.
tedy stáhneš pomocí composeru, zaregistruješ podle návodu v readme a použití třeba:
$dateRange = [
\Nette\Utils\DateTime::fromParts(2020, 5, 1), // minimální datum "1.5.2020"
\Nette\Utils\DateTime::fromParts(2020, 7, 20) // maximální datum "20.7.2020"
];
$form = new \AJAXimple\Forms\Form();
$form->addDate('datum', 'Zadejte datum:')
->addRule(\AJAXimple\Forms\Form::DATE_RANGE, 'Špatný rozsah data', $dateRange);
$form->addSubmit('submit', 'odeslat');
$form->onSuccess[] = [$this, 'success'];
return $form;
No a proč takto? Protože to, co je v metodě onValidate, tak se provede vždy. A ty někdy budeš chtít validaci vypnout, například v případech, kdy provedeš nějakou akci po stisku tlačítka, ale tato akce nesmí spadnout na nevalidních polích. (V praxi se to používalo u Kdyby/FormsReplicator pro tlačítka na přidání a smazání řádku.) No a v takovém případě se validace přidané pomocí ->addRule() neprovedou, ale metody v callbacku validate ano. Takže by se ti mohlo stát že ti nepůjde akce provést protože nemáš třeba vyplněné datum ve správném rozsahu i když ta akce se toho vůbec netýká.
Tedy do události onValidate by se mělo dávat vždy jen to, co víš, že využiješ opravdu VŽDY.
No a jako bonus ti tato knihovna z toho formulářového pole vždy vrátí
buď NULL, pokud je špatně zadaná hodnota, nebo objekt třídy
\Nette\Utils\DateTime, čímž s tím pak pracuješ jako s datem. Dokonce
i například NetteDatabase přijmá DateTime object, takže na ukládání do
DB se nic nemění. Pokud používáš NextrasORM třeba, tak je potřeba
akorát přidat
\DateTimeImmutable::createFromMutable($form->values->datum);
Ale o to se může krásně postarat setter třídy, kterou předáš
v formulářové metodě ->setMappedType(‚classname‘);
Editoval Polki (12. 5. 2020 11:01)