Ajax form odeslání a načtení dat
- tatyalien
- Člen | 239
Dobrý den,
prosím nekamenujte mě za začátečnické dotazy, s ajaxem nějak furt
začínám…
v šabloně mám dva formuláře, první formulář kosikRychleVlozeniForm, se
ajaxově odesílá… přidá položky do košíku a do stránky se zboží
přidá…
Nyní jsem chtěl, ještě u formuláře, který slouží pro aktualizaci
položek v košíku, taky přenastavit na ajax, ale nejde mě to rozchodit.
Nevím co dělám furt blbě… třeba to je chujovina, ale nedokážu na to
přijít.. Pro ajax používám jquery.nette.js a jquery.ajaxform.js.
Formuláře jsem zde skusil ořezat na to nejnutnější.
{form kosikRychleVlozeniForm, class => ajax}
<!-- Jednoduché vykreslení chyb -->
<div class="errors" n:if="$form->hasErrors()">
{foreach $form->errors as $error}
{!$error}{sep}<br />{/sep}
{/foreach}
</div>
<span id="frmkosikRychleVlozeniForm-katalog_message"></span>
<span id="frmkosikRychleVlozeniForm-ks_message"></span>
<fieldset>
<legend>Rychlé vložení do košíku</legend>
{label katalog/} {input katalog}
{label ks/} {input ks}
{input vlozit_do_kosiku}
</fieldset>
{/form}
Druhý formulář:
{snippet kosikAjax}
{if count($kosik) != 0}
{form kosikEditForm, class => ajax}
<!-- Jednoduché vykreslení chyb -->
<div class="errors" n:if="$form->hasErrors()">
{foreach $form->errors as $error}
{!$error}{sep}<br />{/sep}
{/foreach}
</div>
{foreach $kosik as $value}
{first}
{var $frm_i = 0}
<table class="basket-table">
{/first}
{var $ksFrm = $frm_i."-ks"}
{var $katalogFrm = $frm_i."-goods_katalog"}
{var $poznamkaFrm = $frm_i."-poznamka"}
<tr>
<td>{$value['goods_nazev']|truncate:50} {label $poznamkaFrm/} {input $poznamkaFrm}</td>
<td>{input $ksFrm} ks{input $katalogFrm}</td>
</tr>
{var $frm_i++}
{last}
</table>
{/last}
{/foreach}
{/form}
{/if}
{/snippet}
zajaxuji formuláře:
<script>
jQuery.ajaxSetup({
cache: false,
dataType: 'json',
success: function (payload) {
if (payload.snippets) {
for (var i in payload.snippets) {
$('#' + i).html(payload.snippets[i]);
}
}
}
});
// odesílání odkazů
$('a.ajax').live('click', function (event) {
event.preventDefault();
$.get(this.href);
});
// odesílání formulářů
$('form.ajax').live('submit', function (event) {
event.preventDefault();
$.post(this.action, $(this).serialize());
});
</script>
Toto se provede v pořádku (rychlé vložení ajaxově)
public function kosikRychleVlozeniFormSubmitted(Form $form)
{
try {
$values = $form->getValues();
$this->context->shoppingCart->add($values['katalog'], $values['ks'],'', $this->presenter, true, true);
if($this->isAjax()) {
$this->invalidateControl('basketSoucet');
$this->invalidateControl('flash');
$this->invalidateControl('basketInfo');
$this->invalidateControl('kosikAjax');
} else {
$this->redirect('this');
}
} catch (IOException $e) {
$form->addError($e->getMessage());
}
}
Toto neproběhne, když vypnu ajax, tak je to ok (ale neajaxově…)
public function editBasketFormSubmitted(Form $form)
{
try {
$values = $form->getValues();
foreach($values as $val) {
$this->context->shoppingCart->edit($val['goods_katalog'], $val['ks'], $val['poznamka'], $this->presenter, false);
}
$this->flashMessage('Nákupní košík přepočítán.', 'success');
if($this->isAjax()) {
$this->invalidateControl('basketSoucet');
$this->invalidateControl('flash');
$this->invalidateControl('basketInfo');
$this->invalidateControl('kosikAjax');
} else {
$this->redirect('this');
}
} catch (IOException $e) {
$form->addError($e->getMessage());
$this->redirect('this');
}
}
data plním v metodě:
public function renderBasket()
{
$kosik = $this->context->shoppingCart;
$this->template->kosik = $kosik->printCart();
// helpery:
$this->template->registerHelper('prevodDatumu', function($value, $format='d.m.Y H:i:s') {
return date($format, strtotime($value));
});
$this->template->registerHelper('existObrBasket', function($value, $nahrada) {
$isExisting = @fopen($value, 'r');
return $isExisting ? $value : $nahrada;
});
$this->template->registerHelper('existObrBasketOur', function($value, $nahrada) {
$isExisting = @fopen($_SERVER['DOCUMENT_ROOT'].'/'.$value,"r");
return $isExisting ? $value : $nahrada;
});
// náhledy
$katalog = Array();
foreach($this->template->kosik as $value) {
// zde to není objekt, nemůžu přistupovat jako $value->goods_katalog
$katalog[] = $value['goods_katalog'];
}
$nahled = $this->modelShop->getFotogalery()->select('*')->where('goods_katalog', $katalog)->where('typ', 0)->fetchPairs("goods_katalog");
$this->template->nahled = $nahled;
// ceny
$ceny= $this->modelShop->getGoods()->select('cenaSdani, katalog')->where('katalog', $katalog)->fetchPairs("katalog");
$this->template->ceny = $ceny;
}
Editoval tatyalien (29. 5. 2012 8:47)
- tatyalien
- Člen | 239
Tak jsem ještě zjistil, že to vrací /test/basket?do=kosikEditForm-submit 500 Internal Server Error
v logu mám pak Nette\Application\BadRequestException #404 Invalid parameter name ‚0‘
Přitom argument odesílaný je pole textinputu 0 ⇒ Array(katalog, ks, poznamka), 1 ⇒ Array(katalog,ks, poznamka)… proto se nejspíš cpe name ‚0‘ jako první prvek toho pole… ale jak na tohle nastavit routu? Routy mám normálně presenter/action… když to není ajaxové odesílání, vše fachá jak má.
log:
Nette\Application\BadRequestException: ‚Invalid parameter name '0‘ in
C:\xampp\htdocs\www\…\aplikace\libs\Nette\Application\UI\Presenter.php:707 @
http://localhost/…/test/basket?… @@
exception-2012–05–29–13–45–07–93bbdef2cc2bc86cb2eb0abf17689f55.html
$request:
Nette\Application\Request(7) ▼ {
method private => "POST" (4)
flags private => array(1) ▼ {
secured => FALSE
}
name private => "Test" (4)
params private => array(2) ▼ {
action => "basket" (6)
do => "kosikEditForm-submit" (20)
}
post private => array(3) ▼ [
0 => array(3) ▼ {
poznamka => ""
ks => "2"
goods_katalog => "ast-A9012" (9)
}
1 => array(3) ▼ {
poznamka => ""
ks => "2"
goods_katalog => "ast-EFLH1250M1" (14)
}
2 => array(3) ▼ {
poznamka => ""
ks => "1"
goods_katalog => "ast-EFLH1250M2" (14)
}
]
files private => array(0)
frozen private => TRUE
}
Editoval tatyalien (29. 5. 2012 13:48)
- tatyalien
- Člen | 239
Ještě jsem zkusil změnit typ odesílání z postu na get a skočí laděnka co skáče k ajaxu… protože to vygeneruje:
test/basket?0%5Bpoznamka%5D=&0%5Bks%5D=2&0%5Bgoods_katalog%5D=ast-A9012&1%5Bpoznamka%5D=&1%5Bks%5D=2&1%5Bgoods_katalog%5D=ast-EFLH1250M1&2%5Bpoznamka%5D=&2%5Bks%5D=1&2%5Bgoods_katalog%5D=ast-EFLH1250M2&ok=P%C5%99epo%C4%8D%C3%ADtat
Ale jak na tohle nastavit routu fakt netuším, nebo jak to přenastavit… přesunout do actionu, handlu…
- tatyalien
- Člen | 239
No, asi mě nic jiného nezbyde… ale stejně nevím jak bych měl nastavit routu na „GET“ metodu, nebo jestli se to tím vyřeší… no jak přepíšu na kontejner metodu tak dám vědět jestli to pomohlo…
PS-asi to pomohlo, ale jsem už utahanej, zejtra to ozkouším víc a dám vědět.
Editoval tatyalien (30. 5. 2012 0:07)
- tatyalien
- Člen | 239
Tak to pomohlo… stačilo opravit továrničku na:
...
$pole = Array();
// tady dodáno container polozka
$sub1 = $form->addContainer('polozka');
foreach($kosik as $key => $value) {
// toto jsem už v containeru měl
$sub1->addContainer($i);
$sub1[$i]->addHidden('goods_katalog', ' ');
$sub1[$i]->addText('ks', 'ks:', 3,20)
->addRule($form::INTEGER, '%label musí být celé číslo.')
->addRule($form::RANGE, '%label musí být kladné celé číslo.', Array(0, NULL))
->addRule($form::MAX_LENGTH, '%label musí obsahovat maximálně %d znaků.', 20);
$sub1[$i]->addText('poznamka', 'Poznámka:', 44,1024)
->addRule($form::MAX_LENGTH, '%label musí obsahovat maximálně %d znaků.', 1024);
$i++;
$pole[$i-1] = Array('goods_katalog' => $key, 'ks' => $value['ks'], 'poznamka' => $value['poznamka']);
}
$arr = Array('polozka' => $pole);
Jen jsem zapouzdřil jeden container do druhého a rozjelo se to. Jen se po znovunačtení formuláře nenastaví automatické opravování, ale to se myslím tady někde řešilo, tak začnu hledat…
- tatyalien
- Člen | 239
Tak pomohlo toto:
na konci v základním layoutu jsem dal níže uvedejen kód, kde po
zpracování ajaxového požadavku invaliduji tutu část…
{snippet javaAjax}
<script>
// napojení po načtení ajaxu live validace
for (var i = 0; i < document.forms.length; i++) {
Nette.initForm(document.forms[i]);
}
</script>
{/snippet}