Klávesové zkratky ve formulářích

DefenestrationPraha
Člen | 99
+
0
-

Mám formuláře s tlačítky Back a Submit, ke kterým bych rád nastavil klávesovou zkratku (Esc pro Back, Enter pro Submit). To umím udělat pomocí následující jquery:

$(document).ready(function() {
    $("input").keyup(function(e) {
        if (e.which == 13) {
            $('#submit-button').click();
            return false;
        }
        if (e.which == 27) {
            $('#back-button').click();
            return false;
        }
        return true;
    });
});

Jenže tento kód zároveň deaktivuje všechny validace Nette Forms a submitne veškerá data bez kontroly.

Řešil už někdo tento nebo podobný problém? Aby klávesnicové zkratky fungovaly zároveň s Nette Forms?

Kamil Valenta
Člen | 752
+
0
-
if (e.which == 13) {
    $('#form').submit();
}

?

DefenestrationPraha
Člen | 99
+
0
-

Kamil Valenta napsal(a):

if (e.which == 13) {
    $('#form').submit();
}

?

Tenhle kód zajišťuje, že zmáčkneš-li při práci s formulářem Enter, odešle se pomocí toho buttonu, který chceš, a ne pomocí prvního buttonu v DOM stromu HTML. Je totiž standardní vlastností HTML, že při stisku Enter se formulář odesílá prvním buttonem v pořadí ve formuláři, a ne „tím, kterým bys chtěl“.

Jelikož mám formuláře, kde nalevo je často šipečka „<- Zpět“ jako button, při stisku Enter by se odeslal formulář se „Zpět“, což většinou uživatel nechce. Enter je obvykle vnímáno jako zkratka k odeslání formuláře k dalšímu zpracování.

Nicméně o to tolik nejde. Moje otázka směřuje hlavně k tomu, jak nastavit klávesové zkratky na formulář společně s validací. Pokud je na to jiný postup, byl bych rád.

EDIT: Aha, to jsem nepochopil. Myslel jsem, že to tvoje ? je otázka, co myslím svým vlastním kódem. Ale tys tam do té citace dal upravený kód. Toho jsem si všiml až za chvíli. Někdy je ta přílišná stručnost zavádějící.

Jdu to zkusit, ale myslím si, že to submitne ten formulář defaultním buttonem, což je ten, který je v DOM stromu první. A ne tím, kterým bych chtěl.

Editoval DefenestrationPraha (25. 8. 2022 11:22)

DefenestrationPraha
Člen | 99
+
0
-

Možná bych to měl popsat podrobněji.

Takto vypadá typický formulář, u kterého bych chtěl, aby Esc aktivovalo Zpět a Enter aktivovalo submit, ale s validací Nette Formuláře. Žel sem nejde nahrávat přímo soubory, tak musím takto odkazem.

Jelikož tlačítko Esc je nalevo od tlačítka Odeslat, dostává v DOM stromu přednost, tj. v defaultním stavu zmáčknete-li Enter, odešle se formulář s tlačítkem Zpět. To nechci.

Jsou na to různé JS triky se zachytáváním klávesy, ale ty zase obejdou validaci Nette Forms, což je nežádoucí. To je ten problém, který mám.

Kamil Valenta
Člen | 752
+
0
-

Proč je tlačítko pro Zpět jako submit? Vůbec bych ho nedělal jako submit a tím bude mít form 1 submit navázaný na enter.
Pokud je problémem pořadí v DOM, tak nechť je submit první a cancel druhý. O tom, které bude vlevo a které vpravo přeci nerozhoduje pořadí v DOM, ale css.

DefenestrationPraha
Člen | 99
+
0
-

Kamil Valenta napsal(a):

Proč je tlačítko pro Zpět jako submit? Vůbec bych ho nedělal jako submit a tím bude mít form 1 submit navázaný na enter.
Pokud je problémem pořadí v DOM, tak nechť je submit první a cancel druhý. O tom, které bude vlevo a které vpravo přeci nerozhoduje pořadí v DOM, ale css.

Hmm, no, upřímně do toho CSS se mi nechtělo. Používám Form Factory z jednoho Nette Examplu, nechtěl jsem to kompletně rozstřelit.

Klidně bych předělal Zpět na button místo submit, ale jakým způsobem pak zachytím stisknutí tlačítka v prezentéru?

V současné době tam mám toto (např.):

    /**
     * @throws InvalidArgument
     * @noinspection PhpUnused
     */
    protected function createComponentEditGeneralSettingsForm() : Form {
        $form = $this->settingsFormFactory->createGeneralSettings($this->settings[SettingsConstants::GENERAL_SETTINGS_NAME]);
        $form->onSuccess[] = [$this, 'generalSettingsFormSubmitted'];
        return $form;
    }

a následně mám funkci

   /**
     * @throws AuthorizationException
     * @throws InvalidArgument
     * @throws AuthenticationException
     * @throws AbortException
     * @throws InvalidArgument
     * @noinspection PhpUnusedParameterInspection
     */
    #[NoReturn] public function generalSettingsFormSubmitted(Form $form, stdClass $data) : void
    {
        ... back nebo submit. ...

ve které si to přeberu. Kdyby se ale Zpět předělalo na button, patrně by se akce onSuccess nevyvolávala. Na co bych to pak měl navázat?

Editoval DefenestrationPraha (25. 8. 2022 11:40)

Kamil Valenta
Člen | 752
+
0
-

Co se děje při akci zpět, že to nemůže obstarat obyčejný n:href nebo handle?

DefenestrationPraha
Člen | 99
+
0
-

Kamil Valenta napsal(a):

Co se děje při akci zpět, že to nemůže obstarat obyčejný n:href nebo handle?

Do budoucna nevím. Snažím se to udělat tak, aby v situaci, kdy jednoho dne budu muset přidat sofistikovanější akci, nemusel předělávat několik prezentérů.

Dalo by se použít něco jako onClick()?

Jinak já veškeré ty formuláře generuji kódem, tj. existují Form Factories, ve kterých je kód jako

		$caption = $form->translForm('button.submit');
        $submit = $form->addSubmit(Constants::STANDARD_SEND_BUTTON_NAME, ($localizedString === self::DEFAULT_VALUE ? $caption : $localizedString));
        $submit->setHtmlId('kraken-submit-button');
        return $submit;

Víceméně nikde není formulář napsaný přímo v latte šabloně pomocí HTML značek, všechny se dělají v PHP pomocí Form Factories, aby se v případě potřeby mohly dát relativně snadno upravit přímo u zdroje a člověk nemusel prokopávat všechny desítky latte šablon, které má. V Latte je jenom odkaz na komponentu generovanou v prezentéru pomocí form factory.

Čili případné řešení v mém případě by zase mělo použít něco jiného než schopnosti latte šablon, jako jsou n:href a handle. Něco, co se dá zapsat přímo kódem.