diff --git a/packages/vuetify/src/components/VSelect/VSelect.tsx b/packages/vuetify/src/components/VSelect/VSelect.tsx index 8b114838d0d..f8d436aacf7 100644 --- a/packages/vuetify/src/components/VSelect/VSelect.tsx +++ b/packages/vuetify/src/components/VSelect/VSelect.tsx @@ -16,6 +16,7 @@ import { VVirtualScroll } from '@/components/VVirtualScroll' // Composables import { useScrolling } from './useScrolling' +import { useAutocomplete } from '@/composables/autocomplete' import { useForm } from '@/composables/form' import { forwardRefs } from '@/composables/forwardRefs' import { IconValue } from '@/composables/icons' @@ -160,6 +161,7 @@ export const VSelect = genericComponent model.value.map(selection => selection.value)) const isFocused = shallowRef(false) @@ -387,7 +389,8 @@ export const VSelect = genericComponent v.props.value).join(', ') } + modelValue={ model.value.map(v => v.props.title).join(', ') } + name={ undefined } onUpdate:modelValue={ onModelUpdate } v-model:focused={ isFocused.value } validationValue={ model.externalValue } @@ -420,6 +423,20 @@ export const VSelect = genericComponent ( <> + + { expect(screen.getAllByCSS('.v-checkbox-btn input:checked')).toHaveLength(1) }) + describe('native form submission', () => { + const items = [ + { title: 'Item 1', value: 1 }, + { title: 'Item 2', value: 2 }, + { title: 'Item 3', value: 3 }, + ] + + it('should include selected value in form data for single selection', async () => { + let submittedData: FormData | null = null + + render(() => ( +
{ + e.preventDefault() + submittedData = new FormData(e.target as HTMLFormElement) + }} + > + + + + )) + + const submitButton = screen.getByRole('button', { name: 'Submit' }) + await userEvent.click(submitButton) + + expect(submittedData).not.toBeNull() + expect(submittedData!.get('select')).toBe('1') + }) + + it('should include selected values in form data for multiple selection', async () => { + let submittedData: FormData | null = null + + render(() => ( +
{ + e.preventDefault() + submittedData = new FormData(e.target as HTMLFormElement) + }} + > + + + + )) + + const submitButton = screen.getByRole('button', { name: 'Submit' }) + await userEvent.click(submitButton) + + expect(submittedData).not.toBeNull() + const select = submittedData!.getAll('select') + expect(select).toHaveLength(2) + expect(select).toContain('1') + expect(select).toContain('2') + }) + }) + describe('Showcase', () => { generate({ stories }) }) diff --git a/packages/vuetify/src/composables/autocomplete.ts b/packages/vuetify/src/composables/autocomplete.ts index 756eb13d09a..143f2054e33 100644 --- a/packages/vuetify/src/composables/autocomplete.ts +++ b/packages/vuetify/src/composables/autocomplete.ts @@ -23,6 +23,8 @@ export function useAutocomplete (props: InputAutocompleteProps) { const isSuppressing = toRef(() => props.autocomplete === 'suppress') const fieldName = toRef(() => { + if (!props.name) return undefined + return isSuppressing.value ? `${props.name}-${uniqueId}-${reloadTrigger.value}` : props.name