Náhodně vybrané prvky ve formuláři
- _enigma
- Člen | 17
Ahoj,
potřebuji vytvořit formulář, kde budou testovací
otázky z databáze, které se budou
náhodně vybírat.
Pokud si z otázek vygeneruji form, všechny radiolisty vyplním, tak po
odeslání se mi v dumpu u některých vrací value NULL. Zde na fóru jsem se
dočetl něco o tom, že to bude problém sestavení formu po vykreslení a po
odeslání, ale moc jsem z toho nebyl moudrý a nebylo uvedeno žádné
řešení.
Lze to nějak udělat? Případně prosím o hrubý nástřel, jak to udělat.
Zjednodušený náhled formu:
protected function createComponentTestForm()
{
$form = new UI\Form;
// vrátí náhodně 4 řádky z DB s otázkou a odpověďmi
$questions = $this->tests->getTest();
$container = $form->addContainer('questions');
foreach ($questions as $question){
$answers = array(
1 => $question->answerOne,
2 => $question->answerTwo,
3 => $question->answerThree
);
$container->addRadioList($question->id, $question->question, $answers);
}
$form->addSubmit('submit', 'Results');
$form->onSuccess[] = callback($this, 'testFormSucceeded');
Debugger::dump($values) po odeslání formu vrací následující:
...
19 => NULL
34 => 3
9 => 1
58 => NULL
...
přitom všechny radiolisty byly vyplněné. Zda se, že u hodnot NULL nesedí id otázek, která byly původně vyplněné. (Nette 2.2.6, PHP 5.4)
Děkuji všem za reakce a nápady.
- Šaman
- Člen | 2668
Zkus si pro začátek nevytvářet ten formulář náhodně. Asi to opravdu bude tím, že kontrolní mechanismy nedovolí vrátit hodnoty pro pole, která nebyla ve formuláři definovaná. A ten formulář vytváříš dvakrát – poprvé když se má zobrazit, pak ho uživatel vyplní, odešle a pak ti proběhne request, po kterém si musíš ten formulář vytvořit znovu a on si načte pro každé své pole odpovídající hodnoty. Ale ta pole jsou najednou jiná (a tak jejich hodnoty v POSTu neexistují).
Když budeš načítat poprvé i podruhé stejné otázky a tohle bude fungovat, tak pak budeš řešit problém kde uchovávat id otázek. Většinou se to řeší hidden polem. Takže od boku něco takového.
<?php
foreach ($questions as $question){
$answers = array(
1 => $question->answerOne,
2 => $question->answerTwo,
3 => $question->answerThree
);
$container->addHidden('questionId')->setDefaultValue($question->id);
$container->addRadioList('answer', $question->question, $answers);
}
?>
- _enigma
- Člen | 17
Ahoj a díky za reakci. To jsem už také zkoušel a to skutečně jde. Jakmile odstraním prvek náhodnosti, tak je to OK. Nicméně bych tam tu náhodnost potřeboval.
Napadlo mě nechat vyjet všechny ID otázek z DB do pole, to zamíchat a pak vybrat jen třeba prvních 5 položek a předávat je do formu. Zkoušel jsem to v actionTest, ale to taky nezafungovalo. Ovšem nejsem si jist jestli to bylo to správné místo.
- Aurielle
- Člen | 1281
Nevím, jestli by se ti v tomhle případě místo hackování náhodnosti nevyplatilo použít nízkoúrovňový přístup k formulářům.
- _enigma
- Člen | 17
Díky Aurielle, to funguje.
Takto to generuji v šabloně:
{foreach $questions as $question}
<p>{$question->question}</p>
<p><input type='radio' name='sel[{$question->id}]' value='1'> {$question->answer1}</p>
<p><input type='radio' name='sel[{$question->id}]' value='2'> {$question->answer2}</p>
<p><input type='radio' name='sel[{$question->id}]' value='3'> {$question->answer3}</p>
{/foreach}
… a poté si id otázek už normálně předávám jako perzistentní parametr v presenteru. A jede to :) Ani netušíte, jakou mám radost.
Vlastně děkuji všem, že jsem alespoň trochu více nahlédl pod pokličku formulářu Nette.