« home

svelte-multiselect Svelte MultiSelect

Hook up Multiselect to SvelteKit form action incl. form validation

This example shows the SvelteKit form action way of handling MultiSelect fields in form submission events. If you’re not interested in progressively enhanced forms (i.e. supporting no-JS browsers) take a look at the JS form example instead.

Note that this example will only work when running the dev server locally since it needs a server to respond to the form’s POST request and this documentation site is only static HTML.

select some options, then click submit to see what data MultiSelect sends to a form submit handler
<script lang="ts">import MultiSelect from 'svelte-multiselect';
import { ColorSlot } from '$site';
import { colors } from '$site/options';
import { repository } from '$root/package.json';
export let form;
// export let data: PageServerData
$: err_msg = {
    json: 'The email field is required',
    array: 'The email field is required',
    boring: 'Boring answer!',
}[form?.error];
</script>

<form method="POST" action="?/validate-form">
  <label for="colors">
    <strong>Which colors would you pick for the Martian flag?</strong>
  </label>
  <MultiSelect
    options={colors}
    placeholder="Pick some colors..."
    name="colors"
    required
    invalid={!!form?.error}
    selected={form?.colors ?? [`Red`]}
    let:idx
    let:option
  >
    <ColorSlot {idx} {option} />
  </MultiSelect>
  <button>Submit</button>
  <small>
    select some options, then click submit to see what data MultiSelect sends to a form
    submit handler
  </small>
  {#if err_msg}
    <p class="error">{err_msg}</p>
  {/if}
  {#if form?.success}
    <p class="success">
      Good answer! You entered
      {#each form.colors as color}
        <ColorSlot
          option={color}
          style="display: inline-flex; vertical-align: middle; margin: 0 0 0 1ex;"
        />
      {/each}
    </p>
  {/if}
</form>

+page.server.ts

The above code needs to be in a +page.svelte file with the following +page.server.ts file in the same directory next to it.

import { invalid } from '@sveltejs/kit'

export const actions = {
  'validate-form': async ({ request }) => {
    const data = await request.formData()
    let colors = data.get(`colors`)

    try {
      colors = JSON.parse(colors)
    } catch (err) {
      return invalid(400, { colors, error: `json` })
    }

    if (!Array.isArray(colors)) {
      return invalid(400, { colors, error: `array` })
    }
    if (colors.length === 1 && colors[0] === `Red`) {
      return invalid(400, { colors, error: `boring` })
    }

    return { colors, success: true }
  },
}