Problém s odesíláním formuláře „Maximum call stack size exceeded“

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

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

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

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)

CZechBoY
Člen | 3608
+
0
-

@2bfree pošli kod