Validační pravidlo závislé na hodnotě jiného inputu

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

Ahoj, je možné vytvořit pravidlo, které je závislé na číselné hodnotě jiného inputu?
Př. inputCelkem: zadejte počet účastníků; inputDospeli: zadejte počet dospělých osob.
A dospělých osob smí být maximálně tolik, kolik je celkem :)

Příklad je vykonstruovaný, tak prosím neřešte jestli má logiku, nebo jestli by se nedalo ptát jinak.. V reálu jde o možnosti připojištění, které však mají strop omezený podle hodnoty základní ceny. Díky.

BigCharlie
Člen | 283
+
0
-

Budeš si muset s velkou pravděpodobností dopsat vlastní javascriptový validátor. Tady v tom případě totiž nejspíš nevystačíš s předdefinovanými pravidly.

UPDATE: teď ještě koukám, že v dokumentaci, kam jsem odkázal, chybí zmínka o metodě addConditionOn, která umožňujě „navěsit“ pravidla na nějaký jiný prvek.

Editoval BigCharlie (29. 3. 2010 11:36)

iguana007
Člen | 970
+
0
-

pravidla jdou definovat i takto:

function myValidator($control, $arg)
{
	return ((int) $control->value % $arg) === 0;
}
$form = new Form;
$subform->addText('name','Políčko')
      ->addRule('myValidator', 'chyba', 8);
iguana007
Člen | 970
+
0
-

Nebo jak píše BigCharlie:

	->addConditionOn($form['promo'], Form::EQUAL, TRUE)
		->addRule(Form::FILLED, 'Zadejte email abychom vam mohli posilat spam')
	->endCondition()
	->addCondition(Form::FILLED)
		->addRule(Form::EMAIL, "E-mailova \n adresa neni platna");
bazo
Člen | 620
+
0
-

skusil by som nieco taketo

$form->addText('inputDospeli', 'Dospeli')->addConditionOn($form['inputCelkem'], Form::Range, array(0, $form['inputCelkem']->getValue()))->addRule(...);

ale este to treba znegovat, aby sa pravidlo spustilo ak inputDospeli mimo rozsah

Šaman
Člen | 2635
+
0
-

Zkouším to takhle:

<?php
$form->addText('nezavislyInput', 'Základní částka')->setOption('description', 'Kč')
  ->setDefaultValue(0) // todo: nacist ze v sessions
  ->addRule(Form::FILLED, 'Je nutné vyplnit částku.')
  ->addRule(Form::INTEGER, 'Částka smí obsahovat jen číslice.');

$form->addText('zavislyInput')
  ->setDefaultValue(0)
  ->addRule(Form::INTEGER, 'Částka smí obsahovat jen číslice.')
  ->addRule(Form::RANGE, 'Castka smi byt v rozsahu od %d do %d', array(0, $form['nezavislyInput']->getValue()));
?>

Ale bohužel se mi nedaří pomocí $form['nezavislyInput']->getValue() vytáhnout aktuální hodnotu – vrací mi to tu, která je nastavena (setValue() nebo SetDefaultValue()).

Máte někdo tušení v čem je chyba, případně jestli tudy cesta vůbec povede?

vkuzel
Člen | 15
+
0
-

Šaman napsal(a):

Zkouším to takhle:

<?php
$form->addText('nezavislyInput', 'Základní částka')->setOption('description', 'Kč')
  ->setDefaultValue(0) // todo: nacist ze v sessions
  ->addRule(Form::FILLED, 'Je nutné vyplnit částku.')
  ->addRule(Form::INTEGER, 'Částka smí obsahovat jen číslice.');

$form->addText('zavislyInput')
  ->setDefaultValue(0)
  ->addRule(Form::INTEGER, 'Částka smí obsahovat jen číslice.')
  ->addRule(Form::RANGE, 'Castka smi byt v rozsahu od %d do %d', array(0, $form['nezavislyInput']->getValue()));
?>

Ale bohužel se mi nedaří pomocí $form['nezavislyInput']->getValue() vytáhnout aktuální hodnotu – vrací mi to tu, která je nastavena (setValue() nebo SetDefaultValue()).

Máte někdo tušení v čem je chyba, případně jestli tudy cesta vůbec povede?

Ahoj,

tady je problém v tom, že ta hodnota se do validačního pravidla předá v době vytvoření/definice toho pravidla, nikoli v době validace hodnot po odeslání formuláře.

Tzn.:

  1. vytvoříš input, kterému nastavíš pravidlo RANGE s hodnotou, která je aktuálně v $form[‚nezavislyInput‘]->getValue() – tzn. hodnota která tam je v době vytváření pravidla.
  2. zobrazíš formulář, vyplníš něco do něj a odešleš ho
  3. tady se validují data formuláře, ale nevaliduje se proti vyplněné hodnotě v nezavislyInput, ale proti té původní hodnotě, která tam byla v době vytváření pravidla.

Toť problém. Tak jak je validace navržená teď mně nenapadá žádné čisté řešení tohoto problému. Teda nenapadá mně ani žádné jiné navržení validace, aby šly vkládat aktuálně vyplněné hodnoty formulářů a fungovalo to i v js.

Velmi nečisté řešení, které mě napadá je:

Máš onSubmit handler, ve kterém zpracováváš hodnoty formuláře. Do tohoto handleru předáváš jako calback formulář třeba v proměnné $form. No a ten nápad je takový, že v této metodě přidáš požadovanému inputu ve formu validační pravidlo s hodnotu, kterou získáš z toho odeslaného formu.

<?php
$form['zavislyInput']->addRule(Form::RANGE, 'Neni v rozsahu', array(0, $form['nezavislyInput']->getValue()));
?>

Fungovat by to mělo, ale příjdeš tím o javascriptovou validaci. Asi bych se tomu vyvaroval a popřemýšlel bych nad tím, jestli ten formulář takhle validovat skutečně chci.

Šaman
Člen | 2635
+
0
-

Moc díky za analýzu, alespoň chápu, proč se mi chová getValue() jinak než jsem předpokládal.

Ale některá pravidla jsou přeci závislá na jiných inputech (např. přes ->addCondition(Form::FILLED), nebo podmínka EQUAL). K hodnotě mám přístup jak při JS validaci, tak po odeslání → nemám problém validovat si to sám, ale rád bych zachoval konzistentní přístup.

V rámci čistoty řešení to zatím vidím na redirect po každé změně (jednoho) nezávislého inputu (závislý je celý zbytek formuláře).

Pozn. Jak tak koukám do zdrojáků, neměl by být problém dopsat podmínku, že pokud je arg[0] instanceof FormControl (nebo TextBase), tak namísto hodnoty arg[0] vkládat arg[0]->getValue(), resp arg[0].value v JS. Problém je, že editovat nette je prasárna (myslím na locale:). Přidal bych si tedy vlastní pravidlo, ale nepřišel jsem na to, jak mu přiřadit JS validátor. Asi se v tomto případě na JS vyprdnu.