jednoduchý setValidationScope(false)

- MC
 - Člen | 7
 
Ahoj,
používám 3.0 nette a vytvářím formulář v komponentě dle dokumentace a chci vypnout validaci viz. níže …
    protected function createComponentStep2()
    {	// Nette\Application\UI\Form
        $form = $this->formFactory->create();
        $form->addText('name')->setRequired();
        $details = $form->addContainer('details');
        $details->addInteger('age')->setRequired('age');
        $details->addInteger('age2')->setRequired('age2');
        $form->addSubmit('send1'); // Validates the whole form
        $form->addSubmit('send2')->setValidationScope(false); // Validates nothing
        $form->addSubmit('send3')->setValidationScope([$form['name']]); // Validates only 'name' input
        $form->addSubmit('send4')->setValidationScope([$form['details']['age']]); // Validates only 'age' input
        $form->addSubmit('send5')->setValidationScope([$form['details']]); // Validates 'details' container
        return $form;
    }
Nette hlásí chybu – dle dokumentace předávám false: Argument 1 passed to Nette\Forms\Controls\SubmitButton::setValidationScope() must be iterable or null, boolean given
Ještě přidávám setValidationScope z Nette\Forms\Controls\SubmitButton níže …
	/**
	 * Sets the validation scope. Clicking the button validates only the controls within the specified scope.
	 * @return static
	 */
	public function setValidationScope(?iterable $scope)
	{
		if ($scope === null || $scope === true) {
			$this->validationScope = null;
		} else {
			$this->validationScope = [];
			foreach ($scope ?: [] as $control) {
				if (!$control instanceof Nette\Forms\Container && !$control instanceof Nette\Forms\IControl) {
					throw new Nette\InvalidArgumentException('Validation scope accepts only Nette\Forms\Container or Nette\Forms\IControl instances.');
				}
				$this->validationScope[] = $control;
			}
		}
		return $this;
	}
Co jsem prosím přehlédl? Děkuju za pomoc.

- David Matějka
 - Moderator | 6445
 
null je implicitní hodnota, která znamená „validuj vše“.
oproti tomu false, které znamená nevaliduj nic, se interně
převádělo na prázdné pole, viz:
foreach ($scope ?: [] as $control) {
tedy
nullatruebyly ekvivaletní hodnoty, nyní se používánull[]afalsebyly ekvivaletní hodnoty, nyní se používá[]
a když se koukneš do validate, tak pokud obdrží null, tak validuje všechny controly

- MajklNajt
 - Člen | 518
 
@DavidMatějka ospravedlňujem sa, v rýchlosti som sa nepozrel až
do validate a funguje to samozrejme tak, ako hovoríš…
napriek tomu mi toto chovanie príde trošku nepredvídateľné, pretože:
setValidationScope([$form['details']['age']]); // Validates only 'age' input
setValidationScope([$form['details']]); // Validates 'details' container
takže by som prirodzene očakával, že [] bude validovať
všetko, a správa sa to presne opačne…
takisto by som nečakal, že null je ekvivalentom
true, pretože aj napr. $foo ?: $bar; vráti
$foo v prípade, že je false alebo
null, ale v prípade true vráti
$bar…
ale určite má tento prístup svoj dôvod – to len na vysvetlenie, prečo
som ťa (nesprávne) opravil a prečo si viacero ľudí môže chovanie
setValidationScope takisto (nesprávne) interpretovať

- Martk
 - Člen | 661
 
imo to funguje předvídatelně. Předtím jsem nevěděl co tam házet, když se tam míchalo true, false, null, pole
Házíš tam teď pole controlů, které chceš validovat. Hodíš tam
$form['details']['age'], bude se ti validovat jen control age,
hodíš tam $form['details'], bude se ti validovat kontejner
(logicky včetně těch inputů), hodíš tam [] bude se ti
validovat nic. A většinou null ve funkci aktivuje výchozí chování tzn.
validuj vše.