Předání dat mezi formulari

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

Zdravím, potřeboval bych poradit jak udělat asi základní věc, ale v nette začínám.

Mám tabulky v databázi PRODEJ, vazební OBSAHOVAL (pk_lek, pk_prodej) a s lékama LEK.

Chtěl jsem dělat prodeje léků tak, že vytvořím prodej pomocí formuláře v presenteru prodej (vytvoří se položka tabulky prodej) a po vytvoření, že se udělá redirect na šablonu „pridat lek do prodeje“, a tam je formulář pro nové tabulky obsahoval.

Problém: Po odeslání formulare pro vytvoreni prodeje v metode OnSubmit znam PK prave vytvorenoho prodeje pres zavalani getPrimary na activeRow co vrati insert. Potom dam redirect na formular pro pridavani leku do tabulky OBSAHOVAL, jenže teď už v metode OnSubmit pro tento formular nemám active row z toho insertu do prodeje a nevim jak ziskat PK prodeje ktery jsem prave vytvoril abych mohl pridavat leky.

Zkousel sem si ten PK ulozit do promenne, zkousel sem i statickou promennou ale tomu nerozumim, zkousel jsem to jako argument redirectu, ale to pak zas nevim jak a kde ho vyzvedout. Nebo to nejak narvat do POST a pak zas nejak vyzvednout, nevim…

Jdu na to správně nebo mám celý problém řešit úplně jinak?

kod:

public function prodejFormSubmitted($button)
{
$values = $button->getForm()->getValues();
$pojcislo = $values['pojistovna_cislo'];

$this->actRow = $this->prodejs->createProdej($pojcislo);
$this->obsahovalRep->insert(
array('lek_kod' => $values["lek"],
'prodej_id' => $this->actRow->getPrimary()
));
$this->flashMessage('Prodej vytvořen.');

$this->setId($this->actRow->getPrimary()); // TADY TO ID znam

 $this->redirect('nextlek', array('id' => $this->actRow->getPrimary()));  // Toto sem jen zkosusel nejak to id protlacit....

}

public function nextlekFormSubmitted($button)
{
// $this->actId = $id;
$httpRequest = $this->context->httpRequest;
//$id = $httpRequest->getPost('id');
//$id = $this->getId();

$values = $button->getForm()->getValues();


for($i = 1; $i <= $values['kusu']; $i++)
{
$this->obsahovalRep->insert(
array('lek_kod' => $values["lek"],
  'prodej_id' => $this->omgId                   // TADY to ID potrebuju
));
}
$this->flashMessage('Položka přidána.');

$this->redirect('nextlek', $this->actId);
}

Díky za reakce

hAssassin
Člen | 293
+
0
-

Myslím, že na to jdeš dobře. V prvním formuláři přesměruj na druhý presenter s parametrem ID, což je ID právě přidané položky. Akorát že v tom druhým presenteru bys asi měl nejdřív už v action metodě vzít to ID, vytáhnout z modelu daný „prodej“ a ten si uložit do property třídy (samozřejmě že by se zde hodilo i ověření jestli prodej s daným ID existuje apod) a pak v nextlekFormSubmitted() použít ten. Tedy nějak takto (druhý presenter):

class DruhyPresenter extends BasePresenter {

	private $prodej = NULL;

	public function actionDefault($id)
	{
		$this->prodej = $this->prodejModel->findById($id);
		if(!$this->prodej) {
			throw new BadRequestException; // prodej neexistuje nebo cokoliv
		}
	}

	public function nextlekFormSubmitted($button)
	{
		$values = $button->getForm()->getValues();
		// ...
		array('lek_kod' => $values["lek"],
			'prodej_id' => $this->prodej->id;
		));
		// ...
		$this->redirect('nextlek', $this->actId);
	}
}

Další možností je to přidat uz při vytváření formuláře jako ‚LekForm‘ jako hidden pole, ale tohle si myslím je lepší způsob. No a poslední možností co mě teď napadá je už při vytvoření prodeje v prvním presenteru uložit to ID do session a pak si ho vytáhnout v nextlekFormSubmitted(). Ale to se mi taky moc nezamlouvá. Takže asi tak.

mildabre
Člen | 62
+
0
-

Moc se mě nelíbí jaké Jsi si zvolil názvy tabulek, raději dodržuj osvědčenou konvenci pro názvy spojovacích tabulek i cizí klíče. Spojovací tabulka obsahuje by se měla spíše jmenovat prodej_lek. Cizí klíče v tabulce prodej_lek bych pojmenoval prodej_id a lek_id.

V metodě prodejFormSubmitted($button) přenášíš parametr $button, není zveřejněn kód toho formuláře prodejForm takže nevím jak to tam zachycuješ, ale lepší by bylo zachytit událost celého formuláře $form->onSucceed[] = $this->prodejFormSubmitted, potom by Jsi přenesl jako parametr místo $button $form:

public function prodejFormSubmitted(Form $form)

a místo

$values = $button->getForm()->getValues();

by Jsi psal jednodušeji:

$values = $form->getValues();

Automatické přesměrování na formulář pro přidání léku se mě zdá zbytečně manipulativní technika – raději bych po vytvoření prodeje přesměroval zpátky na stejný formulář a přidal tam tlačítko „Přidat lék“, které by teprve vyvolalo ten druhý formulář pro přidání léku (nejlépe událostí onClick[] v níž by se na druhý formulář přesměrovalo). Uživatel by tak sám rozhodoval kdy si formulář pro další lék vyvolá.

Formulář pro přidání léku potřebuje znát id prodeje a to nejlépe předat v URL v get stringu (za otazníkem). Nette automaticky předá parametry které nejsou v masce Routeru do tohoto get stringu. Parametr definuješ v presenteru kupříkladu takto:

$this->params['prodej_id'] = $prodej_id

nebo můžeš parametr zapsat do toho přesměrování nějak takto (parametr který není v masce routeru musí mít definován klíč ⇒ hodnota a dostane se automaticky do get stringu v URL):

$this->redirect('Presenter:action prodej_id => $prodej_id')

a po přesměrování se na ten parametr dostaneš takto:

$this->params['prodej_id']

V url by se Ti mělo objevit …?prodej_id=123 – to je právě ten parametr přenesený v get stringu.

Když se odešle přidaný lék zapíšeš v prvním kroku záznam do tabulky lek a odchytneš si lek_id nového záznamu a v druhém kroku zapíšeš záznam do spojovací tabulky prodej_lek kam dáš lek_id + prodej_id a to je vše.

Správnou programovací praktikou by bylo použít pro zápis do tabulek lek a prodej_lek tzv. transakci, aby se buďto zapsalo do obou nebo do žádné, jinak by Ti takto mohly vznikat sirotci v tabulce lek.

Editoval mildabre (8. 12. 2012 15:13)