Ukladanie jedneho formulara do dvoch tabuliek
- majo1
- Člen | 103
Zdravim, mam otazku.
v modeli ukladam formular do DB,
v presenteri vytvaram formular pomocou nette forms, podla dokumentacie a
v latte formular vykreslujem, cez jQuery chcem spravit „viac-krokovy
formular“
Otazne je ale, ci sa da formular spravit tak, aby ukladal nejake hodnoty do jednej tabulky a nejake hodnoty do druhej tabulky, po stlaceni Submit buttonu.
Dakujem velmi pekne za vsetky odpovede :)
Editoval majo1 (1. 2. 2016 10:59)
- majo1
- Člen | 103
http://oi66.tinypic.com/xbzng6.jpg
instalovane cez composer, – WebChemistry\Forms\Controls\DI\WizardExtension
mam v configu
Editoval majo1 (1. 2. 2016 11:48)
- David Matějka
- Moderator | 6445
hm, ono v dokumentaci chybi, ze musis v presenteru vytvorit tovarnu na ten wizard, neco jako
protected function createComponentWizard()
{
return new Wizard(); //se spravnym namespacem
}
- majo1
- Člen | 103
pardon, toto je screen, ktory som chcel poslat: http://oi63.tinypic.com/dpea20.jpg
David Matějka napsal(a):
hm, ono v dokumentaci chybi, ze musis v presenteru vytvorit tovarnu na ten wizard, neco jako
protected function createComponentWizard() { return new Wizard(); //se spravnym namespacem }
- pata.kusik111
- Člen | 78
Používáš namespace v souboru, kte vytváříš tu svoji komponentu. Jednoduchá oprava je na řádku 13 za „extends“ před jestu k extendované class přidat lomítko.
- David Matějka
- Moderator | 6445
vypada to, ze ta trida se spravne jmenuje
\WebChemistry\Forms\Controls\Wizard
- majo1
- Člen | 103
ach.. asi zostanem pri povodnom plane → na formular vykresleny v latte aplikovat tento script :)
a dalej upravit v modeli tento dopyt na databazu (neviem presne kvoli dokumentacii, ako na to)
public function saveReservationform($reservationform)
{
if (!$reservationform[self::COLUMN_ID])
$this->database->table(self::TABLE_NAME)->insert($reservationform);
}
- David Matějka
- Moderator | 6445
ach.. asi zostanem pri povodnom plane
no to se ti nic nezmeni na tom, ze reservationformpresenter bude muset dedit od presenteru
a dalej upravit v modeli tento dopyt na databazu (neviem presne kvoli dokumentacii, ako na to)
a ja nevim, na co se ptas. hlasi to nejakou chybu?
- majo1
- Člen | 103
moja chyba je, ze som nezacal s hlavnym problemom, najpodstatnejsou
vecou.
ide mi v principe o toto:
mam nasledujuci model:
<?php
namespace App\Model;
use App\Model\BaseManager;
use Nette\Database\Table\IRow;
use Nette\Database\Table\Selection;
use Nette\Utils\ArrayHash;
class ReservationformManager extends BaseManager
{
const
TABLE_NAME = 'reservations',
COLUMN_ID = 'idreservation',
CUSTOMERSTABLE_NAME = 'customers',
CUSTOMERSCOLUMN_ID = 'idcustomer',
SKIBUSTABLE_NAME = 'skibuses',
SKIBUSCOLUMN_ID = 'idskibus',
STATIONTABLE_NAME = 'stations',
STATIONCOLUMN_ID = 'idstation',
CENTERTABLE_NAME = 'centers',
CENTERCOLUMN_ID = 'idcenter';
public function saveReservationform($reservationform)
{
$this->database->table(self::TABLE_NAME)->insert($reservationform);
}
public function getCenter()
{
return $this->database->table(self::CENTERTABLE_NAME)->order(self::CENTERCOLUMN_ID . ' ASC');
}
public function getStation()
{
return $this->database->table(self::STATIONTABLE_NAME)->order(self::STATIONCOLUMN_ID . ' ASC');
}
public function getSkibus()
{
return $this->database->table(self::SKIBUSTABLE_NAME)->order(self::SKIBUSCOLUMN_ID . ' DESC')->limit(10);
}
}
nasledujuci presenter:
<?php
namespace App\Presenters;
use App\Model\ReservationformManager;
use App\Presenters\BasePresenter;
use Nette\Application\BadRequestException;
use Nette\Application\UI\Form;
use Nette\Application\UI\Presenter;
use Nette\Database\UniqueConstraintViolationException;
class ReservationformPresenter extends BasePresenter
{
protected $reservationformManager;
public function __construct(ReservationformManager $reservationformManager)
{
parent::__construct();
$this->reservationformManager = $reservationformManager;
}
public function renderDefault()
{
}
protected function createComponentEditorForm()
{
$form = new Form;
$form->addHidden('idreservation');
$form->addHidden('datetime');
$form->addText('numAdult', 'Počet dospelých:')
->addRule(Form::RANGE, 'Musí byť v rozsahu %d až %d', array(0, 100))
->setDefaultValue('0')
->setType('number')->setRequired();
$form->addText('numJunior', 'Počet juniorov:')
->addRule(Form::RANGE, 'Musí byť v rozsahu %d až %d', array(0, 100))
->setDefaultValue('0')
->setType('number')->setRequired();
$form->addText('numKid', 'Počet detí:')
->addRule(Form::RANGE, 'Musí byť v rozsahu %d až %d', array(0, 100))
->setDefaultValue('0')
->setType('number')->setRequired();
$form->addText('numTransportOnly', 'Len doprava:')
->addRule(Form::RANGE, 'Musí byť v rozsahu %d až %d', array(0, 100))
->setDefaultValue('0')
->setType('number')->setRequired();
$result = $this->reservationformManager->getCenter();
$centers = $result->fetchPairs('idcenter', 'centerName');
$form->addSelect('center_idcenter', 'Stredisko:', $centers);
$result = $this->reservationformManager->getStation();
$stations = $result->fetchPairs('idstation', 'city');
$form->addSelect('station_idstation', 'Zastávka:', $stations);
$result = $this->reservationformManager->getSkibus();
$skibus = $result->fetchPairs('idskibus', 'departureDatetime');
$form->addSelect('skibus_idskibus', 'Skibus:', $skibus);
$form->addText('name', 'Meno:')
->setType('text')->setRequired();
$form->addText('surename', 'Priezvisko:')
->setType('text')->setRequired();
$form->addText('telephone', 'Telefónne číslo:')
->setType('text')->setRequired();
$form->addText('email', 'E-mail:');
$form->addSubmit('submit', 'Rezervovať skibus');
$form->onSuccess[] = [$this, 'editorFormSucceeded'];
return $form;
}
public function editorFormSucceeded($form, $values)
{
try {
$this->reservationformManager->saveReservationform($values);
$this->flashMessage('Rezervácia bola úspešná.');
$this->redirect(':Reservationform:', $values->idreservation);
} catch (UniqueConstraintViolationException $ex) {
$this->flashMessage('Rezervácia s týmto ID už existuje!');
}
}
}
- majo1
- Člen | 103
a latte
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" href="{$basePath}/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
<link rel="stylesheet" href="{$basePath}/dist/css/AdminLTE.min.css">
<link rel="stylesheet" href="{$basePath}/dist/css/skins/skin-blue.min.css">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<form n:name=editorForm class=form>
<div n:if="$form->hasErrors()" class="callout callout-warning">
<h4>Chyba!</h4>
<p n:foreach="$form->errors as $error">{$error}</p>
</div>
<div class="form-group">
<label n:name=center_idcenter>Stredisko*</label>
<select n:name=center_idcenter class="form-control">
<option></option>
</select>
</div>
<div class="form-group">
<label n:name=skibus_idskibus>Skibus*</label>
<select n:name=skibus_idskibus class="form-control">
<option></option>
</select>
</div>
<div class="form-group">
<label n:name=station_idstation>Zastávka*</label>
<select n:name=station_idstation class="form-control">
<option></option>
</select>
</div>
<div class="input-group">
<label n:name=numAdult>Počet dospelých*
<div class="input-group">
<input type="number" min="0" max="100" class="form-control" n:name=numAdult>
<div class="input-group-addon">
<i class="fa fa-child"></i>
</div>
</div>
</label>
</div>
<div class="input-group">
<label n:name=numJunior>Počet juniorov*
<div class="input-group">
<input type="number" min="0" max="100" class="form-control" n:name=numJunior>
<div class="input-group-addon">
<i class="fa fa-child"></i>
</div>
</div>
</label>
</div>
<div class="input-group">
<label n:name=numKid>Počet detí*
<div class="input-group">
<input type="number" min="0" max="100" class="form-control" n:name=numKid>
<div class="input-group-addon">
<i class="fa fa-child"></i>
</div>
</div>
</label>
</div>
<div class="input-group">
<label n:name=numTransportOnly>Len doprava*
<div class="input-group">
<input type="number" min="0" max="100" class="form-control" n:name=numTransportOnly>
<div class="input-group-addon">
<i class="fa fa-bus"></i>
</div>
</div>
</label>
</div>
<div class="input-group">
<label n:name=name>Meno*
<div class="input-group">
<input class="form-control" n:name=name>
<div class="input-group-addon">
<i class="fa fa-user"></i>
</div>
</div>
</label>
</div>
<div class="input-group">
<label n:name=surename>Priezvisko*
<div class="input-group">
<input class="form-control" n:name=surename>
<div class="input-group-addon">
<i class="fa fa-user"></i>
</div>
</div>
</label>
</div>
<div class="input-group">
<label n:name=telephone>Telefón*
<div class="input-group">
<input class="form-control" n:name=telephone>
<div class="input-group-addon">
<i class="fa fa-phone"></i>
</div>
</div>
</label>
</div>
<div class="input-group">
<label n:name=email>E-mail
<div class="input-group">
<input class="form-control" n:name=email>
<div class="input-group-addon">
<i class="fa fa-envelope"></i>
</div>
</div>
</label>
</div>
<p><input n:name=submit class="btn btn-primary"></p>
</form>
<script src="http://momentjs.com/downloads/moment.min.js"></script>
<script src="{$basePath}/plugins/jQuery/jQuery-2.1.4.min.js"></script>
<script src="{$basePath}/bootstrap/js/bootstrap.min.js"></script>
<script src="{$basePath}/plugins/datatables/dataTables.bootstrap.min.js"></script>
<script src="{$basePath}/dist/js/app.min.js"></script>
<script src="{$basePath}/dist/js/demo.js"></script>
<link rel="stylesheet" href="{$basePath}/plugins/timepicker/bootstrap-timepicker.min.css">
<script src="{$basePath}/plugins/timepicker/bootstrap-timepicker.min.js"></script>
<link href="//cdn.rawgit.com/Eonasdan/bootstrap-datetimepicker/e8bddc60e73c1ec2475f827be36e1957af72e2ea/build/css/bootstrap-datetimepicker.css" rel="stylesheet">
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/moment-with-locales.js"></script>
<script src="//cdn.rawgit.com/Eonasdan/bootstrap-datetimepicker/e8bddc60e73c1ec2475f827be36e1957af72e2ea/src/js/bootstrap-datetimepicker.js"></script>
<script type="text/javascript">
$(function () {
$('#datetimepicker2').datetimepicker({
locale: 'sk',
useCurrent: true,
format: 'YYYY-MM-DD HH:mm'
});
});
</script>
<script>
$(function () {
//Timepicker
$(".timepicker").timepicker({
showInputs: false,
showMeridian: false,
minuteStep: 1,
defaultTime: 'current',
format: 'HH:mm'
});
});
</script>
</body>
</html>
screen latte: tu
screen tracy po odkliknuti tlacidla: tu
neviem formular upravit tak, aby sa udaje o zakaznikovi (stlpce name,
surename, telephone, mail) ukladali do tabulky customers a nie do tabulky
reservations.
resp. tabulky reservations a customers maju spolu vztah 1:n
latte budem upravovat, je tam kopu zbytocnosti.. v podstate ide o formular a k nemu administraciu (ktora by mala byt funkcna)
zaroven potrebujem, aby sa pri zvoleni strediska (centers) vyfiltrovali zastavky (stations) a skibusy (skibuses) len pre to urcite stredisko.
dakujem
Editoval majo1 (1. 2. 2016 14:55)
- David Matějka
- Moderator | 6445
a kde je problem? proste nektery prvky z toho pole (resp hash mapy) vlozis
do jedny tabulky, nektery do druhy. Pro logicky rozdeleni formulare muzes pouzit
containery a ve
$values
budes mit ty data rozdeleny
- David Matějka
- Moderator | 6445
@majo1 jako nazev toho inputu pouzijes nazev kontejneru a nazev inputu
oddeleny pomlckou, tedy treba
{input address-name}
resp.
<input n:name="address-name"/>
kde address je nazev
kontejneru a name nazev inputu
- majo1
- Člen | 103
dakujem, uz to funguje,
v modeli som insertol data takto:
29:
$this->database->table(self::TABLE_NAME)->insert($reservationform->resdetail);
30:
$this->database->table(self::TABLE_NAME)->insert($reservationform->custdetail);
len som asi zle vytvoril tabulky alebo zle insertujem :D
tracy:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a
child row: a foreign key constraint fails
(nitransform
.reservations
, CONSTRAINT
fk_reservation_customer1
FOREIGN KEY
(customer_idcustomer
) REFERENCES customers
(idcustomer
) ON DELETE NO ACTION ON UPDATE NO ACTION)
- majo1
- Člen | 103
takto https://unsee.cc/gusedami/ vyzera moja db.
nenapada mi, ako to spravne vlozit.
pri insertnuti informacii o zakaznikovi by sa malo jeho auto-incrementnute
id niekde zapamatat a nasledne insertnut do rezervacie
neviem, ako na to :/
Editoval majo1 (2. 2. 2016 15:10)
- David Matějka
- Moderator | 6445
vloz do tabulky customers a to ti vrati radek s prirazenym ID, ktery muzes pouzit pro insert do reservations
- majo1
- Člen | 103
moj model:
const
TABLE_NAME = 'reservations',
COLUMN_ID = 'idreservation',
CUSTOMERSTABLE_NAME = 'customers',
CUSTOMERSCOLUMN_ID = 'idcustomer',
public function saveReservationform($reservationform)
{
$this->database->table(self::CUSTOMERSTABLE_NAME)->insert($reservationform->custdetail);
$this->database->table(self::TABLE_NAME)->insert($reservationform->resdetail);
}
, tracy pise stale
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update
a child row: a foreign key constraint fails
(nitransform
.reservations
, CONSTRAINT
fk_reservation_customer1
FOREIGN KEY
(customer_idcustomer
) REFERENCES customers
(idcustomer
) ON DELETE NO ACTION ON UPDATE NO ACTION)
pricom odkazuje chybu pri inserte $reservationform->resdetail :/
- majo1
- Člen | 103
už som to vyriešil :) pri inserte mi vynechávalo jeden FK. preto ta chyba…
teraz sa snazim zisit, co by bolo lepsie.
vo formulari je select box a od neho zavisi, ake udaje sa budu do DB
nahravat.
asi pomocou uz spomenuteho https://componette.org/…orms-wizard/
len akosi to neviem rozbehat.. :/ chcelo by to nejaky priklad
- majo1
- Člen | 103
ten priklad neviem vo svojom projekte implementovat :/
v configu mam spomenuty extension pridany,
toto je moj presenter WizardPresenter.php
<?php
namespace App\Presenters;
use App\Presenters\BasePresenter;
use Nette\Application\BadRequestException;
use Nette\Application\UI\Form;
use Nette\Application\UI\Presenter;
use Nette\Database\UniqueConstraintViolationException;
class WizardPresenter extends \WebChemistry\Forms\Controls\Wizard {
protected function finish() {
$values = $this->getValues();
}
protected function createStep1() {
$form = $this->getForm();
$form->addText('name', 'Uživatelské jméno')
->setRequired();
$form->addSubmit(self::NEXT_SUBMIT_NAME, 'Další');
return $form;
}
protected function createStep2() {
$form = $this->getForm();
$form->addText('email', 'Email')
->setRequired();
$form->addSubmit(self::PREV_SUBMIT_NAME, 'Zpět');
$form->addSubmit(self::FINISH_SUBMIT_NAME, 'Registrovat');
return $form;
}
}
toto moje latte Wizard/default.latte
<div n:wizard="wizard">
<ul n:if="!$wizard->isSuccess()">
<li n:foreach="$wizard->steps as $step" n:class="$wizard->isDisabled($step) ? disabled, $wizard->isActive($step) ? active"><a n:tag-if="$wizard->useLink($step)" n:href="changeStep! $step">{$step}</a></li>
</ul>
{step 1}
{control $form}
{/step}
{step 2}
{control $form}
{/step}
{step success}
Úspěšně jste se registroval/a.
{/step}
</div>
a po otvoreni stranky wizard, mi pise chybu:
Nette\Application\BadRequestException #404
Cannot load presenter ‚Wizard‘, class ‚App\Presenters\WizardPresenter‘
was not found.
chyba na:
$container->getByType(‚Nette\Application\Application‘)->run();