rob-balfre / svelte-select

Svelte Select. A select component for Svelte
https://svelte-select-examples.vercel.app
Other
1.25k stars 175 forks source link

Submit value instead of whole object for complex items #571

Open sebastianbonilla opened 1 year ago

sebastianbonilla commented 1 year ago

I've got a json file that I'm using as input for a select element. The json is something like:

[ { "label": "England", "value": "ENGLAND", "emoji": "🏴󠁧󠁢󠁥󠁮󠁧󠁿", "univalue": "U+1F3F4 U+E0067 U+E0062 U+E0065 U+E006E U+E0067 U+E007F", "image": "https://cdn.jsdelivr.net/npm/country-flag-emoji-json@2.0.0/dist/images/ENGLAND.svg" }, { "label": "Scotland", "value": "SCOTLAND", "emoji": "🏴󠁧󠁢󠁳󠁣󠁴󠁿", "univalue": "U+1F3F4 U+E0067 U+E0062 U+E0073 U+E0063 U+E0074 U+E007F", "image": "https://cdn.jsdelivr.net/npm/country-flag-emoji-json@2.0.0/dist/images/SCOTLAND.svg" } ] And the element is:

`<Select items={countries} name="country2">

{item.emoji} {item.label}
        </Select>`

I'm also using sveltekit forms. When submitting my form, the value for country2 is the whole object, so if I selected for instance Antigua & Barbuda then I'm getting on +page.server.js the whole object:

{ name: 'country2', value: '{"label":"Antigua & Barbuda","value":"AG","emoji":"🇦🇬","univalue":"U+1F1E6 U+1F1EC","image":"https://cdn.jsdelivr.net/npm/country-flag-emoji-json@2.0.0/dist/images/AG.svg"}' }

I tried using value but still it's submitting the whole object. Is that the original intent of value? or is this an error?

Thanks

maximilianmeier commented 1 year ago

I solved it like that

    <Select {items} bind:justValue />
    <input type="hidden" name="ingredient" bind:value={justValue} />
Josh-Nicholson commented 1 year ago

How could you do this when trying to bind the select to another variable? I'm using sveltekit-superforms and I'm trying to bind to a formFieldProxy value.

My form looks like this:

<script lang="ts>
  const form = superForm(data);
  const enhance = form.enhance;
  const submitting = form.submitting;

  const { value: idValue, errors: idErrors } = formFieldProxy(form, 'id');

  async function getItemsFromSearchString(searchText: string) {
    if (!searchText.length) return Promise.resolve([]);
    try {
        const response = await fetch(`/api/items/searchText=${searchText}`);
        const items = await response.json();
        return Promise.resolve(parts);
    } catch (error) {
        return Promise.resolve([]);
    }
  }
</script>
<form method="POST" use:enhance>
<Select
  name="id"
  bind:justValue={$idValue}
  loadOptions={getItemsFromSearchString}
  placeholder="Search..."
  containerStyles="background-color: rgb(var(--color-surface-200)); border-radius: var(--theme-rounded-base); border-width: var(--theme-border-base); border-color: rgb(var(--color-surface-400));"
  >
    <div slot="item" let:item let:index>
        <div>{item.itemNumber} - {item.description}</div>
    </div>
    <div slot="selection" let:selection>
        <div>{selection.itemNumber} - {selection.description}</div>
    </div>
  </Select>
  <button type="submit">Submit</button>
</form>

When submitting the form, the value is an object rather than just the value property

maximilianmeier commented 1 year ago

It is working, as the input, that the value is bind to, is hidden but the HTML form takes it into account when submitting. The value I assign to the input is just the single value such as an id

miklereverie commented 11 months ago

It is working, as the input, that the value is bind to, is hidden but the HTML form takes it into account when submitting. The value I assign to the input is just the single value such as an id

@maximilianmeier by any chance, did you get this working with multiple autocompletes? I have a form with multiple autocompletes from which I just need to get the value. Thing is I cant just store everything insde of justValue, I would need to declare a different justValue for each autoComplete, but it just doesn't seem to work, it returns undefined.

andreinistor commented 11 months ago

I solved it like this for Superforms: <Select value={$fields.recipe[i].product} bind:justValue={$fields.recipe[i].product} />

value is needed to set the initial selected item. (without bind:) bind:justValue updates your object.