Použití setDefaults v containeru
- tatyalien
- Člen | 239
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)
- Martin
- Člen | 171
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)
- Filip Procházka
- Moderator | 4668
Můj bože, proč bys to dělal, smaž to než tě někdo zabanuje za ignoranci.
- Mikulas Dite
- Člen | 756
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())
;
- Martin
- Člen | 171
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:
- Doporučoval jsem použít funkci barDump(). Rada byla použita, je na tom něco špatně?
- 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é?
- 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?
- 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
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
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
- tatyalien
- Člen | 239
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…
- tatyalien
- Člen | 239
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.
- tatyalien
- Člen | 239
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)