Submit formuláře – refresh pouze snippet (ostatní formy na stránce zůstanou i s daty)

- Tomas Trdla
 - Člen | 19
 
Zdravím,
- Pracuji na presenteru, který vytváří graf s filtrovanými daty.
 - Filtry jsou vybrány v několika identických formulářích (každý z formulářů je pro jednu křivku v grafu → porovnání mezi nimy)
 - Při aplikování filtrů jednoho z formulárů je překreslen pouze graf.
 
Jak to funguje: Problém nastává když je jeden z formulářů potvrzen. Celá stránka se refreshne a data v ostatních formulářích se ztratí.
Jak by to mělo fungovat: Všechny formuláře si ponechají svoje data a překreslen je pouze graf.
Kód pro několik formulářů na jedné stránce:
class MultiForm extends Form {
    var $parent; // used in process()
    public function __construct($parent = null, $name = null) {
        parent::__construct($parent, $name);
        $this->parent = $parent;
    }
}
Předvytvoření formulářu:
public function actionStatsTest() {
        $this->checkLogin();
        $formsID = array(1,2);
        foreach ($formsID as $id) {
            $this->_createSearchForm($id);
. . . // empty data for graph
        }
        $this->template->forms = $formsID;
		$this->template->graphData = $graphData;
    }
public function _createSearchForm($formID) {
        $form = new MultiForm($this, 'SearchForm_' . $formID);
        $this->DBpatientSearchFF->AddFilterFields($form);
        $form->addSubmit('send', 'Aplikovat filtry');
        $form->onSuccess[] = array($this, "postFormSucceeded");
    }
Form submit handler:
    public function postFormSucceeded($form, $values) {
		//process into graph data
        // . . .
		$this->template->graphData = $graphData;
        $this->redrawControl('graph');
    }
Latte:
{foreach $forms as $id}
	<div id="SearchFilters{$id}">
		<div class="panel-body">
			{var formName = 'SearchForm_' . $id}
			<form n:name="$formName" class="validation-form">
				{include '../MultipresenterForms/dbSearchForm.latte'}
				<fieldset class="form-group">
					<input n:name=send class="btn btn-primary">
				</fieldset>
			</form>
		</div>
	</div>
{/foreach}
{snippet graph}
        . . .
{/snippet}
				
- Ondřej Kubíček
 - Člen | 494
 
nikde tam nevidím ajax, bez něj to neuděláš
a spíš bych ten form řešil přes multiplier

- Tomas Trdla
 - Člen | 19
 
Tak multiplier můj problém nevyřešil, dělá přesně to samé → po submitu jednoho z formů multiplieru se stránka refreshne a co bylo napsané v ostatních formech zmizí a zůstane pouze ten submitnutý
je nějaká možnost jak z latte poslat instanci formu do handler metody…
něco jako
<a n:href="methodHandle! $form, $formID">Apply</a>, že
bych si ty data vytahnul ručně?
a ten ajax se nedaří, pravděpodobně protože pořadně nevim jak na to
Editoval Tomas Trdla (20. 4. 2018 12:19)

- Ondřej Kubíček
 - Člen | 494
 
ten multiplier je jen na to abys to nedělal tak prasácky jak jsi to měl
:)
jinak jsem ti psal, že tam nemáš ajax, takže si nastuduj https://doc.nette.org/…ication/ajax
Editoval Ondřej Kubíček (20. 4. 2018 12:21)

- Tomas Trdla
 - Člen | 19
 
takze…
    public function createComponentSearchForm($formId) {
        return new Multiplier(function ($formId) {
            $form = new Form;
            $this->DBpatientSearchFF->AddFilterFields($form);
            $form->getElementPrototype()->class('ajax'); // pridavam ajax formu poprve
            $form->onSuccess[] = array($this, 'postFormSucceeded');
            return $form;
        });
    }
<form n:snippet="fsnipet$id" n:name=searchForm-$id class="validation-form ajax"> pridavam ajax do formu podruhe
	{include '../MultipresenterForms/dbSearchForm.latte'}
	<fieldset class="form-group">
		<a n:href="FormRefresh! $id" class="btn btn-warning ajax"> Odebrat křivku</a> *V1* s ajaxem pres handle
		<a n:href="FormRefresh! $id" class="btn btn-warning"> Odebrat křivku</a> *V2* bez ajaxu pres handle
		<input n:name=send class="btn btn-primary ajax"> *V3* s ajaxem pres submit
		<input n:name=send class="btn btn-primary"> *V4* bez ajaxu pres submit
	</fieldset>
</form>
a vysledek:
    public function postFormSucceeded($form, $values) {//tady form ziskam, ale nejde ajax
        if (!$this->isAjax()) {
            // tady skonci V3 a V4
        } else {
            // sem se nedostane nikdy
        }
    }
    public function handleFormRefresh($id) { // nevim jak ziskat form, ale ajax jde
        if (!$this->isAjax()) {
            // sem se dostane V2
        } else {
            // sem se dostane V1
			// ale nemam obekt formu abych z nej mohl nacist hodnoty nebo s nim vubec neco udelat
        }
    }
a pro uplnost layout a js inicializace
{block scripts}
	...
	<!-- Ajax scripts -->
	<script src="{$basePath}/bs/js/nette.ajax.js"></script>
	...
{/block}
$(function () {
    $.nette.init();
});
jak tedy ziskam formular? uz jsem stravil nekolik hodin hledanim a nenasel nic co by mi fungovalo
jo a V3 mi vyhazuje chybu v konzoli:
Uncaught ReferenceError: Nette is not defined	(nette.ajax.js:319)
    at Object.before (nette.ajax.js:319)
    at Function.<anonymous> (nette.ajax.js:42)
    at Function.each (jquery.min.js:2)
    at Object.fire (nette.ajax.js:40)
    at Object.settings.beforeSend (nette.ajax.js:215)
    at Function.ajax (jquery.min.js:4)
    at nette.ajax (nette.ajax.js:225)
    at HTMLFormElement.requestHandler (nette.ajax.js:48)
    at HTMLFormElement.dispatch (jquery.min.js:3)
    at HTMLFormElement.q.handle (jquery.min.js:3)
je radek:
if ((typeof Nette.version === 'undefined' || Nette.version == '2.3')) { // Nette 2.3 and older
a jediny co je starsi nez 2.3 jsou tyhle:
"name": "nette/tester",
"version": "v1.7.1"
"name": "dg/composer-cleaner",
"version": "v1.0",
					Editoval Tomas Trdla (26. 4. 2018 14:14)

- Tomas Trdla
 - Člen | 19
 
Asi uz jsem na to prisel. Mel jsem v layoutu zakomentovane
{block scripts}
	<!-- Nette forms -->
	<script src="https://nette.github.io/resources/js/netteForms.min.js"></script>
	...
{/block}
po odkomentovani to uz skocilo tam kam melo
… ted si jeste vzpomenou proc to bylo zakomentovane
Editoval Tomas Trdla (26. 4. 2018 14:21)

- Tomas Trdla
 - Člen | 19
 
Nicmene stale to neresi muj problem… snippet se proste neprekresli
{snippetArea wrapper}
	<div class="cont">
		{foreach $forms as $id}
			{var snipname = "fs$id"}
			{snippet $snipname}
				<form n:name=searchForm-$id class="validation-form ajax">
					{include '../MultipresenterForms/dbSearchForm.latte'}
					<fieldset class="form-group">
						<a class="btn btn-primary" onClick="HandleThisForms(this,{$id}, 'filter')">Aplikovat filtry</a>
						<input n:name=send class="btn btn-primary">
					</fieldset>
				</form>
			{/snippet}
		{/foreach}
	</div>
{/snippetArea}
public function postFormSucceeded($form, $values) {
	if ($this->isAjax()) {
		$id = $values->formID;
		$form->setValues([], TRUE);
		$form->setValues(['formID' => $id], TRUE);
		$this->redrawControl("fs$id");
	}
}
jako odpoved v XHR se mi dostane pouze
{state: []}
	state:[]
jmena snippetu co chci prekreslit jsou stejna jako na strance