Spojení formulářů s AJAXem
- David Grudl
- Nette Core | 8218
Občas tu padnou dotazy, jak spojit formuláře s AJAXem, nebo jak vybrání položky v select boxu načíst jiný box atd. Řešení existuje samozřejmě více, chtěl bych je i probrat na školení PHP, Toto je jedno z nich (neříkám že vzorové):
public function actionDefault()
{
$this->template->form = $form = new AppForm($this, 'form');
$form->addSelect('lokalita', 'Vyberte si lokalitu:', $lokality)
->addRule(Form::FILLED, 'Vyberte lokalitu');
$form->addSelect('termin', 'Zvolte si termín:') // zatim bez hodnot
->addRule(Form::FILLED, 'Vyberte termín');
$form->addSelect('den', 'A vyberte si den:') // zatim bez hodnot
->addRule(Form::FILLED, 'Vyberte den');
$form->addSubmit('submit1', 'Odeslat');
// nastavime události onchange:
$form['lokalita']->getControlPrototype()
->onchange('loadBox(1, this.value);');
$form['termin']->getControlPrototype()
->onchange('loadBox(2, this.value);');
$form['den']->getControlPrototype()
->onchange('loadBox(3, this.value);');
if ($form->isSubmitted()) {
// teprve nyni dosadime hodnoty
$form['termin']->setItems(...);
$form['den']->setItems(...);
if ($form->isValid()) {
...
}
} else {
$form['termin']->setDisabled();
$form['den']->setDisabled();
$form['submit1']->setDisabled();
}
}
Jako obsluhu události onchange jsem prvkům select nastavil volání funkce loadBox(). Ta může vypadat třeba takto (využívá se jQuery):
function loadBox(phase, value)
{
if (phase === 1) {
// zvolena hodnota prvniho select boxu
$('#frmform-den').attr('disabled', true);
$('#frmform-den').val(0);
$('#frmform-submit1').attr('disabled', true);
// zobrazi symbol, že se něco načítá
spinner();
// natáhne obsah druhého selectboxu pomocí AJAXu
$.get("?do=loadData", {"value": value, "phase": phase}, function(data) {
$('#frmform-termin').parent().html(data);
});
} else if (phase === 2) {
// zvolena hodnota druheho select boxu
$('#frmform-submit1').attr('disabled', true);
// zobrazi symbol, že se něco načítá
spinner();
// natáhne obsah třetího selectboxu pomocí AJAXu
$.get("?do=loadData", {"value": value, "phase": phase}, function(data) {
$('#frmform-den').parent().html(data);
});
} else if (phase === 3) {
// zvolena hodnota tretiho select boxu, povolí tlačítko submit
$('#frmform-submit1').attr('disabled', true);
}
}
Funkce zase vyvolá signál loadData, jehož handler může vypadat takto:
public function handleLoadData($phase, $value)
{
$form = $this->template->form;
if ($phase == 1) {
// naplníme select box prvky a vypíšeme na výstup
$form['termin']->setItems(...);
echo $form['termin']->getControl();
} elseif ($phase == 2) {
$form['den']->setItems(...);
echo $form['den']->getControl();
}
// konec zpracování
$this->terminate();
}
- edke
- Člen | 198
Ahoj David. Vdaka za postrcenie, uz mam zaklad, na com skusat Ajax. Funguje to, az na par typos, na ktore som narazil:
1. pri zmene lokality je treba pre druhy select aj zrusit disabled ako vo faze 1 tak 2:
public function handleLoadData($phase, $value)
{
$form = $this->template->form;
if ($phase == 1) {
// naplníme select box prvky a vypíšeme na výstup
$form['termin']
->setItems( ... )
->setDisabled(false);
2. pri zvoleni tretieho selectu treba enablovat submit, znovu typo:
// zvolena hodnota tretiho select boxu, povolí tlačítko submit
$('#frmform-submit1').attr('disabled', false);
Super, mozem sa pustit do Ajaxu :) Este raz vdaka za nakopnutie.