Spojení formulářů s AJAXem
 
- David Grudl
- Nette Core | 8285
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.
