zjištování změn hodnot ve formuláři
- h4kuna
- Backer | 740
Ahoj,
prosím vás existuje nějaka metoda, která mi po odeslání formuláře řekne ano teď je změněné políčko.
Mám editaci udajů o uživateli už předvyplněnou:
xyzPresenter.php
//$rows['surname'] = Vořežprut; data vybrána z db
$form->addText('surname', 'Příjmeni')
->setDefaultValue($rows['surname']);
vyrenderuje se:
<input type="text" name="surname" value="Vořežprut">
po odeslání mi příjde:
$data = $form->getValues();
//$data['surname']; bude tu: Novák data poslaná uživatelem
$form->isChangedValue('surname');//vrátí true
Pač kdyby toto fungovalo tak nemusím přeukládat příjmení nebo nejaký data vytáhnout z db ověřit a zase uložit do db.
Předem děkuji
EDIT
Hodnoty nastavené setDefaultValue() se nemusí nijak posílat přes request, když se po odeslání opět pouští zpracovává ten stejný formulář jen je po odelaní budu mít s čím porovnat.
Editoval matata (10. 8. 2010 16:15)
- Filip Procházka
- Moderator | 4668
uložil bych asi výchozí data pro formulář do session a použil array_diff_assoc
- h4kuna
- Backer | 740
HosipLan napsal(a):
uložil bych asi výchozí data pro formulář do session a použil array_diff_assoc
jako je to řešení pro tuto chvíli,
avšak se mi zdá zbytečný když nastavuju defaultní hodnoty tak není takový problém, aby si je framework uložil a pak porovnal.
Jak jsem psal nemusí se to ukládat do requestu když po odeslání probíhá opět ten samý nadefinovaný formulář a ty data se nemění které vytahnu z db, tak se znovu vytahnou a inicializujou
Editoval matata (10. 8. 2010 17:33)
- Ondřej Mirtes
- Člen | 1536
Tohle není bez použití sessions z principu možné.
Dostanu vyplněný formulář. Změním v něm nějaké hodnoty a odešlu.
Jak by framework měl zjistit, které hodnoty tam byly předvyplněné? Pokud
plnění výchozích hodnot provádíš v action* metodě, tak při novém
requestu ten databázový dotaz na hodnoty proběhne znova a i kdyby si to
formulář do momentu zpracování uložil někam vedle, nic neušetříš.
Pokud setDefaults()
voláš v render* metodě, tak formulář
nemá v momentě zpracování o původních hodnotách ani páru.
Pokoušel jsem se něco takového implementovat před dvěma týdny a pohořel jsem. Nejjednodušší bude, pokud si ten původní záznam vytáhneš v submit metodě formuláře a ty hodnoty ručně porovnáš.
- h4kuna
- Backer | 740
Ondřej Mirtes napsal(a):
Tohle není bez použití sessions z principu možné.
ja bych řekl že to je možné, ono zaleží asi jak to máš naimplementované ja formuláře tvořím továrničkami a vidím co mi to dává a že ten dotaz je zase stejný, pac mam url klasicke <presenter>/<action>/<id> a to id tam je i po odeslani formulare, no dobře i kdyby to bral pomocí sessions, aby se to nedalo v url měnit id, avšak u článků mi to nevadí, tak si zapamatuje výchozí hodnoty
EDIT
detaily implementace bych nechtěl probírat spíše zda je to užitčné?
Každopádně když jsi se o něco pokoušel, Majkl578 taky a já jsme hledal něco takového, tak asi ano?
Editoval matata (10. 8. 2010 19:07)
- David Grudl
- Nette Core | 8228
Upřímně řečeno, neumím si představit, k čemu by to bylo dobré. Je snazší zavolat jeden UPDATE, než SELECT + ověřování isChangedValue + UPDATE, ne?
- mlha
- Člen | 58
Mám trochu podobný problém.
Formulář se sestavuje postupně. Po každém odeslání se přidají nová
pole.
Protože je ale formulář už odeslaný, nefunguje u nových polí
setDefaultValue().
To zjišťování změn by se taky hodilo, provedl by se pouze test klíčových
form. prvků, které ovlivňují zobrazení podmíněných prvků.
- Panda
- Člen | 569
Ondra Mirtes má pravdu, i moje konstrukce s formuláři vypadají nějak takto
protected function createComponentMyForm()
{
$form = new AppForm();
//...
$form->onSubmit[] = callback($this, 'myForm_Submit');
}
public function myForm_Submit(Form $form)
{
// ..
$this->redirect('this');
}
public function renderDefault()
{
$this['myForm']->setDefaults($model->find( ... ));
}
Metoda renderDefault
se volá až po zpracování signálů,
takže není s čím porovnávat změny. A feature, která v některých
případech nemůže z principu fungovat (nastavování dat až v metodě
render se mi jeví jako celkem běžná a logická praktika), mi nepřijde moc
užitečná.
matata: v kódu, který jsem napsal, se při úspěšném odeslání formuláře ten vyznačený SELECT neprovede, byl by navíc.
mlha: na to nastavování výchozích hodnot u nových položek můžeš zkusit něco takového (píšu z fleku, tak možná budou nějaké překlepy):
FormControl::extensionMethod('forceDefaultValue', function (FormControl $control, $value) {
if ($control->getValue() === NULL) {
$control->setValue($value);
}
});
// Doplnění: ještě dodám, že formulář by už v době sestavování měl být připojen k presenteru, jinak se po dodatečném připojení všechny hodnoty přepíší.
Editoval Panda (12. 8. 2010 21:58)
- Ondřej Mirtes
- Člen | 1536
Panda: Njn a právě, že se mi to nedařilo ani v action* metodě, loadHttpData nad jednotlivými prvky se volalo ještě před ní.
- h4kuna
- Backer | 740
Ondřej Mirtes + Panda: ok, když to bude přes session tak by to mohlo makat
nějak takto
Nette a8c51dd
released on 2010–07–23 pro php 5.2
kód nehodnotit :) s GITem nedělám a neumím takže tam je patch z svn a změněný soubory + příklad (example.php)
- Panda
- Člen | 569
Abychom předešli modifikacím formuláře, napsal jsem na to komponentu: https://gist.github.com/565891
//Doplnění: jen dodám, že je to zatím použitelné jen s
AppForm
.
Použtí je jednoduché:
public function createComponentTestForm()
{
$form = new AppForm();
// ...
$form['tracker'] = new \NetteExtras\Forms\ChangeTracker();
return $form;
}
public function testForm_Submit(Application\BaseForm $form)
{
\Nette\Debug::barDump($form['tracker']->getModifiedValues());
}
Editoval Panda (5. 9. 2010 12:49)
- h4kuna
- Backer | 740
Panda napsal(a):
Abychom předešli modifikacím formuláře, napsal jsem na to komponentu: https://gist.github.com/565891
Přesně tak o toto mi šlo :)
Editoval matata (5. 9. 2010 12:31)
- h4kuna
- Backer | 740
Ahoj chtěl bych toto tema připomenout.
Teď jsem to opět potřeboval.
Přiklad:
mam výpis firem, které mají svoji tabulku a ke každé firmě můžu přidat
3 kontakty (jiná tabulka) a žádná hodnota není povinná, co kontakt to
kontejner, bez ajaxu se mi všechny kontejnery zobrazují najednou. Když je
formulář odeslaný, tak nechci prázdné řádky v db tak musím kontejnery
kontrolovat a jejich hodnoty ručně jednu za druhou, zda uložit nebo
neuložit.
Zavolat nad kontejnerem $form->getContainer(‚xxx‘)->isChanged(); by bylo fakt super. By mi to rozhodlo zda kontejner mam ulozit nebo uplne preskocit.
tzn INSERT || NOT INSERT nikoliv INSERT || UPDATE