Next.js Discord

Discord Forum

Don't want decimal numbers in form input to get accepted

Answered
QBit posted this in #help-forum
Open in Discord
Form should not accept decimal nos.
For <=0 numbers code is written to not accept them. Now it accepting positive decimal also but I don't want. What to do?
"use client"

import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
import { z } from "zod"
import { useRouter } from "next/navigation"

import { Button } from "@/components/ui/button"
import {
  Form,
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form"
import { Input } from "@/components/ui/input"

const FormSchema = z.object({
  ID: z
    .string()
    .min(1, { message: "Problem ID must be at least 1 character" })
    .refine((value) => parseInt(value) > 0, {
      message: "ID must be greater than zero",
    }),
})

export function ProblemIDForm() {
  const form = useForm<z.infer<typeof FormSchema>>({
    resolver: zodResolver(FormSchema),
    defaultValues: {
      ID: undefined,
    },
  })

  const router = useRouter()
  function onSubmit(values: z.infer<typeof FormSchema>) {
    // console.log(values)
    router.push(`/problems/${values.ID}`)
  }

  return (
    <Form {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)} className="w-2/3 space-y-6">
        <FormField
          control={form.control}
          name="ID"
          render={({ field }) => (
            <FormItem>
              <FormLabel className="flex justify-center">Problem ID</FormLabel>
              <FormControl>
                <Input type="number" placeholder="Enter ID here" {...field} />
              </FormControl>
              <FormDescription>LeetCode problem ID</FormDescription>
              <FormMessage />
            </FormItem>
          )}
        />
        <div className="flex justify-center">
          <Button type="submit">Submit</Button>
        </div>
      </form>
    </Form>
  )
}
Answered by alfonsus ardani
try
z.coerce.number().int().positive().finite()
View full answer

14 Replies

@QBit Form should not accept decimal nos. For <=0 numbers code is written to not accept them. Now it accepting positive decimal also but I don't want. What to do? ts "use client" import { zodResolver } from "@hookform/resolvers/zod" import { useForm } from "react-hook-form" import { z } from "zod" import { useRouter } from "next/navigation" import { Button } from "@/components/ui/button" import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form" import { Input } from "@/components/ui/input" const FormSchema = z.object({ ID: z .string() .min(1, { message: "Problem ID must be at least 1 character" }) .refine((value) => parseInt(value) > 0, { message: "ID must be greater than zero", }), }) export function ProblemIDForm() { const form = useForm<z.infer<typeof FormSchema>>({ resolver: zodResolver(FormSchema), defaultValues: { ID: undefined, }, }) const router = useRouter() function onSubmit(values: z.infer<typeof FormSchema>) { // console.log(values) router.push(`/problems/${values.ID}`) } return ( <Form {...form}> <form onSubmit={form.handleSubmit(onSubmit)} className="w-2/3 space-y-6"> <FormField control={form.control} name="ID" render={({ field }) => ( <FormItem> <FormLabel className="flex justify-center">Problem ID</FormLabel> <FormControl> <Input type="number" placeholder="Enter ID here" {...field} /> </FormControl> <FormDescription>LeetCode problem ID</FormDescription> <FormMessage /> </FormItem> )} /> <div className="flex justify-center"> <Button type="submit">Submit</Button> </div> </form> </Form> ) }
what do you want the value to be?
positive nonnegative integers?
@QBit Form should not accept decimal nos. For <=0 numbers code is written to not accept them. Now it accepting positive decimal also but I don't want. What to do? ts "use client" import { zodResolver } from "@hookform/resolvers/zod" import { useForm } from "react-hook-form" import { z } from "zod" import { useRouter } from "next/navigation" import { Button } from "@/components/ui/button" import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form" import { Input } from "@/components/ui/input" const FormSchema = z.object({ ID: z .string() .min(1, { message: "Problem ID must be at least 1 character" }) .refine((value) => parseInt(value) > 0, { message: "ID must be greater than zero", }), }) export function ProblemIDForm() { const form = useForm<z.infer<typeof FormSchema>>({ resolver: zodResolver(FormSchema), defaultValues: { ID: undefined, }, }) const router = useRouter() function onSubmit(values: z.infer<typeof FormSchema>) { // console.log(values) router.push(`/problems/${values.ID}`) } return ( <Form {...form}> <form onSubmit={form.handleSubmit(onSubmit)} className="w-2/3 space-y-6"> <FormField control={form.control} name="ID" render={({ field }) => ( <FormItem> <FormLabel className="flex justify-center">Problem ID</FormLabel> <FormControl> <Input type="number" placeholder="Enter ID here" {...field} /> </FormControl> <FormDescription>LeetCode problem ID</FormDescription> <FormMessage /> </FormItem> )} /> <div className="flex justify-center"> <Button type="submit">Submit</Button> </div> </form> </Form> ) }
Number.isInteger() to check if a number is an integer
Ackshually, zod has native methods for this
z.number().int().positive().finite() is probably what you need
when I changed the zod FormSchema to this @joulev
const FormSchema = z.object({
  // ID: z
  //   .string()
  //   .min(1, { message: "Problem ID must be at least 1 character" })
  //   .refine((value) => parseInt(value) > 0, {
  //     message: "ID must be greater than zero",
  //   }),
  ID: z.number().int().positive().finite(),
})

Now the integer is not getting accepted
I think my z.number() is not working. Something maybe mismatched
@alfonsus ardani what do you want the value to be?
I want to accept only natural numbers 1, 2, 3,....
I don't want 23.45, 38.6, .... such decimal numbers
currently form is accepting pos decimal also
Answer
@alfonsus ardani try tsx z.coerce.number().int().positive().finite()
working!!
thanks!!
Glad it worked!