Jak dostat proměnnou do formuláře a jak ji pak vykreslit?

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

Ahoj hledal jsem, ale bohužel jsem nenašel. Nevíte jak dostat proměnnou do formuláře při vykreslování. Ukážu na kódu
mám presenter

$form->addContainer('obrazky');
			foreach($this->model->getObrazkyZbo()->where(array("zbozi_id" =>$data->id)) as $key => $dataa)
			{
				$form["obrazky"]->addText('nazev'.$key, 'Název souboru:')->setDefaultValue($dataa->nazev);
				$form["obrazky"]->addCheckBox('hlavni'.$key, 'Hlavní Obrázek:')->setDefaultValue($dataa->hlavni);
				** Zde bych chtěl proměnnou naplnit v závislosti na cyklu **
				$form["obrazky"]->promenna = $dataa->soubor;//toto neni dobre
			}

v sablone bych chtel

<tr n:foreach="$form['obrazky']->components as $obrazek">
                	<td>{$obrazek->label}</td>
                    <td>{$obrazek->control}</td>
                    <td>{* link Obrazek:default $obrazek->control *}$obrazek->promenna</td>{* toto takz spatne*}
                </tr>

Nevite prosim co s tim

Jan Endel
Člen | 1016
+
0
-

Nejčistějším řešením je pravděpodobně vyčlenit formulář do vlastní třídy, nějak takto:

use Nette\Application\UI\Form;

class FooForm extends Form
{

	private $bar;
	private $images;
	private $var;



	public function setBar($bar)
	{
		$this->bar = $bar;
	}



	public function setImages($images)
	{
		$this->images = $images;
	}



	public function build()
	{
		//...
		$imagesCon = $this->addContainer('obrazky');
                        foreach($images as $key => $dataa)
                        {
                                $imagesCon->addText('nazev'.$key, 'Název souboru:')->setDefaultValue($dataa->nazev);
                                $imagesCon->addCheckBox('hlavni'.$key, 'Hlavní Obrázek:')->setDefaultValue($dataa->hlavni);
                                $this->var = "whatEver";
                        }
		//....
	}

}

použití je pak jednoduché:

protected function createComponentFooForm
{
	$form = new FooForm();
	$form->setFoo("Lorem");
	$form->setImages($this->model->getObrazkyZbo()->where(array("zbozi_id" =>$data->id));

	$form->build();

	return $form;
}

a prosím odnauč se psát kód englishČesky

Editoval pilec (19. 1. 2012 21:36)

zoool
Člen | 89
+
0
-

Děkuji, a jak ji pak vykreslím v šablone? Stačí takto {$var} já si myslím že to nebude fungovat? Odnaučím se englishČesky ;-)

Editoval zoool (19. 1. 2012 21:57)

Jan Endel
Člen | 1016
+
0
-

Jo konečně jsem pochopil, co zamýšlíš, v tom případě rozhodně jednotlivé položky k obrázku patří ještě do vnořeného kontejneru (mít název prvku „nazev“.$key je fujík. Takže bych vytváření kontejneru upravil asi nějak takto:

$imagesCon = $this->addContainer('obrazky');
                       foreach($images as $key => $dataa)
                       {
				$imgCon = $imagesCon->addContainer($key);
                               $imgCon->addText('nazev'.$key, 'Název souboru:')->setDefaultValue($dataa->nazev);
                               $imgCon->addCheckBox('hlavni'.$key, 'Hlavní Obrázek:')->setDefaultValue($dataa->hlavni);
                               $this->var = "whatEver";
                       }

a pak lze v šabloně dělat:

{foreach $form['obrazek'] as $idImg => $container}
	<tr>
		{foreach $container->components as $component}
			<td>{$component->label}</td>
			<td>{$component->control}</td>
			<td>{$arrayOfValues[$idImg]}</td>
		{/foreach}
	<tr>
{/foreach}

kde $arrayOfValues je předané pole možných hodnot, ze kterých pomocí id obrázku taháš správný prvek. Trošku se mi to nepozdává, ale nevím proč. Možná mě někdo zkušenější ještě poopraví.

zoool
Člen | 89
+
0
-

Super nápad děkuji vyzkouším

zoool
Člen | 89
+
0
-

Nevím nějak mi to nefunguje, někde bude chyba přidal jsem do render naplnění do šablony $this->var , tak už se k ni dostanu, ale není naplněna :-(

Jan Endel
Člen | 1016
+
0
-

ukaž jak ji plníš a co chceš, aby obsahovala.

zoool
Člen | 89
+
0
-

Mám inicializovanou proměnnou

public $var = array();

toto mám v komponente

$obrazky = $form->addContainer('obrazky');
			foreach($this->model->getObrazkyZbo()->where(array("zbozi_id" =>$data->id)) as $key => $dataa)
			{

				$obrazek = $obrazky->addContainer($key);
				$obrazek->addText('nazev', 'Název souboru:')->setDefaultValue($dataa->nazev);
				$obrazek->addCheckBox('hlavni', 'Hlavní Obrázek:')->setDefaultValue($dataa->hlavni);
				$this->var[$key] = $dataa->soubor;

			}

toto mám render

public function renderEdit($id){

		$this->template->var = $this->var;

	}

A toto v šabloně

<table n:foreach="$form['obrazky']->components as $key => $obrazekyCon">
            	<tr n:foreach="$obrazekyCon->components as $obrazek">
                	<td>{$obrazek->label}</td>
                    <td>{$obrazek->control}</td>
                    <td>{* link Obrazek:default $obrazek->control *}</td>
                </tr>
                <tr>
                	<td>{$var[$key]}</td>
                </tr>
      </table>
zoool
Člen | 89
+
0
-

Napíše mi to chybu
**Notice

Undefined offset: 1 **
na řádku

 <?php $iterations++; endforeach; array_pop($_l->its); $iterator = end($_l->its) ?>
125:                    <tr>
126:                        <td><?php echo Nette\Templating\DefaultHelpers::escapeHtml($var[$key], ENT_NOQUOTES) ?></td>
127:                    </tr>
128:          </table>
Jan Endel
Člen | 1016
+
0
-

předpokládám, že to máš vše ve dvou souborech (presenter + šablona), zkus dumpnout obsah $var a nastav ji jako private, není důvod, aby bylu public, to jen tak na okraj.

zoool
Člen | 89
+
0
-

Ahoj, samozřejmě mám to oddělené a proměnná var je NULL prázdná

Jan Endel
Člen | 1016
+
0
-

Já jsem takové pako, dyť jě to vidět na první pohled. Nette funguje tak, že stránku vygeneruje a pakliže narazí na vykreslitelnou komponentu, teprve potom zavola createComponent, takže se render volá před createComponent a var je tím prázdný. Ideálně to asi uděláš tak, když var bude zcela nezávislá na formu a budeš do ní přímo sypat data z modelu.

zoool
Člen | 89
+
0
-

Ahoj jj už to funguje díky…

22
Člen | 1478
+
0
-

pilec napsal(a):

takže se render volá před createComponent a var je tím prázdný.

Fakt?!

Jan Endel
Člen | 1016
+
0
-

22 napsal(a):

pilec napsal(a):

takže se render volá před createComponent a var je tím prázdný.

Fakt?!

Pokud se pletu, tak mě prosím oprav, rád se přiučím.

22
Člen | 1478
+
0
-

mno:

final class HomepagePresenter extends BasePresenter
{
    protected function createComponentTest()
    {
        firelog('component');
        return new \Nette\Application\UI\Form();
    }

    public function actionDefault()
    {
        firelog('action');
    }

    public function renderDefault()
    {
        firelog('render');
    }
}
action
render
component

a když si zavolám komponentu v action, kde by se měla plnit daty:

final class HomepagePresenter extends BasePresenter
{
    protected function createComponentTest()
    {
        firelog('component');
        return new \Nette\Application\UI\Form();
    }

    public function actionDefault()
    {
	firelog('action');
        $form = $this->getComponent('test');
    }

    public function renderDefault()
    {
        firelog('render');
    }
}
action
component
render

..tak nevím

Editoval 22 (21. 1. 2012 10:47)

Jan Endel
Člen | 1016
+
0
-

Ok díky za objasnění.

Filip Procházka
Moderator | 4668
+
0
-

Nevidím důvod, proč se spoléhat na nějaké pořadí render a createComponent, když to jde napsat tak, aby to bylo jedno

protected function createComponentForm()
{
	return new MyForm($this->imagesModel);
}

Stačí si na to správně napsat komponentu.

use Nette\Application\UI\Form;
class MyForm extends Form
{
	private $images;
	public function __construct($images)
	{
		parent::__construct();
		$this->images = $images;

		$images = $form->addContainer('images');
		foreach ($this->images->getImage() as $image) {
			$container = $images->addContainer($image->id);
			$container->addText('nazev', 'Název souboru:')
				->setDefaultValue($image->name);
			$container->addCheckBox('hlavni', 'Hlavní Obrázek:')
				->setDefaultValue($image->main)
		}

		$this->addSubmit('send', Odeslat);
		$this->onSubmit[] = callbac($this, 'handleSubmit');
	}

	public function handleSubmit(Form $form)
	{
		dump($form->values)
	}
}

Teď je ti jedno, kdy komponentu vytvoříš, vždy se ale vytvoří až během akce, nebo po ní, můžeš toho tedy využít a upravit její vytváření a něco jí předat z akce

private $item;

public function actionDefault($id)
{
	$this->item = $this->imagesModel->find($id);
	if (!$this->item) {
		throw new Nette\Application\BadRequestException;
	}

	// ...
}

protected function createComponentForm()
{
	if (!$this->item) {
		throw new Nette\Application\BadRequestException;
	}

	// předám item a můžu s ním tedy pracovat v komponentě
	return new MyForm($this->imagesModel, $this->item);
}
Jan Endel
Člen | 1016
+
0
-

přesně tak jsem to radil na začátku (akorát jsem šel cestou setru namísto konstruktoru). Pak ale zoool chtěl s formulářem vykreslit i nahraný obrázek, což mu přímo tahle komponenta neumožní …

Filip Procházka
Moderator | 4668
+
0
-

Těžko by mu to umožnila, když jsme ji měl napsanou za 2 minuty a je to jenom ukázka :)

bene
Člen | 82
+
0
-

Možná by to šlo přes setOption… Asi to není úplně nejpěknější řešení, protože setOption by k tomuto asi sloužit neměla, ale je to ryclé řešení.

$form["obrazky"]->addText('nazev'.$key, 'Název souboru:')->setDefaultValue($dataa->nazev)
	->setOption('myFile', $dataa->soubor);
<td>{$form['obrazky']['myImageKey']->getOption('myFile')}</td>