ajaxove odosielanie formulara – onchange

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

ahojte viete mi poradit?
mam formular a ked nastavim select a dam odoslat poziadavka mi prebehne ajaxovo,
ale ja by som chcel aby sa formular odoslal ajaxovo aj ked budem mat onchange,
lenze ked to pouzijem tak uz sa mi formular odosle normalne. viete mi poradit co mam zle?

public function createComponentTaskFilterForm($name)
{
  $form = new Form($this, $name);
  $form->getElementPrototype()->class('ajax');

  // Project filter
  $form->addSelect('project', 'Projekt:', $this->projectModel->fetchPairs('id', 'name'))
    ->setPrompt('- Vyberte -')
    ->setDefaultValue($this->projectId)
    ->setAttribute('onchange', 'submit()'); // pokial pouzijem toto tak to prebehne normalne

  $form->addSubmit('filter', 'Filter');
  $form->onSuccess[] = callback($this, 'taskFilterFormSubmitted');
  return $form;
}

public function taskFilterFormSubmitted(Form $form)
{
  $taskFilter = array();

  $this->projectId = $form->values->project;
  $taskFilter['projectId'] = $this->projectId;
  $this->setFilter($taskFilter);

  if (!$this->presenter->isAjax())
  {
    $this->redirect('this');
  }else
  {
    $this->invalidateControl('taskListFilter');
    $this->getParent()->invalidateControl('taskListTable');
  }
}
Vojtěch Dobeš
Gold Partner | 1316
+
0
-

The question is… jak provádíš ajaxizaci? Pokud používáš nette.ajax.js, můžeš přidat obsluhu onchange následovně:

$('select').change(function (e) {
	$(this).closest('form').submit();
});

Ajaxové odeslání proběhne, protože formulář má třídu ajax a je automaticky zaajaxován na událost submit.

duskohu
Člen | 778
+
0
-

dakujem,
tak toto pomohlo:

$("select").live("change", function () {
    $(this).closest('form').submit();
    return false;
});
jtousek
Člen | 951
+
0
-

jQuery.live používej pouze v případě, že chceš aplikaci z hlediska výkonu JS totálně zabít. Zkus raději delegate. Mluvím ze zkušenosti, jedna aplikace mi na to dojela a raději jsem ji celou zahodil, bohužel náhrada za live tehdy neexistovala.

jsvelta
Člen | 39
+
0
-

Citujem:
As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers. Users of older versions of jQuery should use .delegate() in preference to .live().

jtousek
Člen | 951
+
0
-

Vida, koukám, že delegate bude brzy deprecated taky. :-D Ještě lepší. :-) V každém případě live / livequery jsou fuj.

Vojtěch Dobeš
Gold Partner | 1316
+
0
-

Finální verze s nette.ajax.js (chovající se jako s live()):

$.nette.ext('select-onchange', {
	load: function () {
		$('select').change(function (e) {
		        $(this).closest('form').submit();
			return false;
		});
	}
});

Editoval vojtech.dobes (31. 7. 2012 1:14)

LeonardoCA
Člen | 296
+
0
-

jen se mně tam moc nelíbí ten obecný selector ‚select‘ …

nezajaxovatí se tak všechny selecty na stránce? (i když se tam někdy objeví select, který by neměl nic hned odesílat)

Vojtěch Dobeš
Gold Partner | 1316
+
0
-

Kód by měl samozřejmě matchovat jen ty selecty, které matchovat má :).

duskohu
Člen | 778
+
0
-

este by som sa chcel informovat pouzival som jquery.nette.js ale zmenil som to za nette.ajax.js

pouzil som :

<script type="text/javascript" src="{$basePath}/js/nette.ajax.js"></script>
<script type="text/javascript">
$(function () {
  $.nette.ext('select-onchange', {
    load: function () {
      $('select.ajax').change(function (e) {
        $(this).closest('form').submit();
        return false;
      });
    }
  });
  $.nette.init();
});
</script>

// sablona
<a n:href="setTaskId! $task->id" class="ajax" >Zozbraz</a>


// handle
    if ($this->presenter->isAjax()) {
      $this->invalidateControl('taskDetail');
    } else {
      $this->presenter->redirect('this');
    }

vsetko funguje fajn, ale ked urobim ajax poziadavok,
vo firebugu prebehne, ale sucasne sa mi zmenu aj url, resp, vyzera to tak ako by sa to neurobilo ajaxovo,

viete mi poradit ako postupovat???

jtousek
Člen | 951
+
0
-

Nezmění se náhodou pouze ta část URL která je až za „#“?

duskohu
Člen | 778
+
0
-

nie,
mam pred:localhost/taskmanager/www/
a po: localhost/taskmanager/www/?executorIncompleteTasks-task_Id=246&do=executorIncompleteTasks-setTaskId

ked urobim: tak vrati ajax, ale url zmeni

if ($this->presenter->isAjax()) {
$this->presenter->flashMessage('ajax', 'error');
  $this->invalidateControl('taskDetail');
} else {
$this->presenter->flashMessage('no ajax', 'error');
  $this->presenter->redirect('this');
}

Editoval duskohu (31. 7. 2012 19:29)

Vojtěch Dobeš
Gold Partner | 1316
+
0
-

nette.ajax.js obsahuje rozšíření, které pracuje s History API v přohlížeči. Lze vypnout pomocí:

$.nette.ext('history', false);
duskohu
Člen | 778
+
0
-

super paradicka, ide to dakujem,
ono to urobilo refrsh stranky alebo len zmenilo url??????
a dalo by sa to aplikovat aby to fungovalo len na konkretnu poziadavku, napr. len na urcity handle?

$.nette.ext('history', true);
Vojtěch Dobeš
Gold Partner | 1316
+
0
-

Provede to změnu URL bez refreše. Umožňuje to zachovávat použitelné tlačítko Zpět i pro ajaxové requesty. Nyní se to provede vždy (mám dojem), nicméně tuto část plánuji vyladit lépe.

xxxmisko
Člen | 140
+
0
-

Čaute chlapi!

Prosím vedeli by ste mi poradiť? Potrebujem naviazať akciu na selecty, pričom onchange sa vykoná submit.

Používam riešenie vyššie, teda

<script>
$(function () {
  $.nette.ext('select-onchange', {
    load: function () {
      $('select.ajax').change(function (e) {
        $(this).closest('form').submit();
        return false;
      });
    }
  });
  $.nette.init();
});
</script>

Všetko pekne funguje, problém ale je, že nette mi vráti celú stránku, nie vo formáte JSON a nič mi neprepíše. Obsah sa pekne zobrazí, ale nič sa mi nevypíše.
Problém asi bude v handle metóde, kde invalidujem snippet.

public function handle() {

	if ($this->presenter->isAjax()) {
	    $this->invalidateControl('testSnippet');
	}

}

skúšal som všelijaké názvy, ale neviem, ako handle udalosť nazvať.

A v šablóne mám

  {snippet testSnippet}
    {form testForm}
...
...
{/form]
{/snippet}
<div>

Teda chcel by som prekleslovať form.

Prosím o radu, ako riešenie rozchodiť, nejako sa mi nedarí nájsť funkčné riešenie, ďakujem

Vojtěch Dobeš
Gold Partner | 1316
+
0
-

Pokud AJAXově odesíláš formulář, tak se prostě zavolá jeho obsluha onSuccess[] (pokud byl odeslán správně vyplněný), žádná metoda handle<naprostoCokoliv> se sama od sebe nezavolá, pokud ji ručně nezavoláš v té obsluze formuláře.

xxxmisko
Člen | 140
+
0
-

@vojtech.dobes

takto: ten kód vyššie zavolá submit toho selectu, ale nie ajaxovo, iba obyčajne. Čo tam treba dopísať, aby pracoval ajaxovo?

Editoval xxxmisko (19. 4. 2013 11:31)

jiri.pudil
Nette Blogger | 1029
+
0
-

Má ten formulář třídu ajax?

Vojtěch Dobeš
Gold Partner | 1316
+
0
-

Musí být zajaxovaný, tj. na událost submit musí být navázano ajaxové odeslání :). Nejsnáze toho lze docílit použitím doplňku nette.ajax.js a přidáním CSS třídy ajax tomu formuláři.

xxxmisko
Člen | 140
+
0
-

@vojtech.dobes, jiri.pudil

vyriešil som to takto:

formu som nenasadil triedu ajax, pretože mi to pri onchange udalosti validovalo 2×, aj keď som vypol validáciu.

Vytvoril som submit button, ktorý som skryl, pričom pri selecte som naviazal udalosť onchange na odoslanie cez daný submit button.

Všetko funguje ako má, keď už teraz viem, ako to funguje, je to poprdeli ľahké, nette.ajax.js je super.