Jak na tlačítko „zrušit“?

Šaman
Člen | 2663
+
0
-

Mám formuláře, které mají už defaultně nějakou obsluhu v onSubmit. Do toho zasahovat nechci.
Teď ale potřebuji přidat tlačítko „Zrušit“. Pokud ho přidám jako addSubmit(), tak se mi spustí ty obslužné rutny, což nechci.
Když ho přidám jako addButton(), tak mohu nějak nastavit obslužnou rutinu? Jde mi buď o možnost zapsat nějakou obsluhu v definici formuláře (jako je metoda onClick u submit buttonu), nebo ajaxové spuštění handleru.

Ideálně bez psaní JS, všechno v definici formuláře.

Editoval Šaman (4. 3. 2019 17:33)

MajklNajt
Člen | 498
+
+1
-

myslím, že budeš musieť prerobiť default obsluhu z onSubmit na onClick, alebo minimálne pridať do onSubmit podmienku $form->isSubmitted() === $form['submit']

Šaman
Člen | 2663
+
0
-

Já bych se právě rád vyhnul zasahování do odesílání formuláře. Tohle má jít úplně mimo.
On vlastně stačí ajaxový odkaz, ale teď už jen přemýšlím jak co nejjednodušeji vykreslit mezi ostatní submity bez manuálního renderování.

David Matějka
Moderator | 6445
+
0
-

ještě by vzhledem k pořadí volání těch eventů šlo udělat, že v onClick cancel buttonu vymažeš onSubmit/onSuccess eventy formuláře. ale spíše bych dopuručil cestu, jak píše @MajklNajt

MajklNajt
Člen | 498
+
0
-

ak to teraz refaktoruješ, budeš mať menej problémov v budúcnosti, napr. ak budeš chcieť pridať ďalší submit, ktorý ti bude napr. generovať preview…

duke
Člen | 650
+
0
-

Na druhou stranu chápu @Šaman, že to chce mít mimo odesílání formuláře. Nač odesílat všechna data formuláře, když uživatel chce jen operaci zrušit (absurdní je to např. v případě, kdy formulář obsahuje upload inputy). Možná by nebylo špatné mít pro tento případ speciální button, který by se nerenderoval jako input/button, ale jako odkaz na signál. Otázka je, nakolik a jak je možné to pak propojit s událostmi formuláře, aby na to šlo navěšovat handlery, které se provedou i jindy než při form submitu. Možná nějak přes rozšíření třídy UI\Form…

CZechBoY
Člen | 3608
+
+1
-

Já mám většinou reset tlaačítko implementované jen jako <input type=reset>.
Jakou funkcionalitu od toho očekáváš?

Šaman
Člen | 2663
+
+4
-

Vyřešeno vlastním custom inputem HrefButton (ale button to není:). Pracuje se s ním stejně, jako s formulářovým inputem, ale obsahuje čistý odkaz. Do BootstrapRendereru stačilo přidat jednu podmínku, aby to tenhle „input“ renderovalo společně s buttony a submity.

Takže mám odkaz, který vede na signál (handleReset) a který je normálně ajaxový, když se mu nastaví třída ajax.

<?php

namespace App\Utils;

use Nette\Forms\Controls\BaseControl;


class HrefButton extends BaseControl
{
	protected $href = '#';
	protected $class = 'btn btn-default';

	function getControl()
	{
		return "<a href='$this->href' class='$this->class'>$this->caption</a>";
	}

	// aby se tento "input" nedostal do odeslaných hodnot
	public function isOmitted()
	{
		return TRUE;
	}

	// aby se při vykreslování nezobrazovalo nic ve sloupci s labely inputů
	function getLabel($caption = null)
	{
		return NULL;
	}

	public function setHref(string $href)
	{
		$this->href = $href;
	}

	public function setClass(string $class)
	{
		$this->class = $class;
	}

	public function addClass(string $class)
	{
		$this->class .= ' ' . $class;
	}

}
?>

Použití ve formuláři (tohle přidávám až v presenteru v createComponent…Form. V definici samotného formuláře to nemá co dělat.

<?php
	$form = $this->formFactory->create();
	// …
	$cancelButton = new \App\Utils\HrefButton('Zavřít formulář');
	$cancelButton->setHref($this->link('redrawPanel!'));
	$cancelButton->addClass('ajax');
	$form['cancel'] = $cancelButton;
	// …
?>

Výsledkem je „tlačítko“ vyrenderované jako součást formuláře bez nutnosti manuálního renderování.

Editoval Šaman (4. 3. 2019 23:47)

andros
Člen | 145
+
0
-

A co jsi přidal do Bootstrap.php ? Aby to bylo kompletní ?

Ondřej Kubíček
Člen | 494
+
+3
-

@Šaman akorát bych ten element vytvářel přes Html::el() :)

CZechBoY
Člen | 3608
+
0
-

A jak vypada ten handleReset?

Šaman
Člen | 2663
+
0
-

HandleReset obsahuje jen redrawControl() a volá se nad nějakým panelem jehož součástí je i formulář. Ale může být samozřejmě složitější, pokud by bylo potřeba. Pro mě je klíčové, že nemusím vytvářet JS.

Určitě by to šlo udělat lépe, možná pokud to bude ještě někdy potřeba. Tohle je nejjednodušší nástřel.

A ten Bootstrap3FormRenderer jsem měl upravený uz předtím, tak nevím kde přesně to bude, ale jedná se o podmínku v metodě renderControls. Tam se vybírají prvky, které se pak vykreslí v poli tlačítek (jinak se v další části podmínky vykreslí jako běžný pár label – control).

<?php
elseif ($control instanceof Nette\Forms\Controls\Button || $control instanceof \App\Utils\HrefButton) {
	$buttons[] = $control;
}
?>

Editoval Šaman (5. 3. 2019 10:07)

CZechBoY
Člen | 3608
+
0
-

@Šaman A jakou to má teda výhodu oproti prohlížečovýmu resetu?

Šaman
Člen | 2663
+
0
-

@CZechBoY: Zavře to formulář, tedy překreslí panel (tzn. místo formuláře tam je zase tlačítko „přidat“ atd.) Nešlo mi jen o vymazání hodnot.

Kdybych to měl modálně, tak tohle neřeším a jen zavřu celý modal bez uložení změn.


Ono když o tom přemýšlím, tak do sekce „formuláře“ to moc nepatří. Výsledkem je vlastně odkaz na signál něaké nadřazené komponenty a ten odkaz by měl být také v té komponentě. Jediný problém, že požadavek byl aby se to tvářilo jako tlačítko formuláře (protože pro uživatele to není akce „překreslit celý panel“, ale „zavřít tenhle formulář“). A bez manuálního renderování.
A html button prostě jako odkaz upravit moc nejde.

Editoval Šaman (5. 3. 2019 11:02)