nefunguje mi predvyplneni formulare (setDefaults())

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

Ahoj, potřeboval bych poradit jak předvyplnit formulář
MySQL tabulka:
[---- novinky ----]
id [INT]
id_uzivatele [INT]
perex [TEXT]
text [TEXT]
datum_vlozeni [DATETIME]
[-----------------]

formulář v presenteru

protected function createComponentEditNovinkuForm()
        {

            $form = new Nette\Application\UI\Form;
            $form->addProtection('CSFR ochrana: Vypršel časový limit, odešlete formulář znovu');
            $form->addText('perex', 'Perex:');
            $form->addTextArea('text', 'Text:')->getControlPrototype()->class('mceEditor');
            $form->addDatePicker('datePicker1','Datum:');
            $form->addSubmit('vlozit', 'vložit');
            $form->getElementPrototype()->onsubmit('tinyMCE.triggerSave()'); //kvuli TinyMce
            $form->onSuccess[] = callback($this, 'updateNovinku');
            return $form;
        }

akce, kterou volám z jedné tabulky

public function actionEditujNovinku($id)
        {
            /* predvyplneni formu + kontrola id zaznamu */
            $id = $this->kontrolaId($id);
            $this['editNovinkuForm']->setDefaults($this->novinky->vratPoleHodnot($id));
        }

způsob jakým jí volám

$this->addButton("edit", "Editovat")
            ->setClass("edit")
            ->setLink(function($row) use ($presenter){return $presenter->link("editujNovinku", array("id"=>$row['id']));})

(nevím jestli tímto volám action nebo render, ale předpokládám, že action po kterém se zavolá render se stejným jménem)

db model:

public function vratPoleHodnot($id)
        {
            return $this->db->query("SELECT perex,text,datum_vlozeni as datePicker1 FROM novinky WHERE id=$id");
        }

výsledek je ten, že se mi bez chyby načte prázdný formulář, v čem může být chyba ? děkuji.

Editoval muflix (8. 9. 2012 15:05)

Felix
Nette Core | 1245
+
0
-

Vraci funkce vratPoleHodnot($id) spravna data? Tzn, vraci neco jako

array('id' => 2, 'perex' => 'text..',..);

Mozna bych zkusil

$this['editNovinkuForm']->setDefaults((array) $this->novinky->vratPoleHodnot($id));

Nebo

$this['editNovinkuForm']->setValues($this->novinky->vratPoleHodnot($id));

Editoval Felix (8. 9. 2012 15:45)

muflix
Člen | 92
+
0
-

děkuji za odpověď

$this['editNovinkuForm']->setDefaults((array) $this->novinky->vratPoleHodnot($id));

ani

$this['editNovinkuForm']->setValues($this->novinky->vratPoleHodnot($id));

mi nefunguje.
SQL mi vrací http://www.nahraj-obrazek.cz/?…. SQL dotaz mi vypsal takovy ten Nette panel. Nebo to mám vyzkoušet nějak jinak ?

Tomáš Votruba
Moderator | 1114
+
0
-

Dumpni si:

$defaults = (array) $this->novinky->vratPoleHodnot($id);
dump($defaults);

Defautls umí zpracovat pouze pole. Přetypování objektu pouhým (array) může změnit názvy klíčů. Na to je někdy lepší iterator_to_array či projet foreachem do nového pole, není-li jiná cesta.

Na debugování je dobrý tento postup:

dump($form->getValues(TRUE)); // před naplněním

dump(is_array(defaults)); // nutno TRUE
$form->setDefaults($defaults));

dump($form->getValues(TRUE)); // po naplnění, mělo by se lišit

Editoval Schmutzka (9. 9. 2012 2:00)

muflix
Člen | 92
+
0
-

aha, děkuji, ta funkce dump() je dobra :)

upravil jsem akci na

public function actionEditujNovinku($id)
        {
                /* debug */
                $defaults = (array)$this->novinky->vratPoleHodnot($id);
                dump($defaults);
                dump($this['editNovinkuForm']->getValues(TRUE)); // před naplněním
                dump(is_array($defaults)); // nutno TRUE
            /* predvyplneni formu + kontrola id zaznamu */
            $id = $this->kontrolaId($id);
            $this['editNovinkuForm']->setDefaults($this->novinky->vratPoleHodnot($id));

                dump($this['editNovinkuForm']->getValues(TRUE)); // po naplnění, mělo by se lišit

        }

a v html mi to vypsalo

array(6) {
   "\x00DibiResult\x00driver" => DibiMySqlDriver(4) {
      connection private => mysql link resource
      resultSet private => mysql result resource
      autoFree private => TRUE
      buffered private => TRUE
   }
   "\x00DibiResult\x00types" => array(3) {
      perex => "bin" (3)
      text => "bin" (3)
      datePicker1 => "t"
   }
   "\x00DibiResult\x00meta" => NULL
   "\x00DibiResult\x00fetched" => FALSE
   "\x00DibiResult\x00rowClass" => "DibiRow" (7)
   "\x00DibiResult\x00formats" => array(2) {
      d => NULL
      t => NULL
   }
}

array(3) {
   perex => ""
   text => ""
   datePicker1 => NULL
}

TRUE

array(3) {
   perex => ""
   text => ""
   datePicker1 => NULL
}

tak se mi to do toho pole ty hodnoty neukládaj, ale SQL mi je vrací, takže co by s tím mohlo být ?:P

llook
Člen | 407
+
0
-

vratPoleHodnot() ti nevrací pole hodnot, ale objekt typu DibiResult. Pokud z něj chceš dostat první řádek výsledku, tak na něm zavolej fetch().

muflix
Člen | 92
+
0
-

llook: supr dík, bylo to tim, už se mi to předvyplňuje paráda.. akorát mi to po uložení vrátí

Notice
Undefined variable: id

přičemž chybě rozumím, ale nevím jak ten parametr přidat do callbacku nebo kam jinam ho dát ?
akce vypadá takto

public function updateNovinku(Nette\Application\UI\Form $form)
        {
            $id = $this->kontrolaId($id);

            $values = $form->getValues();
            $this->novinky->updateTable($values,$id);

            $this->flashMessage("Record updated!", "success");
            $this->redirect("nifty-tb");
        }

callback takhle

$form->onSuccess[] = callback($this, 'updateNovinku');
muflix
Člen | 92
+
0
-

22: dekuji to sem cet asi 8 krat a nepochopil sem to z toho, ale ted mi to doslo a funguje to :)

muflix
Člen | 92
+
0
-

Ješte bych se chtěl zeptat, možná trochu off topic ale trochu to souvisí, nevím jestli mám dobře strukturu aplikace..
řekněme, že mám
Frontend jako HomepagePresenter.php (jeden hlavní layout a každá podstránka jako jiná .latte šablona)
Backend jako AdminPresenter.php (další hlavní layout a každá podstránka jako jiná .latte šablona)

a mě de o to, pokuď mám v administraci například 3 editační formuláře.. tak je vhodné je mít všechny v AdminPresenter.php nebo je lze nějak oddělit ?

teď bych to měl jako

public function renderEditujNovinku(){...}
public function actionEditujNovinku($id){...}
protected function createComponentEditNovinkuForm(){...}
public function updateNovinku(Nette\Application\UI\Form $form){...}


public function renderEditujClanek(){...}
public function actionEditujClanek($id){...}
protected function createComponentEditClanekForm(){...}
public function updateClanek(Nette\Application\UI\Form $form){...}

ale při složitější aplikaci by ten soubor mohl být dost nepřehledný.. mohl bych tedy oddělit ten formulář do vlastního presenteru třeba
novinkyPresenter.php
clanekPresenter.php

a pak to v render metodě přesměrovat na AdminPresenter třeba pomocí

$this->redirect('Admin:editujNovinku');

zajímalo by mě jaký je best practice jestli se to takto dělá, děkuji.

Editoval muflix (9. 9. 2012 20:15)