Validace prvků addConditionOn (křížové validační pravidlo?)

ragulin
Člen | 58
+
0
-

Ahoj,

Mám dva prvky formuláře a chtěl bych je kontrolovat mezi sebou, zda je jeden vyplněný, tak jednomu nastavit něco a naopak. Problém je, že pokud nastavím "addConditionOn tomu prvnímu, samozřejmě mi vypíše, že prvek který tam je, ještě neexistuje:

$form->addText('cislo')
	 ->addConditionOn($form['string'], form::FILLED, false)
 	 ->setRequired('error')
$form->addText('string')
	 ->addConditionOn($form['cislo'], form::FILLED,false)
	 ->setRequired('error')

Ve výsledku jde o to, aby v případě, že je vyplněné číslo, nebyl povinný string a naopak pokud je vyplněný string, nebylo povinné číslo. Jde to nějak jednoduše, nebo musím jít do vlastní validace (lambda fce z doku) / js validace?

Zároveň si hraju i s onValidate pravidlem a zkouším to, tak třeba než někdo odpoví, něco vymyslím sám. Ale za nějakou radu nebo popostrčení bych byl vděčný.

Edit:
Tak malý edit, pokračuji tímto stylem, ale nevím jak v funkci validateForm nastavit elementu formu, že má být required pokud…

{
$form = new Form
$form->addText('cislo')
	 ->setRequired('error')
$form->addText('string')
	 ->setRequired('error')
$form->onValidate[] = [$this, 'validateForm']
return $form;
}

public function validateForm($form) {
	if ($form['cislo']->value == null) {
		$form['string']->setRequired();  /*Zde dostávám hlášku, že setRequired není známá metoda..*/
	}
}

Editoval ragulin (24. 4. 2019 9:11)

ali
Člen | 342
+
+2
-
$form->addText('cislo');
$form->addText('string');

$form['cislo']->addConditionOn($form['string'], ..);
$form['string']->addConditionOn($form['cislo'], ..);
ragulin
Člen | 58
+
0
-

edit:
Děkuji, ale tohle nefunguje.

Zkouším něco takového..

$string = $form->addText('string');
if ($form['cislo']->value === null) {
    $string->setRequired();
}

Editoval ragulin (24. 4. 2019 10:15)

David Matějka
Moderator | 6445
+
+1
-

to, co píše @ali je správně. co znamená, že „tohle nefunguje“?

ragulin
Člen | 58
+
-1
-

David Matějka napsal(a):

to, co píše @ali je správně. co znamená, že „tohle nefunguje“?

Ahoj,
Problém byl v tom, že pro ten případ, co používá Ali, musí to být definované takto:

$string = $form->addText('string');
$cislo = $form->addText('cislo');

 $string->addConditionOn($cislo, Form::BLANK, true)->setRequired('strin test');
 $cislo->addConditionOn($string, Form::BLANK, true)->setRequired('cislo test');

Teď to funguje, trvalo mi chvilku než jsem k tomu došel, akorát jsem chtěl napsat comment. Ten $form->addText musí prostě být v proměnné jinak to vypíše – Method ‚addConditionOn‘ not found in Nette\ComponentModel etc –

Editoval ragulin (24. 4. 2019 10:43)

ali
Člen | 342
+
0
-

@ragulin co mas za verzi Nette/Forms a PHP?

Editoval ali (24. 4. 2019 11:21)

David Matějka
Moderator | 6445
+
0
-

@ragulin myslím, že ti to jen hlásilo IDE, které nebylo schopné pomocí statické analýzy rozpoznat správný typ. pokud bys to ale spustil, tak to bude fungovat.

ale jak si to napsal, tak je to samozřejmě taky možné (já to taky tak píšu, právě aby fungovalo napovídaní v IDE)

ragulin
Člen | 58
+
0
-

David Matějka napsal(a):

@ragulin myslím, že ti to jen hlásilo IDE, které nebylo schopné pomocí statické analýzy rozpoznat správný typ. pokud bys to ale spustil, tak to bude fungovat.

ale jak si to napsal, tak je to samozřejmě taky možné (já to taky tak píšu, právě aby fungovalo napovídaní v IDE)

Aha, no to je možné, nezkoušel jsem to spustit v ten moment, ale koukám níže v kódu je od kolegy commitnuto něco podobného s hláškou IDE také a funguje to, takže to bude asi určitě schůdné oběma způsoby. Děkuji za vysvětlení a radu

Editoval ragulin (24. 4. 2019 11:32)

pista5
Člen | 60
+
0
-

Ahoj,
zkoušel jsem tuto křížovou validaci a nefunguje mi…

Jakmile ji do formulaře vložím a odešlu ho bez obou vyplněných políček, proběhne mi reload stránky (onSuccess neproběhne) a ostatní políčka formuláře jsou vyplněna (jako pro Erroru), ale žádný Error se nevypíše…

<?php

$form = new Form;

        $form->addText('nazev', 'Název reklamy')
            ->setRequired('Zadejte název reklamy')
            ->setHtmlAttribute('maxlength', 50)
            ->setHtmlAttribute('class', 'form-control form-control-sm');
        $form->addSelect('pozice', 'Pozice reklamy', [1 => 'nahoře', 'dole'])
            ->setPrompt('--- vyberte ---')
            ->setRequired('Vyberte pozici reklamy (nahoře/dole)')
            ->setHtmlAttribute('class', 'form-control form-control-sm');
        $form->addSelect('typ', 'Typ reklamy', [1 => 'soubor', 'skript'])
            ->setPrompt('--- vyberte ---')
            ->setRequired('Vyberte typ reklamy (soubor/skript)')
            ->setHtmlAttribute('class', 'form-control form-control-sm');
        $form->addUpload('soubor', 'Soubor')
            ->setHtmlAttribute('class', 'form-control form-control-sm')
            ->addRule(Form::MIME_TYPE, 'Soubor musí být ve formátu JPEG, GIF nebo PNG', ['image/jpeg', 'image/gif', 'image/png'])
            ->addConditionOn($form['typ'], Form::EQUAL, '1')
                ->setRequired('Vyberte soubor s reklamou');
        $form->addText('odkaz', 'URL odkaz')
            ->setHtmlAttribute('maxlength', 255)
            ->setHtmlAttribute('class', 'form-control form-control-sm')
            ->addConditionOn($form['typ'], Form::EQUAL, '1')
                ->setRequired('Zadejte URL odkaz k banneru');
        $form->addTextArea('skript', 'Skript')
            ->setHtmlAttribute('class', 'form-control form-control-sm mb-3')
            ->addConditionOn($form['typ'], Form::EQUAL, '2')
                ->setRequired('Zadejte skript reklamy');
        $zobrazeni = $form->addInteger('zobrazeni', 'Počet zobrazení')
            ->setHtmlAttribute('class', 'form-control form-control-sm');
        $kliknuti = $form->addInteger('kliknuti', 'Počet kliknuti')
            ->setHtmlAttribute('class', 'form-control form-control-sm');
        $form->addHidden('id', '0');

        $zobrazeni->addConditionOn($form['typ'], Form::EQUAL, '2')->setRequired('Zadejte počet zobrazení');
        $zobrazeni->addConditionOn($kliknuti, Form::BLANK)->setRequired('Zadejte počet zobrazení nebo počet kliknutí');
        $kliknuti->addConditionOn($zobrazeni, Form::BLANK)->setRequired('Zadejte počet zobrazení nebo počet kliknutí');

        $form->addSubmit('send', 'Uložit')
            ->setHtmlAttribute('class', 'btn btn-sm btn-success');
        $form->addSubmit('zpet', 'Zpět')
            ->setHtmlAttribute('class', 'btn btn-sm btn-info')
            ->setValidationScope([])
            ->onClick[] = function(): void {
            $this->redirect('Reklama:');
            };

        $form->onSuccess[] = [$this, 'reklamaFormSucceeded'];

        return $form;
?>
David Matějka
Moderator | 6445
+
0
-

a jak vypisuješ v šabloně formulář, respektive jeho errory?

David Grudl
Nette Core | 8082
+
0
-

Zkus master větev nette/forms včetně netteForms.js

pista5
Člen | 60
+
0
-

V šabloně jsem si zatím s manuálním vykreslováním nehrál a vykresluji ho pres {control Form}

pista5
Člen | 60
+
0
-

„master větev nette/forms včetně netteForms.js“

Muzes byt prosim trochu konkretnejsi… jsem v Nette relativni zacatecnik :))

Nacitam „netteForms.min.js“ a v composer.jsom mam
„nette/forms“: „^3.0“

Edit:
Tak jsem si stahnul forms-master a nakopiroval do slozky vendor/nette/ (misto puvodni forms) a umistil jsem z teto verze do www/js i netteForms.js a zacalo to fungovat!!!

DIKY moc za radu.

Jen dotaz… mohl jsem pro update pouzit i „composer require nette/forms“??
Je muj update tez spravny?

Editoval pista5 (5. 6. 2020 20:12)

David Grudl
Nette Core | 8082
+
0
-

Dá se to udělat i přes composer, dáš tam "nette/forms": "dev-master".

Novou verzi vydám as soon as, takže jsem rád za ověření funkčnosti :)