jednoduchý setValidationScope(false)

MC
Člen | 7
+
0
-

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.

nightfish
Člen | 518
+
+1
-

Dokumentace je v tomto ohledu neaktuální. Ostatně PHP ti samo píše, že must be iterable or null, boolean given – takže místo false napiš [] a bude to fungovat.

EDIT: opraveno dle komentáře David Matějky

Editoval nightfish (28. 6. 2019 12:08)

David Matějka
Moderator | 6445
+
+2
-

správná náhrada za false je prázdné pole – []

MajklNajt
Člen | 498
+
-2
-

David Matějka napsal(a):

správná náhrada za false je prázdné pole – []

dovolím si nesúhlasiť, $scope je nullable, s null počíta aj Nette\Forms\Container::validate, takže nevidím dôvod, prečo by bolo správnejšie používať prázdne pole namiesto null :)

David Matějka
Moderator | 6445
+
+2
-

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

  • null a true byly ekvivaletní hodnoty, nyní se používá null
  • [] a false byly ekvivaletní hodnoty, nyní se používá []

a když se koukneš do validate, tak pokud obdrží null, tak validuje všechny controly

MajklNajt
Člen | 498
+
0
-

@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
+
+1
-

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.