opetovne volani modelu ve formulari

ales23
Člen | 10
+
0
-

Zdravim vsechny Nette borce. Resim jeden problem a tak jsem si rekl, ze poprosim zkusenejsi o radu.

Jde o to, ze mam v Prezenteru formular:

	protected function createComponentQuestionForm(): Form
	{
		$form = new Form;

		$question = $this->questionsManager->getQuestion();

		//tady nejaka formularova pole

		$form->addSubmit('send', 'Odpověď');

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

		return $form;
	}

	public function formSucceeded(Form $form, $data): void
	{
		if($data->correctAnswer == $data->answers)
		{
			$this->redirect('Answer:correct', $data->questionId);
		}
		else
		{
			$this->redirect('Answer:wrong', $data->questionId);
		}
	}

Vsechno funguje perfektne. Formular se vykresli, spravne vyhodnoti otazku, jenom je problem, ze mi ten callback znovu vola tu funkci v modelu $question = $this->questionsManager->getQuestion(), ktera ma jenom nacitat data do formulare. Jde o to, ze v tom modelu je logika, ktera si hlida, kolikrat byla data do formulare poslana. Takze otazka zni: jak na to, aby se pri vyhodnoceni formulare funkci formSucceeded nevolala opet funkce v modelu getQuestion. Dekuju za pomoc.

Michal Kumžák
Člen | 106
+
0
-
if (!$form->isSubmitted()) {
	$question = $this->questionsManager->getQuestion();
}

Jen nechápu proč to tam voláš. Ty z těch $question, vytváříš ten formulář? Pokud ano tak to musíš volat vždy.

Editoval Michal Kumžák (2. 9. 2021 16:28)

Kamil Valenta
Člen | 752
+
0
-

Pokud ta metoda modelu neovlivní generování inputů a tím i jejich validaci, tak to můžeš vypodmínkovat, aby se model volal jen tehdy, když není procesován signál (protože handle formuláře signál je).

Pak ještě – ačkoliv ses na to neptal:

if($data->correctAnswer == $data->answers)

Toto působí dojmem, že ve formuláři s sebou taháš i správnou odpověď. To bude pro poučené uživatele docela dobrá nápověda :)

ales23
Člen | 10
+
0
-

Michal Kumžák napsal(a):

if (!$form->isSubmitted()) {
	$question = $this->questionsManager->getQuestion();
}

Jen nechápu proč to tam voláš. Ty z těch $question, vytváříš ten formulář? Pokud ano tak to musíš volat vždy.

Ano, je to tak. Zdrojem otazek ve formulari je databaze a tu cte ta funkce getQuestion(). Zkusil jsem dle tve rady, ale bohuzel mi tracy vyhodi: Form is not anchored and therefore can not determine whether it was submitted.

ales23
Člen | 10
+
0
-

Kamil Valenta napsal(a):

Pokud ta metoda modelu neovlivní generování inputů a tím i jejich validaci, tak to můžeš vypodmínkovat, aby se model volal jen tehdy, když není procesován signál (protože handle formuláře signál je).

Pak ještě – ačkoliv ses na to neptal:

if($data->correctAnswer == $data->answers)

Toto působí dojmem, že ve formuláři s sebou taháš i správnou odpověď. To bude pro poučené uživatele docela dobrá nápověda :)

Spravne, ta odpoved jde s formularem. Je to takova hricka, takze na tom zase tak moc nesejde.

ales23
Člen | 10
+
0
-

Kamil Valenta napsal(a):

Pokud ta metoda modelu neovlivní generování inputů a tím i jejich validaci, tak to můžeš vypodmínkovat, aby se model volal jen tehdy, když není procesován signál (protože handle formuláře signál je).

Pak ještě – ačkoliv ses na to neptal:

if($data->correctAnswer == $data->answers)

Toto působí dojmem, že ve formuláři s sebou taháš i správnou odpověď. To bude pro poučené uživatele docela dobrá nápověda :)

Zkousel jsem si o tom neco nacist, ale po pravde nejsem moudry z toho, jak to udelat. Poradis, prosim?

Kamil Valenta
Člen | 752
+
0
-
if ($this->getSignal() === null) {
	$question = $this->questionsManager->getQuestion();
}

Ale opravdu pozor, pokud se z odpovědí skládají inputy (do selectu, do radiolistu). Pak bys u nich musel vypnout validaci, protože najednou se bude porovnávat odeslaná value s prázdnou možnou.

Kamil Valenta
Člen | 752
+
0
-

ales23 napsal(a):

Jde o to, ze v tom modelu je logika, ktera si hlida, kolikrat byla data do formulare poslana.

A když uživatel nad stránkou s formulářem bude mačkat F5?

ales23
Člen | 10
+
0
-

Kamil Valenta napsal(a):

if ($this->getSignal() === null) {
	$question = $this->questionsManager->getQuestion();
}

Ale opravdu pozor, pokud se z odpovědí skládají inputy (do selectu, do radiolistu). Pak bys u nich musel vypnout validaci, protože najednou se bude porovnávat odeslaná value s prázdnou možnou.

Ahoj, ano, z odpovedi se skladaji inputy do radio listu. Celkove jsem to od zacatku zjevne navrhl blbe… no co uz ted :(. Diky za ten tvuj navrh reseni, ale ma to jednu chybku a to ze pri opetovnem pruchodu formularem se se dotazuje na promennou, ktera v tu chvili neexistuje, protoze je v podmince, tzn. $question je v tu chvili prazdna. Rikal jsem si, jestli by se ten dotaz do modelu questionManager nedal nejak vyjmout z formulare a postavit nad, ale aby byla promenna $question ve formulari pristupna. Lze to nejak resit pres SESSION?

if ($this->getSignal() === null) {
	$question = $this->questionsManager->getQuestion();
}
Michal Kumžák
Člen | 106
+
+1
-

Zdar

Aby byla proměnná přístupná v odeslaném formu je celkem snadné.

$form->addHidden('questionId');

if ($form->isSubmitted()) {
  $questionId = $form['questionId']->getValue();
}

Osobně, bych to na tvém místě upravil na to, aby si do generování formu posílal jen to co se týká otázky a odpovědí a správnost bych vyhodnocoval až v onSuccess, nejlépe posláním dotazu do toho modulu, například $this->questionsManager->isValidAnswer($values);

ales23
Člen | 10
+
+2
-

Michal Kumžák napsal(a):

Zdar

Aby byla proměnná přístupná v odeslaném formu je celkem snadné.

$form->addHidden('questionId');

if ($form->isSubmitted()) {
  $questionId = $form['questionId']->getValue();
}

Osobně, bych to na tvém místě upravil na to, aby si do generování formu posílal jen to co se týká otázky a odpovědí a správnost bych vyhodnocoval až v onSuccess, nejlépe posláním dotazu do toho modulu, například $this->questionsManager->isValidAnswer($values);

Uplne genialni rada. Vubec nevim, proc jsem mel tendenci to vsechno napraskat do jedne funkce. Rozdelil jsem to do dvou funkci a volam je kdyz jsou potreba. Parada, diky.