netteForms.js a validace nefunguje po překreslení snippetu
- net-vor
- Člen | 35
Takže zase formulářový „mág“. Mám formulář s jedním ajaxovým selectboxem (podkategorie načítané v závislosti na selectboxu kategorie) + další textová políčka a obalený ve snippetu:
{snippet form}
{control adForm}
{/snippet}
<script type="text/javascript">
$("#frmadForm-category").live('change', function() {
$.get({link selectLoad!}, {"category": $(this).val()});
return false;
});
</script>
K validaci v prohlížeči používám netteForms.js. Po prvotním načtení se vše validuje, jak má. Pokud ale překreslím formulář pomocí ajaxu, validace přestane fungovat. Netuší někdo, v čem je problém?
Nette 2.1dev + jQuery + PHP 5.3.
Podobná témata jsem našel tady, tady a tady, ale bez řešení.
- Vojtěch Dobeš
- Gold Partner | 1316
V success
callbacku AJAXového volání je třeba zavolat
Nette.load();
. Překreslení formuláře totiž vytvoří pro
formulář nový kus DOMu, a na něm není validace nabindovaná.
netteForms.js
nedělají nic jako live()
v jQuery.
- MartyIX
- Člen | 217
https://github.com/…etteForms.js#L306 –
nastaveni handleru se ti vola pouze v ramci udalosti window.load
.
Proto ti validace nemuze fungovat na prvcich, ktere dynamicky pridavas.
Editoval MartyIX (2. 4. 2012 20:08)
- Vojtěch Dobeš
- Gold Partner | 1316
{snippet form}
{control adForm}
{/snippet}
<script type="text/javascript">
var selectChangeCallback = function () {
$("select[name=category]").change(function() {
$.get({link selectLoad!}, {
"category": $(this).val()
}, function (payload) {
$.nette.success(payload);
Nette.load();
selectChangeCallback();
});
return false;
});
};
$(function () {
selectChangeCallback();
});
</script>
- vyhnout se použití
live()
je výkonnější (http://paulirish.com/…jquery-live/) - nezáviset na IDčku generovaném v Nette je odolnější proti BC breakům v budoucnu (na druhou stranu použití ID je výkonnější, to jest pravda :) )
Editoval vojtech.dobes (2. 4. 2012 16:29)
- net-vor
- Člen | 35
vojtech.dobes napsal(a):
<script type="text/javascript"> var selectChangeCallback = function () { $("select[name=category]").change(function() { $.get({link selectLoad!}, { "category": $(this).val() }, function (payload) { $.nette.success(payload); Nette.load(); selectChangeCallback(); }); return false; }); }; $(function () { selectChangeCallback(); }); </script>
Díky, Vojto, ale nefachčí a Firebug hlásí „Nette.load is not a function“.
- Vojtěch Dobeš
- Gold Partner | 1316
Eh, omlouvám se, vykopíroval jsem to z jednoho projektu, kde jsem to měl
upravené :) Aktuální netteForms.js
takovouhle inicializační
funkci nemá, takže jsem si tam dopsal:
Nette.load = function () {
for (var i = 0; i < document.forms.length; i++) {
Nette.initForm(document.forms[i]);
}
};
Uvidíme, co nám David připraví v branchi jquery.
- Vojtěch Dobeš
- Gold Partner | 1316
Použij na Ajax nette.ajax.js
, ten s netteForms.js
už automaticky spolupracuje.
- Vojtěch Dobeš
- Gold Partner | 1316
Obligátně: blbě se odpovídá, když není vidět ani řádku tvého kódu.
- Siam
- Člen | 54
Zkusil jsem to dát zjednodušeně do sandboxu a výsledek byl stejný, zvlášť ty scripty šly a dohromady jenom ten ajaxový. Kód byl tento:
<?php
use Nette\Application\UI\Form;
class HomepagePresenter extends BasePresenter
{
public function handleShowFoo()
{
$this->template->foo = TRUE;
$this->invalidateControl();
}
public function createComponentFoo()
{
$form = new Form;
$form->getElementPrototype()->class('ajax');
$form->addText('name', 'name:')
->setRequired('Pole se jménem musí být vyplněné.');
$form->addSubmit('send', 'Uložit');
$form->onSuccess[] = callback($this, 'process');
return $form;
}
}
{block content}
<a n:href="showFoo!" class="ajax">Show foo</a>
{snippet}
{ifset $foo}
{control foo}
{/ifset}
{/snippet}
<html>
<head>
<meta charset="UTF-8">
<title>title</title>
<link rel="stylesheet" media="screen,projection,tv" href="{$basePath}/css/screen.css">
<script src="http://code.jquery.com/jquery-1.8.1.min.js"></script>
<script src="{$basePath}/js/netteForms.js"></script>
<script src="{$basePath}/js/nette.ajax.js"></script>
<script>
// inicializace nette.ajax.js
$(function () {
$.nette.init();
});
</script>
</head>
<body>
{include #content}
</body>
</html>
Editoval Siam (17. 11. 2012 13:04)
- Siam
- Člen | 54
A html zdroják ztoho leze tento.
<div id="snippet--">
<form id="frm-foo" class="ajax" method="post" action="/?do=foo-submit">
<table>
<tbody>
<tr class="required">
<th>
<label class="required" for="frmfoo-name">name:
</label>
</th><td>
<input id="frmfoo-name" class="text" type="text" value="" data-nette-rules="{op:':filled',msg:'Pole se jménem musí být vyplněné.'}" required="required" name="name"></td>
</tr>
<tr>
<th>
</th><td>
<input id="frmfoo-send" class="button" type="submit" value="Uložit" name="send"></td>
</tr>
</tbody>
</table>
<div>
</div>
</form>
</div>
- Vojtěch Dobeš
- Gold Partner | 1316
Hm… díky za zaslání. Debugoval bych to prozkoumáním, co se odehrává
na těchto
řádcích, co je tam v proměnných a tak (console.log()
).
Jestli se tam ten cyklus projede a jestli se volá Nette.initForm
.
Jinak mě nenapadá, proč by to nemělo fungovat…
- Siam
- Člen | 54
Nemůžeš být prosím trochu konkrétnější? Netuším které proměnné testovat.
Zkusil jsem dát do té funkce řádky console.log(payload.snippets); console.log(window.Nette); a po kliknutí na odkaz a zobrazení toho formuláře snippet obsahoval ten formulář a window.Nette objekt se spoustou metod. Po kliknutí na formulář snippets bylo undefined a window.Nette to samé. To ti ale asi k ničemu není, neznám bohužel ani ten script a ani moc jquery…
Můžu ti poslat celý ten sandbox.
Editoval Siam (17. 11. 2012 20:50)
- Siam
- Člen | 54
vojtech.dobes:
ok, to bude super. Měl bych ještě otázku. Měl bych jí napsat spíš do
vlákna toho rozšíření, ale píšu to sem, protože je už zde napsaný kód
o kterým chci mluvit.
Ten kód jsem poupravil tak, že pokud se ajaxově zobrazí ten formulář, tak se tklačítko „show foo“ změní na „hide foo“ a funguje to jak má.
Problém ovšem je, když na to chci použít efekt, který jsi zmínil v tom vlákně.
<script>
$(function () {
$.nette.init();
$.nette.ext('snippets').applySnippet = function ($el, html) {
$el.fadeTo("fast", 0.01, function () {
$el.html(html).fadeTo("fast", 1);
});
};
});
</script>
Pokud kliknu na show foo, tak se efekt i ajax použije tak jak má. Pokud ovšem potom kliknu na hide foo, tak se místo ajaxového požadavku provede normální a stránka se přesměruje. Ajaxifikace přestane funguvat. Změnil se nějak potřebný zápis, nebo je problém jinde?
Editoval Siam (20. 11. 2012 4:20)