Použití setDefaults v containeru

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
tatyalien
Člen | 239
+
0
-

Dobrý den, snad už poslední otázka na conteinery…

Rozchodil jsem snad už vše co budu potřebovat, ale ukládání dat při odeslání formuláře a znovu vyplňění formuláře mě funguje pouze přez session (když mám více odesílacích tlačítek, tak musím znovu vyplňit data co zadal uživatel, například pokud si kliknu na tlačítko dodej datum, tak jen reloudnu stránku a dodávám text inputu datum_reklamace hodnotu dnešního dne).
Aktuální příklad:

<?php
// Presenter:
        protected function createComponentZboziDatumyForm($name)
        {
                $form = new AppForm($this, $name);
                $form->getElementPrototype()->id = 'frm-datumy';
                $form['datumy'] = new ReklamaceDatumyContainer;
                $form['datumy']['btn_datum_reklamace']->onClick[] = callback($this, 'datumReklamaceClicked');
                $form['datumy']['btn_datum_faktury']->onClick[] = callback($this, 'datumFakturyClicked');
                $form->addGroup("Ukládací tlačítko")->setOption('embedNext', true);
                $form->addSubmit('save', 'Uložit')->setHtmlId("save");
        }

        public function datumReklamaceClicked(\Nette\Forms\SubmitButton $button) {
            $values = $button->getForm()->getValues();
            $values['datumy']['datum_reklamace'] = Date("d.m.Y", Time());
            $namespace = Environment::getSession('rkl_test');
            $namespace->defaults = $values;
            $this->flashMessage("Dodán datum reklamace.");
            $this->redirect('this');
        }
?>

třída containeru:

<?php
class ReklamaceDatumyContainer extends Nette\Forms\FormContainer
{
        public function __construct(IComponentContainer $parent = NULL, $name = NULL)
        {
                parent::__construct($parent, $name);
                $this->monitor('Nette\Forms\Form');
        }

        protected function attached($obj)
        {
                parent::attached($obj);
                if (!$obj instanceof Nette\Forms\FormContainer) {
                        return ;
                }

                $namespace = Nette\Environment::getSession('rkl_test');
                $zpravy = new Nette\Application\AppForm;

                $this->getForm()->getElementPrototype()->setNovalidate('novalidate');
               	$this->currentGroup = $this->getForm()->addGroup()->setOption('embedNext', false);
                $this->addText('datum_reklamace', 'Datum reklamace:')
                    ->setHtmlId("datum_reklamace")
                    ->addRule($obj::FILLED, 'Vyplňte datum reklamace.');

                $this->addText('datum_faktury', 'Datum faktury')
                    ->setHtmlId("datum_faktury")
                    ->addRule($obj::FILLED, 'Vyplňte datum faktury.');

                $this->addSubmit('btn_datum_reklamace', 'Vložit datum reklamace')->setValidationScope(false)->setHtmlId("btn_datum_reklamace");
                $this->addSubmit('btn_datum_faktury', 'Vložit datum faktury')->setValidationScope(false)->setHtmlId("btn_datum_faktury");

                $data_default = Array();
                // vytáhnu si data z containeru datumy název je z preseneteru:
                // $form['datumy'] = new ReklamaceDatumyContainer; pokud bych změnil například:
                // $form['zmena'] = new ReklamaceDatumyContainer;
                // musel bych změnit tady hodnotu na (array) $namespace->defaults["zmena"];
                // pokud už uživatel na něco klikal, musím nastavit defaultní hodnoty -> ty co už zadal uživatel

	// s tímto mě to funguje, ale je to na tvrdo přez session:
                $data_vstup = (array) $namespace->defaults["datumy"];
                foreach($data_vstup as $key => $value) {
                    $data_default[$key] = $value;
                }
                // nyní nastavím zadané data od uživatele
                $this->setDefaults($data_default);


	// ale takto mě to nefunguje: přitom pokud si zobrazím přez flashMessage, tak mám správný výsledný formát:
	// Array("datum_reklamace" => "to co si zadám", "datum_faktury" => "to co si zadám")
                /*
	$data_default = Array();
                $data_vstup = $obj->getValues();
                foreach($data_vstup["datumy"] as $key => $value) {
                    $data_default[$key] = $value;
                }
                $this->setDefaults($data_default);

                */
        }
}
?>

A poslední otázka, jak můžu do třídy containeru dodat debugování? Když si totiž chci jen vypsat data co tam mám, tak jedině jak jsem je dokázal si zobrazit, bylo pomocí $zpravy::flashMessage($data_default);, toto samozřejmně skočí do laděnky, kde si můžu alespoň zobrazit $data_default. Samozřejmně dump() jsem zkoušel, musím to do té třídy nějak nalinovat?
Nějak se mě na to nepodařilo přijít… :(

PS: po použití Nette\Debug::dump($data_default); skočí laděnka na:
Cannot set HTTP code after HTTP headers have been sent (output started at D:\xampp\htdocs\www\mozne_smazat\test_container\libs\Nette\Diagnostics\Debugger.php:599)

Editoval tatyalien (3. 5. 2011 19:37)

Majkl578
Moderator | 1364
+
0
-

Eh?

dump($data_default);
tatyalien
Člen | 239
+
0
-

Nefachá to jsem už zkoušel ;) tohle je ve tříde nalinkované.

Martin
Člen | 171
+
0
-

Pokud Ti stačí data vidět až po vyrenderování stránky:

barDump(array('NazevPromenne' => $NazevPromenne));

Uvidíš je vpravo dole v debugbaru. Na rozdíl od dump() se nemusíš starat, jestli už byly odeslány hlavičky.

Pokud potřebuješ výpis už za běhu, nebo vypisovat z Ajaxové obsluhy, tak FireLog, ale mě to nefungovalo, vypisoval jsem si je do souboru – třeba přes tato makra:

Tato část byla na doporučení odborníků smazána.

Editoval Martin (5. 5. 2011 21:02)

Martin
Člen | 171
+
0
-

Jen pozor, v nové vývojové verzi Nette to už není Nette\Debug ale Nette\Diagnostics\Debugger.

Filip Procházka
Moderator | 4668
+
0
-

Můj bože, proč bys to dělal, smaž to než tě někdo zabanuje za ignoranci.

Mikulas Dite
Člen | 756
+
0
-

Tak psát tohle a navíc v php 5.3, to už chce odvahu…

Ale abych byl i konstruktivní: použí prostě dump(get_defined_vars());

Majkl578
Moderator | 1364
+
0
-

Martin: Gratuluji, vyhráváš titul prase týdne.

Filip Procházka
Moderator | 4668
+
0
-

Navrhuji začátečníka. Zcela vážně.

ViliamKopecky
Nette hipster | 230
+
0
-

Ááá, kluci. Na fórum už moc nezavítávám, ale todle pobavilo. :D

tatyalien
Člen | 239
+
0
-

tak fachá tohle, díky:

barDump(array('NazevPromenne' => $NazevPromenne));

teď ještě to ukládání defaultních hodnot co zadá uživatel :-) sice mě to funguje přez session, ale mělo by to sand jít i nějak normálně ne?

Martin
Člen | 171
+
0
-

Pánové, jen do mě. Tohle se mi líbí, místo odpovědi tazateli 5 kritik mého pokusu. Pardon, Mikulas Dite se o odpověď pokusil, zřejmě však nečetl původní dotaz od tatyalien, neboť ten se ptal, co může použít, když dump() nelze. Takže si to shrňme:

  1. Doporučoval jsem použít funkci barDump(). Rada byla použita, je na tom něco špatně?
  2. Dále jsem psal, že v případě, že z nějakého důvodu potřebuji výpis proměnných dříve, než při renderování stránky, nebo pro výpis z kódu, kde k renderování vůbec nedochází, používám zápis do souboru. Je na tom něco špatně? XDebug padá při pokusu o zobrazení určitých proměnných (nová verze méně, ale také, kromě toho uspokojivě funguje spíš jen lokálně), DBG je nyní k dispozici jen v placené verzi. Nejnovější Firefox+Firebug+Firelogger nespolupracuje s funkcí fireLog() (mohu se mýlit, třeba jsem jen něco špatně nastavil). Lze posílat data i jinam – některému elementu ajaxově, do jiného rámu/záložky/okna prohlížeče, do jiné aplikace, je něco z toho lehce a rychle použitelné?
  3. Samozřejmě místo makra mohu použít třeba statickou funkci. Souhlas, není to zrovna cool, ale pro jednorázové použití s následným smazáním to nějak vadí? Pominu rychlost provádění a délku zápisu v kódu. Důvodem k banu je použití makra v PHP 5.3 aplikaci?
  4. Tohle neberte jako kontroverzní výzvu – rád bych se opravdu dozvěděl řešení: Napíšete sem, prosím, někdo, jak rychle a jednoduše vypsat obsah proměnné (proměnných), když to nemá být do renderovaného výstupu, respektive je to třeba potřebné průběžně a opakovaně dávno před vykreslováním?

Editoval Martin (5. 5. 2011 1:41)

22
Člen | 1478
+
0
-

ono stačí akorát použít vyhledávání na fóru:
https://forum.nette.org/…firebugu-1-7
fireLogger funguje po zmíněné úpravě úpravě i pro FF 4.0.1

Mikulas Dite
Člen | 756
+
0
-

Třeba tohle je ukázka toho statického provedení: https://gist.github.com/955777.

Na rozdíl od evalu je to čitelné, nastavitelné = upravitelné = znovu použitelné a dá se to rozšiřovat.

A nebo něco s původním kolem: https://api.nette.org/….Logger.html#_log

Martin
Člen | 171
+
0
-

22: OK, dík. Nenapadlo mě hledat něco k Fireloggeru, když před dvěma měsíci se zde řešilo, že to asi nejde.

Editoval Martin (4. 5. 2011 22:12)

tatyalien
Člen | 239
+
0
-

Jen se tedy zeptám, debugování jsem tedy rozchodil, děkuji za příspěvky… ale můžeme se vrátit ještě k původnímu dotazu? Jak na donastavení dat co uživatel již vyplnil, když po odesílacím tlačítku reloudnu stránku při použítí contenineru? Mě to funguje pomocí sessionu, ale jak to rozjet bez něj? Kód viz první příspěvek…

Martin
Člen | 171
+
0
-

Mikulas Dite: OK, samozřejmě zápis do souboru jsem mohl/měl napsat lépe.

Editoval Martin (4. 5. 2011 22:17)

Majkl578
Moderator | 1364
+
0
-

Martin: Ty jsi hlavně dost mimo. PHP žádná makra nemá – to, co jsi napsal, je neskutečná prasárna…

OK3
Člen | 91
+
0
-

Vážně zábavné téma, jen jste si na lynčování mohli založit jiné :-)

K původnímu tématu, jak nastavit hodnoty: zkoušel jsi ty hodnoty setDefaults(…) nastavit v (akci) presenteru?

Editoval OK3 (5. 5. 2011 16:40)

tatyalien
Člen | 239
+
0
-

Nastavuji je v containeru, ale asi to budu muset udělat až v presenteru… zejtra to testnu ;)

tatyalien
Člen | 239
+
0
-

Tak stejně netuším jak… tam mě to opět funguje jen se session, továrnička v presenteru:

<?php
        protected function createComponentZboziDatumyForm($name)
        {
                $form = new AppForm($this, $name);
                $form->getElementPrototype()->id = 'frm-zbozi';
                $form['zbozi'] = new ZboziContainer;
                $form['datumy'] = new ReklamaceDatumyContainer;
                $form['servis'] = new ServisContainer;
                $form['zbyle_udaje'] = new RmaZbyleUdajeContainer;

                $form['zbozi']['pridat']->onClick[] = callback($this, 'pridatClicked');
                $form['zbozi']['vymazat']->onClick[] = callback($this, 'vymazatClicked');

                $form['datumy']['btn_reklamace_start']->onClick[] = callback($this, 'datumyClicked');
                $form['datumy']['btn_nakup']->onClick[] = callback($this, 'datumyClicked');
                $form['datumy']['btn_servis_odeslani']->onClick[] = callback($this, 'datumyClicked');
                $form['datumy']['btn_servis_prijeti']->onClick[] = callback($this, 'datumyClicked');
                $form['datumy']['btn_volani_zakazniku']->onClick[] = callback($this, 'datumyClicked');
                $form['datumy']['btn_reklamace_konec']->onClick[] = callback($this, 'datumyClicked');


                $form['zbozi']->addCheckbox('zbozi_show', 'Skrýt zboží')
                        ->setHtmlId("zbozi_show")
                    	->addCondition($form::EQUAL, FALSE)
                    		->toggle('zbozi_all');
                $form['servis']->addCheckbox('servis_show', 'Skrýt poznámky')
                        ->setHtmlId("servis_show")
                    	->addCondition($form::EQUAL, FALSE)
                    		->toggle('servis_all');
                $form['datumy']->addCheckbox('datumy_show', 'Skrýt datumy')
                        ->setHtmlId("datumy_show")
                    	->addCondition($form::EQUAL, FALSE)
                    		->toggle('datumy_all');
                $form['zbyle_udaje']->addCheckbox('zbyle_udaje_show', 'Skrýt zbylé údaje')
                        ->setHtmlId("zbyle_udaje_show")
                    	->addCondition($form::EQUAL, FALSE)
                    		->toggle('zbyle_udaje_all');

                $form->addGroup("Ukládací tlačítko")->setOption('embedNext', true);
                $form->addSubmit('save', 'Uložit')->setHtmlId("save")->onClick[] = callback($this, 'saveClicked');

                // nyní nastavím základní hodnoty popřípadě ty co už uživatel zadal
		// takto mě to funguje...
                $namespace = Nette\Environment::getSession('rkl_test');
                $form->setDefaults((array) $namespace->defaults);
                Nette\Debug::barDump((array) $namespace->defaults);
        }
?>

Ale jak do tohoto zakomponovat při reloudu stránky, aby se vyplnili minulé údaje bez session nevím.

22
Člen | 1478
+
0
-

a proč to nenačteš z $this->getHttpRequest()->post třeba?

tatyalien
Člen | 239
+
0
-

Protože z $this->getHttpRequest()->post se mě nezobrazili žádné výsledky, zobrazí se mě jen dotaz co mám do DB pro získání dat do comboboxu.

22
Člen | 1478
+
0
-

…to je jako po submitu $_POST prázdnej? Hm..

tatyalien
Člen | 239
+
0
-

Budeš se divit, ale ano.

Když kliknu na tlačítko datumu, kde se volá callback:

<?php
        public function datumyClicked(\Nette\Forms\SubmitButton $button) {
            $values = $button->getForm()->getValues();

            // zjistím si, pro jaký formulář chci doplňit datum
            // protože názvy tlačítek jsou stejné jako formuláře jen mají navíc btn_
            $formular = substr($button->getName(), 4);

            $values['datumy'][$formular] = Date("d.m.Y", Time());
            $namespace = Environment::getSession('rkl_test');
            $namespace->defaults = $values;

            $this->flashMessage("Vložen datum do hodnoty: '{$button->caption}'.");
            $this->redirect('this');
        }
?>

Tak se redirectnu zpět, znovu se mě vykreslí formulář ale dle dumpu mám post prázdný. Každopádně data se mě dostanou z callbecku do sessionu správně.

Editoval tatyalien (7. 5. 2011 12:22)