Nefunkcni AJAX redrawcontrol v nette 2.2.7, nette.ajax.js 1.2.2

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

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
+
+1
-

handle* se vola pred render*. Takze se to prekresli, ale ty jsi v renderPok prepsal hodnotu z handleInvalidate

iguana007
Člen | 970
+
+1
-

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
+
0
-

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
+
+1
-

@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
+
0
-

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
+
0
-

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
+
0
-

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!}.