How can i reset a Select field? #638
-
I currently have:
How can i make the select form reset back to the placeholder text? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 11 replies
-
I did this by adding a button at the end of the list, making sure to change the key assigned to the select so that when I change the value I can force it to re render... here's a simple example: export const SelectDemo = () => {
const [key, setKey] = React.useState(+new Date())
const [value, setValue] = React.useState<string | undefined>(undefined)
return (
<>
<Select key={key} value={value}>
<SelectTrigger>
<SelectValue placeholder="Select a Theme" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel className="-ml-2 text-xs">Category 1</SelectLabel>
<SelectItem value="light">Light</SelectItem>
<SelectItem value="dark">Dark</SelectItem>
<SelectItem value="system">System</SelectItem>
</SelectGroup>
<SelectGroup>
<SelectLabel className="-ml-2 text-xs">Category 2</SelectLabel>
<SelectItem value="cobalt2">Cobalt2</SelectItem>
</SelectGroup>
<SelectSeparator />
<Button
className="w-full px-2"
variant="secondary"
size="sm"
onClick={(e) => {
e.stopPropagation()
setValue(undefined)
setKey(+new Date())
}}
>
Clear
</Button>
</SelectContent>
</Select>
</>
)
} |
Beta Was this translation helpful? Give feedback.
-
check this snippet added a 'x' icon for clearing, used the same approach as the above ans.
|
Beta Was this translation helpful? Give feedback.
-
@cchin25 This is a complete example, with separate select examples and form examples. const SelectTrigger = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger> & { onReset?: () => void }
>(({className, children, onReset, ...props}, ref) => {
return (
<div
className={cn(
"relative z-0 flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
className
)}
>
<SelectPrimitive.Trigger
ref={ref}
className={cn("w-full text-left pl-3 pr-10 py-2 truncate")}
{...props}
>
<span className={cn(`w-full pr-2 truncate`, !props.value && "text-neutral-400")}>{children}</span>
</SelectPrimitive.Trigger>
<SelectPrimitive.Icon className={cn(`absolute right-2 cursor-pointer`, !props.value && "pointer-events-none")}>
{props.value ? <CircleXIcon className="h-4 w-4 opacity-50" onClick={onReset}/> : <ChevronDown className="h-4 w-4 opacity-50 "/>}
</SelectPrimitive.Icon>
</div>
)
}) import {Select, SelectContent, SelectItem, SelectTrigger, SelectValue} from "@/components/ui/select"
import {useState} from "react";
import {zodResolver} from "@hookform/resolvers/zod"
import {useForm} from "react-hook-form"
import {z} from "zod"
import {Button} from "@/components/ui/button"
import {Form, FormControl, FormField, FormItem, FormLabel, FormMessage} from "@/components/ui/form"
const FormSchema = z.object({
email: z.string({required_error: "Please select an email to display.",}).nonempty().email(),
})
function App() {
const [theme, setTheme] = useState<string>("")
const form = useForm<z.infer<typeof FormSchema>>({
resolver: zodResolver(FormSchema),
defaultValues: {
email: ""
}
})
function onSubmit(data: z.infer<typeof FormSchema>) {
console.log("Form Data-->", data)
}
return (
<div className="flex gap-x-8">
<div className="">
<Select value={theme} onValueChange={setTheme}>
<SelectTrigger asChild className="w-[280px]" value={theme} onReset={() => setTheme("")}>
<SelectValue placeholder="Place Select Theme" defaultValue={theme}/>
</SelectTrigger>
<SelectContent>
<SelectItem value="light">Light</SelectItem>
<SelectItem value="dark">Dark</SelectItem>
<SelectItem value="system">System</SelectItem>
</SelectContent>
</Select>
<Button onClick={() => console.log("theme-->", theme)}>Theme</Button>
</div>
<div>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="w-[400px] space-y-6">
<FormField
control={form.control}
name="email"
render={({field}) => (
<FormItem>
<FormLabel>Email</FormLabel>
<Select onValueChange={field.onChange} value={field.value}>
<FormControl>
<SelectTrigger value={field.value} onReset={() => form.resetField("email")}>
<SelectValue placeholder="Select a verified email to display"/>
</SelectTrigger>
</FormControl>
<SelectContent>
<SelectItem value="m@example.com">m@example.com</SelectItem>
<SelectItem value="m@google.com">m@google.com</SelectItem>
<SelectItem value="m@support.com">m@support.com</SelectItem>
</SelectContent>
</Select>
<FormMessage/>
</FormItem>
)}
/>
<div className="space-x-2">
<Button type='button' variant="destructive" onClick={() => form.reset()}>Reset</Button>
<Button type="submit">Submit</Button>
</div>
</form>
</Form>
</div>
</div>
)
}
export default App Kapture.2025-01-19.at.16.42.33.mp4@wan-mureithi When there is a value, the element mouse event needs to be ignored |
Beta Was this translation helpful? Give feedback.
I did this by adding a button at the end of the list, making sure to change the key assigned to the select so that when I change the value I can force it to re render... here's a simple example: