From 1be637907594064b5d2629fb03ab15d5ddf52417 Mon Sep 17 00:00:00 2001 From: Johan Bisse Mattsson Date: Thu, 14 Nov 2024 11:01:23 +0100 Subject: [PATCH] LWS-260: Codemirror extension for submitting forms on enter key (#1155) * Add CodeMirror extension for submitting form on enter keypress * Add test * Add optional form attribute * Add hidden textarea inside component for name and value attributes --- lxl-web/src/lib/components/Search.svelte | 13 +++++-- packages/supersearch/e2e/supersearch.spec.ts | 17 +++++++++ .../src/lib/components/SuperSearch.svelte | 9 ++++- .../lib/extensions/submitFormOnEnterKey.ts | 37 +++++++++++++++++++ packages/supersearch/src/routes/+page.svelte | 17 ++++++++- .../supersearch/src/routes/test1/+page.svelte | 1 + .../supersearch/src/routes/test2/+page.svelte | 1 + 7 files changed, 88 insertions(+), 7 deletions(-) create mode 100644 packages/supersearch/e2e/supersearch.spec.ts create mode 100644 packages/supersearch/src/lib/extensions/submitFormOnEnterKey.ts create mode 100644 packages/supersearch/src/routes/test1/+page.svelte create mode 100644 packages/supersearch/src/routes/test2/+page.svelte diff --git a/lxl-web/src/lib/components/Search.svelte b/lxl-web/src/lib/components/Search.svelte index 050b78ed8..fdcd82546 100644 --- a/lxl-web/src/lib/components/Search.svelte +++ b/lxl-web/src/lib/components/Search.svelte @@ -15,8 +15,8 @@ let q = $page.params.fnurgel ? '' //don't reflect related search on resource pages : showAdvanced - ? $page.url.searchParams.get('_q')?.trim() - : $page.url.searchParams.get('_i')?.trim(); + ? $page.url.searchParams.get('_q')?.trim() || '' + : $page.url.searchParams.get('_i')?.trim() || ''; let params = getSortedSearchParams(addDefaultSearchParams($page.url.searchParams)); // Always reset these params on new search @@ -30,7 +30,7 @@ /** Update input value after navigation on /find route */ if (to?.url) { let param = showAdvanced ? '_q' : '_i'; - q = $page.params.fnurgel ? '' : new URL(to.url).searchParams.get(param)?.trim(); + q = $page.params.fnurgel ? '' : new URL(to.url).searchParams.get(param)?.trim() || ''; } }); @@ -45,7 +45,12 @@
{#if env?.PUBLIC_USE_SUPERSEARCH === 'true'} - + {:else} { + await page.goto('/'); +}); + +test('submits closest form on enter key press', async ({ page }) => { + await page.locator('[data-test-id="test1"]').getByRole('textbox').locator('div').fill('hello world') + await page.keyboard.press('Enter'); + await expect(page).toHaveURL('/test1?q=hello+world') +}); + +test('submits form identified by form attribute on enter key press', async ({ page }) => { + await page.locator('[data-test-id="test2"]').getByRole('textbox').locator('div').fill('hello world') + await page.keyboard.press('Enter'); + await expect(page).toHaveURL('/test2?q=hello+world') +}); \ No newline at end of file diff --git a/packages/supersearch/src/lib/components/SuperSearch.svelte b/packages/supersearch/src/lib/components/SuperSearch.svelte index 0a8acc9ef..99e2c24cf 100644 --- a/packages/supersearch/src/lib/components/SuperSearch.svelte +++ b/packages/supersearch/src/lib/components/SuperSearch.svelte @@ -3,21 +3,25 @@ import { EditorView, placeholder as placeholderExtension } from '@codemirror/view'; import { Compartment } from '@codemirror/state'; import { type LRLanguage } from '@codemirror/language'; + import submitFormOnEnterKey from '$lib/extensions/submitFormOnEnterKey.js'; interface Props { + name: string; + value?: string; + form?: string; language?: LRLanguage; placeholder?: string; } - let { language, placeholder = '' }: Props = $props(); + let { name, value = $bindable(''), form, language, placeholder = '' }: Props = $props(); - let value = $state(''); let editorView: EditorView | undefined = $state(); let placeholderCompartment = new Compartment(); let prevPlaceholder = placeholder; const extensions = [ + submitFormOnEnterKey(form), ...(language ? [language] : []), placeholderCompartment.of(placeholderExtension(placeholder)) ]; @@ -37,3 +41,4 @@ + diff --git a/packages/supersearch/src/lib/extensions/submitFormOnEnterKey.ts b/packages/supersearch/src/lib/extensions/submitFormOnEnterKey.ts new file mode 100644 index 000000000..d09f25558 --- /dev/null +++ b/packages/supersearch/src/lib/extensions/submitFormOnEnterKey.ts @@ -0,0 +1,37 @@ +import { Prec } from '@codemirror/state'; +import { EditorView, keymap } from '@codemirror/view'; + +/** + * CodeMirror extension that submits form elements (either the closest or by specified id using the `form` attribute) on enter keypresses. + * + * @param {string} form Optional id of the `` element with which the form control should be associated with (equivalent with + * the [form attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#form) on HTML Input elements). + */ + +const submitFormOnEnterKey = (form?: string) => { + const submitForm = (editorView: EditorView) => { + const formElement = form ? document.getElementById(form) : editorView.dom?.closest('form'); + + if (formElement && formElement instanceof HTMLFormElement) { + formElement.requestSubmit(); + return true; // return true to prevent further commands to be tried + } + + return false; + }; + + return Prec.highest( + keymap.of([ + { + key: 'Enter', + run: submitForm + }, + { + key: 'Shift-Enter', + run: submitForm + } + ]) + ); +}; + +export default submitFormOnEnterKey; diff --git a/packages/supersearch/src/routes/+page.svelte b/packages/supersearch/src/routes/+page.svelte index 979b1757f..27799f04f 100644 --- a/packages/supersearch/src/routes/+page.svelte +++ b/packages/supersearch/src/routes/+page.svelte @@ -1,9 +1,24 @@ - + +
+ Supersearch inside <form> element + +
+ + +
+
+ Supersearch using form attribute + +
+
+ +
diff --git a/packages/supersearch/src/routes/test1/+page.svelte b/packages/supersearch/src/routes/test1/+page.svelte new file mode 100644 index 000000000..ac07b7c64 --- /dev/null +++ b/packages/supersearch/src/routes/test1/+page.svelte @@ -0,0 +1 @@ +

A test route

\ No newline at end of file diff --git a/packages/supersearch/src/routes/test2/+page.svelte b/packages/supersearch/src/routes/test2/+page.svelte new file mode 100644 index 000000000..1d6fd03ad --- /dev/null +++ b/packages/supersearch/src/routes/test2/+page.svelte @@ -0,0 +1 @@ +

Another test route

\ No newline at end of file