Problém s odesíláním formuláře „Maximum call stack size exceeded“
- Mardzis
- Člen | 33
Ahoj,
snažím se připravit formulář, který bude mít js validaci pomocí
jquery-validation.js
. Po odeslání zpracovat v Nette
v presenteru a vrátit do js zpět success nebo error hlášky. Při success
skrýt formulář a zobrazit nějaké „next steps“, při erroru hlášku a
možnost znovu odeslat formulář. Nikde jsem nenašel že by to někdo takto
řešil (konkrétně třeba to skrytí formuláře), hlášky se dají posílat
pomocí payload
.
Bohužel mi teď při odeslání hází konzole v prohlížeči tuto chybu:
main.js:479 Uncaught RangeError: Maximum call stack size exceeded(…)
.
Dokážete mi někdo postrčit či poslat nějaký článek kde už někdo něco podobného řešil? Díky moc
main.js
<script>
require('nette.ajax.js');
require('nette-forms');
require('bootstrap');
$(function () {
$.nette.init();
});
define(['jquery', 'jquery-validation'], function ($) {
$('#frm-testForm').validate({
onkeyup: false,
onfocusout: function (element, event) {
this.element(element);
},
success: function (label) {
label.addClass("valid");
},
rules: {
..... Rules ......
},
invalidHandler: function (form, validator) {
$('html, body').animate({
scrollTop: $(validator.errorList[0].element).offset().top
}, 0);
},
messages: {
..... Messages ......
},
submitHandler: function (form) {
$(form).ajaxSubmit();
}
});
});
</script>
Latte tmp
{block content}
<div>
{snippet responseForm}{/snippet}
{control testForm}
</div>
Presenter
public function saveTestForm($form, $values)
{
$form->addError("some error");
if ($this->isAjax()) {
$this->redrawControl("responseForm");
} else {
$this->redirect("this");
}
}
protected function createComponentTestForm()
{
$form = new UI\Form;
$form->getElementPrototype()->class = 'ajax';
.... RULES ....
$form->addSubmit('submit', 'Send');
$form->onSuccess[] = [$this, 'saveTestForm'];
return $form;
}
Editoval Mardzis (4. 12. 2016 17:34)
- Mardzis
- Člen | 33
Vše vyřešeno, problém mnohonásobného odesílání byl že
form
měl class ajax
, stačí na button (nevim proč,
ale funguje to)
$form->getElementPrototype()->class = 'ajax';
Jelikož téměř každé téma které jsem četl všichni vkládali form přímo do šablony, což pro nebylo moc pohodlné a chtěl jsem mít oddělený js od latte a tak.
V submitHandler
mám teď toto:
<script>
$.ajax({
url: $regForm.attr('action'),
type: 'POST',
data: $regForm.serialize(),
success: function(result) {
console.log($regForm.serialize());
console.log(result);
}
});
</script>
Presenter pak posílá jen payload, stejně jako všude. Nevýhoda, že musím udržovat vlastně stejná pravidla jak v js tak v php, ale ty live-validace co jsem viděl mi moc nevyhovovali.
- 2bfree
- Člen | 248
Právě mi nastala tato chyba. Jedná se o to, že mám dva prvky a vzájemně na nich, že pokud je druhý prvek vyplněn, tak tento musí být také. Čímž dojde k vzájmné kontrole a tedy cyklickému volání.
Zjednodušeně něco ve smyslu
$control1 = $form->addText('control1');
$control2 = $form->addSelect('control2');
$control1->addConditionOn($control2, $form::FILLED)
->addRule($form::REQUIRED, 'Required');
$control2->addConditionOn($control1, $form::FILLED)
->addRule($form::REQUIRED, 'Required')
Vyřešil jsem to workaroundem
$control2->addRule(array($this, 'isFilled'), 'Required');
/**
* Is filled validator
*
* @param IControl $control
* @return boolean
*/
public function isFilled(IControl $control)
{
return Validator::validateFilled($control);
}
Tedy přinutil jsem jeden z prvků k výhradně BackEndové validaci.
Teda v mém přípdě se jedná o sarší verzi Nette a nette.ajax.js ale spíš tak jako hint jak na to…
Editoval 2bfree (28. 8. 2017 16:38)