setValidationScope – validovat vše mimo některých

pista5
Člen | 39
+
0
-

Ahoj,
mam velky formular, ktery ma 2 odesilaci tlacitka… pri stisknuti prvniho se validuji pouze 3 polozky, jejich vycet dam do setValidationScope([x, y, z]).
Pri odeslani druhym potrebuji validovat vsechny ostatni polozky, mimo tech 3… vycet v setValidationScope by byl obrovsky…

Neni nejaky trik, jak validovat vsechny polozky mimo nekterych? Tj. negativni vycet polozek.

Editoval pista5 (19. 11. 2021 21:02)

Martk
Člen | 631
+
0
-

Budeš si muset vytvořit vlastní funkci, která to obrátí, tzn. něco jako

foreach ($form->getControls() as $control) {
	if (!in_array($control, $skip, true)) {
		$validationScope[] = $control;
	}
}
pista5
Člen | 39
+
0
-

Diky za namet, ale nejsem z toho uplne chytry :)))

Jak tuto funkci napojim na formular/submit tlacitko?

Martk
Člen | 631
+
+3
-
->setValidationScope(validationScopeReverse([$x, $y, $z]));

function validationScopeReverse(array $noValidate): array
{
	$scope = [];
	foreach ($form->getControls() as $control) {
		if (!in_array($control, $noValidate, true)) {
			$scope[] = $control;
		}
	}

	return $scope;
}
pista5
Člen | 39
+
0
-

Diky!

pista5
Člen | 39
+
0
-

@Martk Tak mam jeste jeden problem… v jednom formulari mam contributte/forms-multiplier, ktery timto neprojde…

$form->getControls() jeho polozky nevidi… muzes prosim poradit co s tim?

Editoval pista5 (16. 12. 2021 19:30)

Martk
Člen | 631
+
0
-

Zkusil bych nejdříve nastavit validationscope v onAnchor eventu

pista5
Člen | 39
+
0
-

Diky za tip, ale moc moudrý z toho nejsem… udelal jsem toto a v barDumpu v onAnchor data vidim… jak ale prosím zařídit, aby prošla validací?

protected function createComponentRezervaceForm(): Form
{
	$form = new Form;
	$form->getElementPrototype()->class[] = 'ajax';
	.....
	$form->addSubmit('send', 'Odeslat')
	->setValidationScope($this->validationScopeReverse([$form['x']], $form));

	$form->addSubmit('presun', 'Přesunout')
	->setValidationScope([$form['x'], $form['y'], $form['z']]);

	$form->onAnchor[] = function(Form $form): void
	{
		Debugger::barDump($form);
	};

	$form->onSuccess[] = function(Form $form, $values): void
    {
	...
	};

	return $form;
}

function validationScopeReverse(array $noValidate, Nette\Forms\Form $form): array {
	Debugger::barDump($form->getComponents());
    $scope = [];
    foreach ($form->getControls() as $control) {
		Debugger::barDump($control);
		if (!in_array($control, $noValidate, true)) {
            $scope[] = $control;
        }
    }
    return $scope;
}
Nette\Application\UI\Form:
components: (arrray)
...
'hoste' => Contributte\FormMultiplier\Multiplier
	...
	httpData: array
	0 => array
		'jmeno' => 'Jana'
		'prijmeni' => 'Test'
		'narozeni' => ''
Martk
Člen | 631
+
0
-

Metodu ->setValidationScope($this->validationScopeReverse([$form['x']], $form)); přesuneš do onAnchor, tzn.

z

$form->addSubmit('send', 'Odeslat')
	->setValidationScope($this->validationScopeReverse([$form['x']], $form));

$form->onAnchor[] = function(Form $form): void
{

};

na

$form->addSubmit('send', 'Odeslat');

$form->onAnchor[] = function(Form $form): void
{
	$form['send']->setValidationScope($this->validationScopeReverse([$form['x']], $form));
};
pista5
Člen | 39
+
0
-

Kdyz jsem ji presunul, skoncil jsem na tomto erroru, na nize uvedenem radku…

Component ‘multiplier_creator’ is not attached to ‘Nette\Forms\Form’

$ʟ_input = $_input = end($this->global->formsStack)["send"];
echo $ʟ_input->getControlPart()->addAttributes(['value' => null])->attributes() /* line 395 */;
pista5
Člen | 39
+
0
-

@Martk Ahoj, nenapada Te prosim jak to vyresit?

Marek Bartoš
Nette Blogger | 689
+
0
-

Zkus přidat tu část kódu s multiplierem, není patrné kdy ho do formuláře přidáváš a jakým způsobem

pista5
Člen | 39
+
0
-
final class RezervaceForm extends Control
{
	public function create(): Form
  	{
		$form = new Form;
		$form->getElementPrototype()->class[] = 'ajax';
		.....
		$form->addMultiplier('hoste', function(Nette\Forms\Container $container, Form $form) {
	    	$container->addText('jmeno', 'Jméno');
		....
	    }, 0, 1);
		.....
		$form->addSubmit('send', 'Odeslat');

		$form->addSubmit('presun', 'Přesunout')
		->setValidationScope([$form['x'], $form['y'], $form['z']]);

		$form->onAnchor[] = function(Form $form): void
		{
			$form['send']->setValidationScope($this->validationScopeReverse([$form['x']], $form));
		};

		return $form;
	}

	function validationScopeReverse(array $noValidate, Nette\Forms\Form $form): array {
	    $scope = [];
	    foreach ($form->getControls() as $control) {
			if (!in_array($control, $noValidate, true)) {
	            $scope[] = $control;
	        }
	    }
	    return $scope;
	}
}
protected function createComponentRezervaceForm(): Form
{
	$form = $this->rezervaceFormFactory->create();
	....

	$form['hoste']->addCreateButton('kalendar.dalsi_host')
        ->addOnCreateCallback(function (Submitter $submitter) {
        $submitter->onClick[] = function (): void {
			$this->template->sablona = "Kalendar/modal_rezervace.latte";
            $this->payload->isModal = true;
            $this->redrawControl('modal');
		};
	});

	$form['hoste']->addRemoveButton('X')
		->addOnCreateCallback(function (Nette\Forms\Controls\SubmitButton $submitter) {
        $submitter->onClick[] = function (): void {
			$this->template->sablona = "Kalendar/modal_rezervace.latte";
            $this->payload->isModal = true;
            $this->redrawControl('modal');
		};
	});

	$form->onSuccess[] = function(Form $form, $values): void
    {
	...
	};

	return $form;
}

Editoval pista5 (9. 1. 11:59)

Martk
Člen | 631
+
0
-

Voláš tam někde $multiplier->addCreateButton?

pista5
Člen | 39
+
0
-

Ano, doplnil jsem to do kodu…

pista5
Člen | 39
+
0
-

Mám za to, že volám $form['hoste']->addCreateButton správně… je to tak?
Až do spuštění validace funguje Forms-multiplier správně.

Editoval pista5 (17. 1. 18:44)

pista5
Člen | 39
+
0
-

Prosím, nenašel by se tu někdo, kdo by ještě poradil?

Výše uvedená rada funguje, ale pouze do doby, než se použije contributte/forms-multiplier :(

m.brecher
Backer | 124
+
0
-

Ahoj, s formuláři zase tolik zkušeností nemám, ale když je formulář rozdělený na dvě části, které se validují samostatně a odesílají různými tlačítky, co na to jít tak, že by se ve formuláři vytvořily dva kontejnery (nějaký takový control v Nette formulářích je) a vypínala by se validace těch kontejnerů, protože ten postup s výčtem prvků, nebo speciální metodou pro revers validaci je takový nepěkný, kdykoliv se změní nějaký prvek, nesmí se zapomenout ručně měnit parametry pro setValidationScope. Ale nevím, zda to je v reálu možné, muselo by se to vyzkoušet.