question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

`enhance` should progressively enhance `<form method="GET">`

See original GitHub issue

Describe the problem

Currently, enhance only works on forms where method="POST". I would also like to progressively enhance a form where method="GET", e.g. a search form.

For of an example of the kind of form where this would be useful, see the REPL search form on svelte.dev. We currently have to write the submit callback ourselves.

It would be nice if we could use:enhance here as well to get the same behavior. This would also let us encourage people to further #useThePlatform by teaching progressive enhancement of <form method="GET"> and <form method="POST">.

<form
	on:submit|preventDefault={(e) => {
		const search = new FormData(e.target).get('search');
		goto(search ? `/apps?search=${encodeURIComponent(search)}` : '/apps');
	}}
>
	<input
		type="search"
		placeholder="Search"
		aria-label="Search"
		name="search"
		value={data.search}
	/>
</form>

Describe the proposed solution

Instead of calling fetch, when method === 'GET' the action would construct the query string from the form data and call goto(action), i.e. call the load function for the given action. Since this is a navigation and no data is returned, applyAction would not be called and the form property would not be updated.

So on submit, the following form would call goto('/search?q=cats'), the same as the browser would do if JS was not available. We call any +page.js or +page.server.js load function and navigate to the page at that route (what goto normally does).

<form method="GET" action="/search" use:enhance>
	<input name="q" value="cats">
	<button>Submit</button>
</form>

enhance should also be updated to take <button formmethod="GET"> into account, likely using event.submitter.

I don’t think a post-submit callback makes sense in this case, since it would trigger navigation. Any customizations could be implemented with $navigating, beforeNavigate, and afterNavigate.

One open question is do we allow customizing the options passed to goto? For instance, if the user wants to keep focus on the form with goto(action, { keepfocus: true }). Or do we have them implement the action themselves in that case?

Alternatives considered

Do nothing and have people implement it themselves.

Importance

nice to have

Additional Information

No response

Issue Analytics

  • State:closed
  • Created a year ago
  • Reactions:11
  • Comments:16 (12 by maintainers)

github_iconTop GitHub Comments

5reactions
david-pluggecommented, Oct 17, 2022

In the javascript-enabled case, the client side router handles each of these links just as it handles every other navigation

That made me think… Since we are dealing with basic navigation, should the router intercept form get requests?

With this bit of code i get global form get requests working just like anchor tags

// src/routes/+layout.svelte
onMount(() => {
	function handleSubmit(event: SubmitEvent) {
		const form = event.target;

		if (!(form instanceof HTMLFormElement)) {
			return;
		}

		const submitter = event.submitter as HTMLButtonElement | HTMLInputElement | null;

		const actionUrl = new URL(
			submitter?.hasAttribute('formaction') ? submitter.formAction : form.action
		);
		const reload =
			(submitter && submitter.getAttribute('data-sveltekit-reload') !== null) ||
			form.getAttribute('data-sveltekit-reload') !== null;

		// only handle get requests and same origin urls
		if (reload || form.method !== 'get' || actionUrl.origin !== location.origin) {
			return;
		}

		event.preventDefault();
		event.stopPropagation();
		const formData = new FormData(form);
		const query = new URLSearchParams(formData as any);
		goto(`?${query}`);
	}

	addEventListener('submit', handleSubmit);
	return () => {
		removeEventListener('submit', handleSubmit);
	};
});

We can opt out of this behavior just like with the links using data-sveltekit-reload

3reactions
gg187oncommented, Oct 12, 2022

I think it should be in one (not splitted)… there are two reasons:

1st, we already tell if it’s get or post via method= attribute, and telling it twice is weird. 2nd, we can have dynamic forms, e.g.

<script>
     export let forms = [];
</script>

{#each forms as form}
    <form method={form.method} action={form.action} use:enhance>
         {#each form.inputs as input}
              {input.text}<input type={input.type}>
         {/each}
         <button type="submit">Submit</button>
    </form>
{/each}

now imagine how would you do use:{form.method === 'get' ? enhanceGet : enhancePost} and even pass function to it, or some other things… it would be too complicated. In case of combined, it would be just use:enhance={form.handler}

Read more comments on GitHub >

github_iconTop Results From Across the Web

Progressively enhance for a more resilient web
The enhanced experience should be better and it should do more, otherwise the enhanced experience is not needed at all.
Read more >
Semantic form actions, and easier progressive enhancement
The demo app you get when you run npm create svelte includes a progressively enhanced <form> that allows you to create and edit...
Read more >
Build a dynamic MPA with Enhance
Learn about the Enhance framework, and the progressive enhancement mindset, to build mutli-page applications with HTML language.
Read more >
Progressive Enhancement and HTML Forms: use FormData
Enhance ! To apply Progressive Enhancement on HTML forms, there's this little JavaScript gem named FormData that one can use: The FormData ...
Read more >
Form actions • Docs • SvelteKit
When using <form> , client-side JavaScript is optional, but you can easily progressively enhance your form interactions with JavaScript to provide the best ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found