addHidden ve formuláři načte hodnotu jen jednou

před 8 dny

Allconius
Člen | 129
+
0
-

Ahoj, mám tento formulář:

<?php

    protected function createComponentTestForm()
    {

    $form = new Form;
    $result = $this->dbManager->zobrazTest(1); //pocet RAND otazek

    foreach ($result as $row) {


.........................

        $cislootazky = (string)$row->id_otazky;

    }

    $form->addHidden('otazka', $cislootazky);
    $form->addHidden('hledej','1');
    $form->addSubmit('submit', 'Další');
    $form->onSuccess[] = [$this, 'testFormSucceeded'];

    return $form;
    }


    public function testFormSucceeded(Form $form, $values)
    {

        echo $values['otazka'];
    }

?>

Generuji s ním testové otázky a problém je v tom, že se to

<?php
$form->addHidden('otazka', $cislootazky);
?>

naplní jen jednou při prvním odeslání, tzn. ve zdrojáku mám např::

<?php
<input type="hidden" name="otazka" value="99">
<input type="hidden" name="hledej" value="1">
<input type="hidden" name="_do" value="testForm-submit">
?>

a je tam pořád hodnota „99“ i když čísla otázek už jsou úplně jiná, proč tam pořád drží tu hodnotu načtenou poprvé ? Nějaký session … ? Mám pak nesmyslnej zdroják např.:

<?php
<form action="/test/" method="post" class="form-horizontal" id="frm-testForm">

<fieldset>
<legend>1. Cyklista odbočující vpravo:</legend>
<img src="../obrazky/262.png" alt="Cyklista odbočující vpravo:" />

<div class="form-group">
<div class="col-sm-3 control-label">
<label></label>
</div>

<div class="col-sm-9">
<label>
<input type="radio" name="otazka262" value="3"> dává přednost žlutému vozidlu, přijíždějícímu zleva
</label><br>
<label>
<input type="radio" name="otazka262" value="2"> má přednost v jízdě před protijedoucím modrým vozidlem
</label><br>
<label>
<input type="radio" name="otazka262" value="1"> musí dát přednost v jízdě protijedoucímu modrému vozidlu
</label>
</div>
</div>

<div class="form-group">
<div class="col-sm-3 control-label"></div>
<div class="col-sm-9"><input type="submit" name="_submit" value="Další" class="button"></div>
</div>

</fieldset>

<input type="hidden" name="otazka" value="99">
<input type="hidden" name="hledej" value="1">
<input type="hidden" name="_do" value="testForm-submit">
<!--[if IE]><input type=IEbug disabled style="display:none"><![endif]-->
</form>
?>

kdy načítám otázku 262, ale v hidden-otazka mám 99, zkoušel jsem mazat temp a nic, načte ten hidden-otazka jen jednou a pak to „drží“

Editoval Allconius (8. 10. 9:50)

před 8 dny

Ondřej Kubíček
Člen | 419
+
+1
-

a v proměnné $cislootazky je co? tam je 262 nebo 99? nevím jak ten foreach vypadá celý, ale tipuju že 99 je vždy poslední z toho $result a proto si ho vždy nastavíš do té proměnné

před 8 dny

Allconius
Člen | 129
+
0
-

Ondřej Kubíček napsal(a):

a v proměnné $cislootazky je co? tam je 262 nebo 99? nevím jak ten foreach vypadá celý, ale tipuju že 99 je vždy poslední z toho $result a proto si ho vždy nastavíš do té proměnné

Ahoj, je to takto:

<?php
    $form = new Form;
    $result = $this->dbManager->zobrazTest(1); //pocet RAND otazek
    $cislo = 1;
    $numbers = range(1, 3);

    foreach ($result as $row) {

        if (($row->ref('besip_otazky', 'id_otazky')->obrazek)<>'') {

        $form->addGroup($cislo.'. '.$row->ref('besip_otazky', 'id_otazky')->otazka)
           ->setOption('description',Html::el()->setHtml('<img src="../obrazky/'.$row->ref('besip_otazky', 'id_otazky')->obrazek.'.png" alt="'.$row->ref('besip_otazky', 'id_otazky')->otazka.'" />'));

        }else{

        $form->addGroup($cislo.'. '.$row->ref('besip_otazky', 'id_otazky')->otazka);

        }

//namixuj to nahodne
    shuffle($numbers);
        foreach ($numbers as $number) {

        $m = 'm'.$number;
        $odpovedi[$number] = ' '.$row->ref('besip_otazky', 'id_otazky')->$m.'';

        }

        // pro vypsání možností do 1 řádku
        $form->addRadioList('otazka'.$row->ref('besip_otazky', 'id_otazky')->id_otazky.'', '', $odpovedi);
        //->getSeparatorPrototype()->setName(null); //hodnoty v 1 radku
        $cislo++;

        $cislootazky = (string)$row->id_otazky;
        //$cislootazky = '0';

    }

    $form->addHidden('otazka', $cislootazky);
    $form->addHidden('hledej','1');
    $form->addSubmit('submit', 'Další');

?>

no právě nechápu odkud to bere, protože to číslo 1 zde:

<?php
$result = $this->dbManager->zobrazTest(1);
?>

znamená, že vybírám jen jednu otázku, a první načtení stránky se provede dobře:

<?php
<form action="/test/" method="post" class="form-horizontal" id="frm-testForm">

<fieldset>
<legend>1. Cyklista projede křižovatkou jako:</legend>
<img src="../obrazky/310.png" alt="Cyklista projede křižovatkou jako:" />

<div class="form-group">
    <div class="col-sm-3 control-label"><label></label></div>

    <div class="col-sm-9"><label><input type="radio" name="otazka310" value="1"> první</label><br><label><input type="radio" name="otazka310" value="2"> třetí současně s modrým vozidlem</label><br><label><input type="radio" name="otazka310" value="3"> druhý</label></div>
</div>

<div class="form-group">
    <div class="col-sm-3 control-label"></div>

    <div class="col-sm-9"><input type="submit" name="_submit" value="Další" class="button"></div>
</div>

</fieldset>

<input type="hidden" name="otazka" value="310"><input type="hidden" name="hledej" value="1"><input type="hidden" name="_do" value="testForm-submit"><!--[if IE]><input type=IEbug disabled style="display:none"><![endif]-->
</form>
?>

je tam všude 310, ale když dám odeslat tak tam mám:

<?php
<form action="/test/" method="post" class="form-horizontal" id="frm-testForm">

<fieldset>
<legend>1. Pokud se závory  sklápějí nebo zdvihají,  smí se vjíždět na železniční přejezd</legend>
<img src="../obrazky/117.png" alt="Pokud se závory  sklápějí nebo zdvihají,  smí se vjíždět na železniční přejezd" />

<div class="form-group">
    <div class="col-sm-3 control-label"><label></label></div>

    <div class="col-sm-9"><label><input type="radio" name="otazka117" value="1"> ano</label><br><label><input type="radio" name="otazka117" value="2"> ne</label><br><label><input type="radio" name="otazka117" value="3"> nevím</label></div>
</div>

<div class="form-group">
    <div class="col-sm-3 control-label"></div>

    <div class="col-sm-9"><input type="submit" name="_submit" value="Další" class="button"></div>
</div>

</fieldset>

<input type="hidden" name="otazka" value="262"><input type="hidden" name="hledej" value="1"><input type="hidden" name="_do" value="testForm-submit"><!--[if IE]><input type=IEbug disabled style="display:none"><![endif]-->
</form>
?>

tak tam mám najednou 262 místo 117, a další odeslání:

<?php
<form action="/test/" method="post" class="form-horizontal" id="frm-testForm">

<fieldset>
<legend>1. Dodatková tabulka vyznačuje</legend>
<img src="../obrazky/189.png" alt="Dodatková tabulka vyznačuje" />

<div class="form-group">
    <div class="col-sm-3 control-label"><label></label></div>

    <div class="col-sm-9"><label><input type="radio" name="otazka189" value="3"> zvýšení počtu jízdních pruhů pro cyklisty</label><br><label><input type="radio" name="otazka189" value="1"> možný směr jízdy cyklistů</label><br><label><input type="radio" name="otazka189" value="2"> křižovatku</label></div>
</div>

<div class="form-group">
    <div class="col-sm-3 control-label"></div>

    <div class="col-sm-9"><input type="submit" name="_submit" value="Další" class="button"></div>
</div>

</fieldset>

<input type="hidden" name="otazka" value="262"><input type="hidden" name="hledej" value="1"><input type="hidden" name="_do" value="testForm-submit"><!--[if IE]><input type=IEbug disabled style="display:none"><![endif]-->
</form>
?>

zase 262 místo 189 a to 262 už tam pak zůstane dokud nezavřu prohlížeč :-) Asi je to jen nějaká blbost, ale nemůžu na to přijít. Každopádně to číslo co tam zůstává je pokaždé jiný a není stejné jako prvně načtená otázka. Třeba teď jsem to zkoušel a první otázka měla číslo 19, po odkliknutí se načetla otázka 65, ale to číslo v hidden-otazka se zafixovalo na čísle 12 :-)

před 8 dny

Ondřej Kubíček
Člen | 419
+
0
-

bwt když víš že chceš dostat jen jeden záznam použij fetch(), ne fetchAll() (za předpokladu že používáš nette database, nevím co zobrazTest dělá a co je dbManager), pak je uplně zbytečné používat foreach pro $result

před 8 dny

Allconius
Člen | 129
+
0
-

Ondřej Kubíček napsal(a):

a v proměnné $cislootazky je co? tam je 262 nebo 99? nevím jak ten foreach vypadá celý, ale tipuju že 99 je vždy poslední z toho $result a proto si ho vždy nastavíš do té proměnné

Nemůže nějak blbnout ten (string) ? Protože když jsem přidal:

<?php
        echo 'id_otazky='.$row->id_otazky.'<br />';
        $cislootazky = (string)$row->id_otazky;
?>

tak to echo ukazuje správné číslo.

před 8 dny

Šaman
Člen | 2339
+
0
-

Nechci se teď prokousávat těmi bootstrap šablonami, ale obecně se formuláře plní v action metodě. Zvlášť, když chceš náhodné hodnoty. Protože formulář se vždy vytvoří nejméně dvakrát – poprvé když se vykreslí a podruhé jako příjemce hodnot. Ty vytvoříš pokaždé jiný formulář a Nette si nějak hlídá, aby hodnota předaná při předání POSTem byla jedna z možných hodnot toho formuláře.

Vytvoř si formulář jen jako políčka bez hodnot a pak ho předvyplň v action metodě (v render je pozdě!). Ušetříš si různé WTF momenty, možná se to vyřeší.

před 8 dny

Allconius
Člen | 129
+
0
-

Ondřej Kubíček napsal(a):

bwt když víš že chceš dostat jen jeden záznam použij fetch(), ne fetchAll() (za předpokladu že používáš nette database, nevím co zobrazTest dělá a co je dbManager), pak je uplně zbytečné používat foreach pro $result

no teď jsem zjistil že je to správně i po foreach, když vyechuju:

<?php
    echo 'cislootazky='.$cislootazky.'<br />';

    $form->addHidden('otazka', $cislootazky);
    $form->addHidden('hledej','1');
    $form->addSubmit('submit', 'Další');
?>

tak dostanu přes:

<?php
    public function testFormSucceeded(Form $form, $values)
    {
        echo print_r($values);
    }
?>

toto:

<?php
cislootazky=284
Nette\Utils\ArrayHash Object ( [otazka284] => [otazka] => 83 [hledej] => 1 ) 1
?>

nějak to „zprasí“ až ten addHidden

před 8 dny

Šaman
Člen | 2339
+
0
-

A co to dělá, když znova načteš stránku „nanovo“? Bez zavření prohlížeče, ale taky bez toho, že by ses na ten formulář dostal odesláním předchozího formuláře.

před 7 dny

Allconius
Člen | 129
+
0
-

Šaman napsal(a):

A co to dělá, když znova načteš stránku “nanovo”? Bez zavření prohlížeče, ale taky bez toho, že by ses na ten formulář dostal odesláním předchozího formuláře.

Ahoj, máš pravdu, když jen reloaduju stránku F5 tak to funguje správně, problém je když dám submit, byl tu včera kamarád a radil mi to samé co ty, že to nemám rvat do té komponenty ale použít:

<?php
    public function renderDefault()
    {
        $this['testForm']->setDefaults(array('otazka'=>"187"));
    }
?>

nebo asi tedy už do action:

<?php
    public function actionDefault()
    {
        $this['testForm']->setDefaults(array('otazka'=>"187"));
    }
?>

tak to zkusím předělat je pravda že s tou modifikací komponenty jsem měl vždycky problém dřív jsem zkoušel např. modifikace přes proměnnou:

<?php

if ($a==1){
$form->addHidden('otazka', $cislootazky);
}else{
$form->addText('jouda', 10, 10);
}
    $form->addSubmit('submit', 'Další');

?>

ale to jsem rychle opustil :-)))

před 7 dny

CZechBoY
Člen | 3392
+
0
-

A je potreba vubec mit ten hidden field kdyz ho znas i bez toho formulare?

před 7 dny

Allconius
Člen | 129
+
0
-

CZechBoY napsal(a):

A je potreba vubec mit ten hidden field kdyz ho znas i bez toho formulare?

no to je otázka jak ho do toho action dostanu … :-)

před 7 dny

Šaman
Člen | 2339
+
0
-

V tom případě je chyba asi jinde. V (ne)přesměrování po odeslání. Ty vytvoříš formulář i s nějakými hodnotami. Napoprvé dobrý, ale pak ho odešleš. Odeslání je nový request, takže se znovu vytvoří formulář s novými hodnotami… ale hned přijme data z postu, která mu to id přepíšou tou odeslanou. Teď to musíš zpracovat a přesměrovat na nový čerstvý formulář a to asi neděláš. Takže máš nastavené id otázky tak, jak přišlo postem a po odeslání tedy odesíláš minulou hodnotu. Žádné session, předáváš si to tím polem ve formuláři.

Nezůstává ti v adresním řádku nějaké &do=testFormSubmitted nebo tak nějak? V takovém případě ti v onSuccess chybí redirect, který (pokud moc dobře nevíš proč ho nedělat) by se měl dělat vždy. (Koukám že v prvním příspěvku v kódu opravdu chybí, ale myslel jsem že to echo je jen zoufalé testování. Jestli jsi ho tam neměl ani předtím, tak je to tím.)


A trochu nesouvisející druhá věc – proč neplnit formulář v render metodě. Jakmile si začneš hrát s AJAXem (třeba kvůli závislým inputům, které budeš řešit pomocí snippetů) tak budeš používat handle metody. A z životního cyklu presenteru je vidět, že handler proběhne dřív, než render. Jinak řečeno pracuješ se stále nenastaveným formulářem a do něho se pak hodnoty nasypou (a cokoliv předchozího přepíšou) až při vykreslení (render). Řešením je nastavovat to v action, která proběhne jako první a render metody používat ideálně striktně jen pro práci s šablonou (tedy v render by měly být jen řádky $this->template… a to, co s nimi bezprostředně souvisí).

Editoval Šaman (9. 10. 16:13)