znovupouzitelne formulare, generovana tovarnicka a nejlepsi mozne reseni

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

Zdravim kolegy nettisty.
Snazim se po delsi dobe dostat do Nette FW a jeho novinek. Momentalne resim tema znovupouzitelnych formularu a rad bych nasel nejake „best“ reseni. Prosel jsem forum a poskladal si dokupy snad par dulezitych informaci.

  1. formulare neresit dedenim tridy UI/Form ale radeji tovarnou
  2. vyuzit generovane tovarnicky a nastrkat pomoci DI zavislosti

Porad jsem ale asi nedal do kupy to COOL reseni a vlastne ani nevim jesi to reseni aby trida s formularem obstaravala jak pridani noveho zaznamu tak editaci je to nejlepsi.

hodim sem nastrel toho k cemu jsem se zatim dostal, tech variant bylo hodne ale uz potrebuji dat dohromady nejakou funkcnost tak jsem prozatim na tomto reseni

Formular

<?php

namespace MyWApp\Security\Components;

use Nette\Object;
use MyWApp\Application\UI\Form;
use MyWApp\Security\Model\Role;
use MyWApp\Security\Model\User;

class UserForm extends Object
{
	/** @var  User */
	private $user;
	/** @var  Role */
	private $role;

	public function __construct(User $user, Role $role)
	{
		$this->user = $user;
		$this->role = $role;
	}

	private function createBaseForm()
	{
		$form = new Form();
		$form->addText('username', 'Username')->addRule(Form::FILLED);
		$form->addText('password', 'Password')->addRule(Form::FILLED);
		$form->addText('email', 'Email')->addRule(Form::EMAIL);
		$form->addSelect('role_id', 'Role', $this->role->findAllForSelectBox());
		$form->addHidden('id');

		return $form;
	}

	public function createAddForm()
	{
		$form = $this->createBaseForm();

		$form->addSubmit('sub', 'Create');

		$form->onSuccess[] = array($this, 'processAdd');

		return $form;
	}

	public function createEditForm()
	{
		$form = $this->createBaseForm();

		$form->addSubmit('sub', 'Save');

		$form->onSuccess[] = array($this, 'processEdit');

		return $form;
	}

	/**
	 * @param Form $form
	 */
	public function processAdd(Form $form)
	{
		$values = $form->values;

		$this->user->add($values->username, $values->password, $values->email, $values->role);
	}

	/**
	 * @param Form $form
	 */
	public function processEdit(Form $form)
	{
		//$values = $form->values;

		//$this->user->add($values->username, $values->password, $values->email, $values->role);
	}

}

Presenter

	protected function createComponentAddUserForm()
	{
		$form = $this->userFormfactory->create();

		$x = $form->createAddForm();

		$x->onSuccess[] = function() use ($this) {
			$this->flashMessage('data pridana');
		};

		return $x;
	}

	protected function createComponentEditUserForm()
	{
		$form = $this->userFormfactory->create();

		$x = $form->createEditForm();

		$x->onSuccess[] = function() use ($this) {
			$this->flashMessage('data zmenena');
		};

		return $x;
	}

nereste nazvy promennych apod. mam to jen v testovacim presenteru.. chtel jsem docilit toho mit jen jednu tovarnu userForm, ktera by resila jak pridavani a v pripade parametru i editaci, ale narazil jsem na problem jak napr. spravne poslat flash message podle toho zda byla data pridana nebo editovana, atd..

Mate nejake vami uprednostnovane reseni?

Edit: jo a napr. sem nikde v dokumentaci nenasel, ze ten formular nemusi vubec ten interface na generovanou tovarnicku implementovat a vubec nemusi mit metodu create() :)

Editoval tomees (11. 9. 2014 15:44)

David Matějka
Moderator | 6445
+
+5
-

nejlepsi je samozrejme formular jako komponenta :)

tomees
Člen | 59
+
0
-

„Pokud chceme, aby se formulář renderoval specifickým způsobem“ no to ja nepotrebuji :) resp. ano, ale chci si ten formular tvorit opet v presenterech a jinych komponentach… chci ho mit jen jako soucast sve knihovny a samotne sablony a konkretni komponenty resit az v konkretni aplikaci :)

David Matějka
Moderator | 6445
+
0
-

Je nekolik moznosti, jak ten formular vyrenderovat

  1. renderuje to komponenta

1a) „rychle“ automaticke renderovani bez sablony

public function render()
{
	$this['form']->render();
}

1b) pomoci vlastni sablony

public function render()
{
	$this->template->setFile(cesta_k_souboru);
	$this->template->render();
}

a sablona

{control form}
nebo rucne
{form form}
...
{/form}

a je taky uzitecne vytvorit komponente setter, treba setTemplateFile, pomoci ktereho nastavis/zmenis sablonu

  1. komponenta se nebude vykreslovat sama, formular vykresli presenter
public function createComponentMyForm()
{
	return $this->myFormFactory->create();
}

(to vytvori komponentu, ktera ma formular v createComponentForm
a v sablone presenteru

{form myForm-form}
manualni renderovani
{/form}

nebo automaticke renderovani

{control myForm-form}
tomees
Člen | 59
+
0
-

No dobre, kdyz bych pristoupil na toto reseni, stale stojim pred otazkou „Jak to udelat, abych resil jednou komponentou jak pridani, tak editaci?

Editoval tomees (11. 9. 2014 16:32)

David Matějka
Moderator | 6445
+
+2
-

pridej si do ty komponenty a tovarnicky parametr – treba id, radek z databaze, entitu. To budes z presenteru posilat a komponenta se pak rozhodne, co s tim. treba

interface FooFormFactory
{
	/**
	* @return FooForm
	*/
	public function create($id = NULL)
}
class FooForm extends UI\Control
{
	protected $id;

	public function __construct($id, dalsi zavislosti)
	{
		$this->id = $id;
	}

	public function processForm(Form $form)
	{
		if($this->id) {
		...
		} else {
...
		}
	}
}

a neon

services:
	-
		implement: FooFormFactory
		parameters: [id: null] #teda doufam, ze to takhle jde
		arguments: [%id%]
Michal Vyšinský
Člen | 608
+
0
-

Ahoj. Dovolím si odkázat na svůj článek (en) http://www.vysinsky.cz/…nette-forms/ tento způsob používám a jsem s ním naprosto spokojený.

tomees
Člen | 59
+
0
-

Michal: diky, toto reseni je podobne tomu co jsme pouzivali jeste v dobach kdy nebylo DI, ale s DI to vypada lepe no, vyzkousim