Nefunkcni AJAX redrawcontrol v nette 2.2.7, nette.ajax.js 1.2.2
- yamboo
- Člen | 10
Zdravim,
potreboval bych nakopnout, kde delam nejakou banalni chybu, ze se mi nerozbehne
ani zakladni ajax. Po kliknuti na link se ajax spusti, ale neprekresli snippet
oblast, ani kdyz dam v handlu redrawcontrol() na vsechny pripadne snippety.
Stranka zustava beze zmeny (localhost/certificate/pok):
Presenter:
<?php
...
public function handleInvalidate() {
$this->template->defaultName="Ivan";
if ($this->isAjax())
$this->redrawControl('nameDefault');
else
$this->redirect("client:showall");
}
public function renderPok() {
$this->template->defaultName="zdenek";
}
...
?>
Sablony:
@layout.latte
<?php
...
{block scripts}
<script src="{$basePath}/js/jquery.js"></script>
<script src="{$basePath}/js/netteForms.js"></script>
<script src="{$basePath}/js/nette.ajax.js"></script>
<script src="{$basePath}/js/main.js"></script>
{/block}
...
?>
pok.latte
<?php
{block head}
<link rel="stylesheet" href="{$basePath}/css/main.css" type="text/css">
{/block}
{block content}
<span n:snippet='nameDefault'>{$defaultName}</span><br />
<a n:href="invalidate!" class="ajax">change</a><br />
{/block}
?>
main.js
<?php
$(function(){
$.nette.init();
});
?>
- David Matějka
- Moderator | 6445
handle* se vola pred render*. Takze se to prekresli, ale ty jsi v renderPok prepsal hodnotu z handleInvalidate
- iguana007
- Člen | 970
viz. response od @matej21 – popsáno je to tady:
https://doc.nette.org/…n/presenters#…
tj. když si:
public function renderPok() {
$this->template->defaultName="zdenek";
}
změníš na:
public function actionPok() {
$this->template->defaultName="zdenek";
}
tak by ti to mělo začít fungovat…
- yamboo
- Člen | 10
To jsem zkousel, ale problem jsem nakonec objevil jinde. V puvodni sablone xxx.latte jsem mel include na dalsi sablonu, v ktere byl teprve definovan snippet. V tomto pripade byl priklad nefunkcni, pokud jsem vse pridal primo do sablony bez include, tak to zaclo bezet. Dekuji za tipy
- David Matějka
- Moderator | 6445
@yamboo ano, to je known limitation, pri invalidaci se v sablone volaji pouze invalidovane bloky – jelikoz je tvuj snippet v inkludovane sablone, ktera se vsak vubec neinkluduje, tak nedojde k prekresleni. Muzes pouzit makro snippetArea
{* prvni sablona *}
{snippetArea wrapper}
{include "foo.latte"}
{/snippetArea}
{* foo.latte *}
...
{snippet foo}
...
{/snippet}
..
pri invalidaci pak invalidujes oboje
$this->redrawControl('wrapper');
$this->redrawControl('foo');
takze se provede cast, kde se inkluduje sablona – do prohlizece se vsak odesle pouze samotny snippet foo
- yamboo
- Člen | 10
Nice, kazda takova rada mi uchrani hodiny badani, dekuji za ne. Pozeptal bych
se tedy na neco komplexnejsiho. Rozsiril jsem presenter o formular a chci Ajax
obdobnym zpusobem navazat na zmenu hodnoty inputu (onBlur). Mam nasledujici
reseni, ktere ovsem opet neprekresli snippet. Ajax se mi pri zmeni spusti
(ukazkovy alert), ale pak to hodi druhy alert v sekci error ve skriptu.
Zachoval jsem tam zmenu pres A odkaz, ktera funguje, bohuzel to naveseni na
zmenu hodnoty inputu a odeslani na pozadi ve volani ajaxu zlobi.
Druhym probleme je, ze Ajax mi preskoci validacni pravidla a spousti se jenom
on. Potreboval bych ho aktivovat az po te, co probehne korektni validace
definovanych pravidel na prvku v komponente…
presenter
<?php
use Nette\Application\UI,
Nette\Application\UI\Form;
protected function createComponentCertificateForm() {
$form = new Form;
//$form->getElementPrototype()->class('ajax');
$form->addText('id_client', 'ID klienta:')
->setRequired('Vyplň ID klienta')
->addRule(Form::INTEGER, 'ID klienta musí být číslo')
->addRule(~Form::RANGE,'ID klienta musí být větší než 1', array(0,1));
$form->addSelect('month','Platnost do:',$this->functions->getMonths())
->setDefaultValue($this->month);
$form->addSelect('year','',$this->functions->getYears())
->setDefaultValue($this->year);
//Default sekce
$form->addText('name', 'Jméno (pokud je jiné jak zadané):')
->addRule(Form::MAX_LENGTH,'Maximální délká jména je %d znaků',32);
$form->addText('lastname', 'Příjmení (pokud je jiné jak zadané):')
->addRule(Form::MAX_LENGTH,'Maximální délká příjmení je %d znaků',64);
$form->addTextArea('address', 'Lokace (pokud je jiná jak zadaná):',40,4);
$form->addText('phone','Mobil (jen je-li jiný jak zadaný):')
->addRule(Form::PATTERN,'mobil musí mít 9 čísel','^([0-9]{9})?$')
->setOption('description', 'mail');
$form->addText('email','Email:')
->addRule(Form::MAX_LENGTH,'Email nesmí být delší jak %d znaků',255)
->addCondition(Form::FILLED)
->addRule(Form::EMAIL,'Zadejte správný formát emailu');
$form->addText('id_vf','ID VF:')
->setDefaultValue(0)
->addRule(Form::PATTERN,'ID klienta u VF musí být celé číslo','^[0-9]+$');
$form->addText('id_o2','ID O2:')
->setDefaultValue(0)
->addRule(Form::PATTERN,'ID klienta u O2 musí být celé číslo','^[0-9]+$');
$form->addText('id_azor','ID AZOR:')
->setDefaultValue(0)
->addRule(Form::PATTERN,'ID klienta u AZORa musí být celé číslo','^[0-9]+$');
$active = array(1 => 'ano', 0 => 'ne');
$form->addSelect('active','Aktivní:',$active);
$supplement = array(0 => 'ne', 1 => 'ano');
$form->addSelect('supplement','Dodatek:',$supplement);
$rent = array(0 => 'ne', 1 => 'ano');
$form->addSelect('rent','Rentiér:',$rent);
$form->addSubmit('send', 'Ulož');
$form->addProtection('Vypršel časový limit, odešlete formulář znovu');
$form->onSuccess[] = array($this, 'sendCertificateForm');
return($form);
}
public function handleInvalidate($id_client=0) {
$this->template->defaultName="Ivan";
if ($this->isAjax())
$this->redrawControl('nameDefault');
else
$this->redirect("client:showall");
}
?>
edit.latte
<?php
{*Certificate latte*}
{block head}
<link rel="stylesheet" href="{$basePath}/css/main.css" type="text/css">
{/block}
{block content}
{include '../menu.latte'}
{form certificateForm}
<ul class="errors" n:if="$form->hasErrors()">
<li n:foreach="$form->errors as $error">{$error}</li>
</ul>
<fieldset id="base_info">
<legend>Certifikovaný uživatel</legend>
{label id_client /}
{input id_client}<br />
{label month /}
{input month}
{input year}<br />
{label name /}
{input name}<span n:snippet='nameDefault'>{$defaultName}</span><br />
{label lastname /}
{input lastname}<a n:href="invalidate!" class="ajax">Add</a><br />
{label phone /}
{input phone}<br />
{label email /}
{input email}<br />
{label address /}
{input address}<br />
{label id_vf /}
{input id_vf}<br />
{label id_o2 /}
{input id_o2}<br />
{label id_azor /}
{input id_azor}<br />
{label active /}
{input active}<br />
{label supplement /}
{input supplement}<br />
{label rent /}
{input rent}<br />
</fieldset>
{input send}<br />
{/form}
{/block}
?>
Rozsireni v main.js
<?php
$(function(){
$.nette.init();
$('#frm-certificateForm-id_client').on('blur', function (event) {
alert($(this).val());
$.nette.ajax({
type: 'GET',
url: '{link invalidate!}',
data: {
'id_client': $(this).val()
},
error: function() {
alert("An error with AJAX.");
}
});
});
});
?>
- David Matějka
- Moderator | 6445
ale pak to hodi druhy alert v sekci error ve skriptu
a zaloguje se nejaka chyba?
Druhym probleme je, ze Ajax mi preskoci validacni pravidla a spousti se jenom on. Potreboval bych ho aktivovat az po te, co probehne korektni validace definovanych pravidel na prvku v komponente…
jelikoz neodesilas formular, ale volas pouze nejaky signal. Tak to bud odesli jako form, nebo zavolej validaci rucne
- yamboo
- Člen | 10
Zapnul jsem si firebug a hlasi mi to, ze neexistuje routa pro volany {link
invalidate!}. S routama jsem zatim nehybal, takze budu muset zase brouzdat
dokumentaci.
Zkusil jsem narychlo nahradit na
<?php
...
url: '/?do=invalidate',
...
?>
To mi to sezere, ale zase odkazuje na jiny presenter, nez z ktereho to volam (kde nemam medotu handleInvalidate), takze budu muset upravit routovani pro signaly. Ten {link invalidate!} se transformuje na „URL/invalidate“ ci tam lze pouzit i presenter typu {link presenter:invalidate!}.