You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm testing modular forms with Qwik. I'm using the component from the playground Git repository and have successfully created a custom toPhoneNumber function. It formats a 10-digit number correctly when I type it in. However, I've noticed that I can still type in a string, which is not the default behavior for phone number inputs on the web. Do I need to implement separate logic to handle this, or is there a way to accomplish this through the form API?
index.tsc
import{typeDocumentHead}from"@builder.io/qwik-city";importtype{SubmitHandler}from"@modular-forms/qwik";import{$,component$}from"@builder.io/qwik";import{routeLoader$}from"@builder.io/qwik-city";importtype{InitialValues}from"@modular-forms/qwik";import{formAction$,valiForm$,useForm}from"@modular-forms/qwik";import{email,typeInput,minLength,object,string,regex,}from"valibot";import{TextInput}from"~/components/TextInput";import{toPhoneNumber}from"~/components/toPhoneNumber";constLoginSchema=object({name: object({first: string([minLength(1,"Please enter first name.")]),last: string([minLength(1,"Please enter last name.")]),}),email: string([minLength(1,"Please enter an email."),email("The email address is badly formatted."),]),phone: string([minLength(1,"Please enter your phone number."),regex(/^\+?(?:[0-9] ?){6,14}[0-9]$/,"Please enter a valid phone number."),]),});typeLoginForm=Input<typeofLoginSchema>;constgetInitialValues=(): InitialValues<LoginForm>=>({name: {first: "",last: "",},email: "",phone: "",});exportconstuseFormLoader=routeLoader$<InitialValues<LoginForm>>(()=>getInitialValues(),);// export const useFormAction = formAction$<LoginForm>((values) => {// // Runs on server// }, valiForm$(LoginSchema));exportdefaultcomponent$(()=>{const[loginForm,{ Form, Field }]=useForm<LoginForm>({loader: useFormLoader(),// action: useFormAction(),validate: valiForm$(LoginSchema),});consthandleSubmit: SubmitHandler<LoginForm>=$((values,event)=>{console.log(object(values));});return(<FormonSubmit$={handleSubmit}class="container flex flex-col gap-4"><Fieldname="name.first">{(field,props)=>(<TextInput{...props}value={field.value}error={field.error}type="text"// label="First Name"placeholder="First Name"required/>)}</Field><Fieldname="name.last">{(field,props)=>(<TextInput{...props}value={field.value}error={field.error}type="text"placeholder="Last Name"required/>)}</Field><Fieldname="email">{(field,props)=>(<TextInput{...props}value={field.value}error={field.error}type="email"placeholder="example@email.com"required/>)}</Field><Fieldname="phone"transform={toPhoneNumber({on: "input"})}>{(field,props)=>(<TextInput{...props}value={field.value}error={field.error}type="tel"placeholder="(000) 000-0000"requiredmaxlength={14}/>)}</Field><div>{loginForm.response.message}</div><buttontype="submit">Login</button></Form>);});exportconsthead: DocumentHead={title: "Modular Forms",meta: [{name: "description",content: "Modular Form description",},],};
toPhoneNumber.tsx
importtype{TransformOptions}from"@modular-forms/qwik";import{toCustom$}from"@modular-forms/qwik";exportfunctiontoPhoneNumber(options: TransformOptions){returntoCustom$<string>((value)=>{if(value===undefined)return;// Remove everything that is not a numberconstnumbers=value.replace(/\D/g,"");// Continue if string is not emptyif(numbers){// Extract area, first 3 and last 4constmatchResult=numbers.match(/(\d{0,3})(\d{0,3})(\d{0,4})/);if(matchResult!==null){const[,area,first3,last4]=matchResult;// If length or first 3 is less than 1if(first3.length<1){return`(${area}`;}// If length or last 4 is less than 1if(last4.length<1){return`(${area}) ${first3}`;}// Otherwise return full US numberreturn`(${area}) ${first3}-${last4}`;}}// Otherwise return an empty stringreturn"";},options);}
TextInput.tsx
import{component$,typeQRL,useSignal,useTask$}from"@builder.io/qwik";importclsxfrom"clsx";import{InputError}from"./InputError";import{InputLabel}from"./InputLabel";typeTextInputProps={ref: QRL<(element: HTMLInputElement)=>void>;type: "text"|"email"|"tel"|"password"|"url"|"number"|"date";name: string;value: string|number|undefined;onInput$: (event: Event,element: HTMLInputElement)=>void;onChange$: (event: Event,element: HTMLInputElement)=>void;onBlur$: (event: Event,element: HTMLInputElement)=>void;placeholder?: string;required?: boolean;class?: string;label?: string;error?: string;form?: string;maxlength?: number;};/** * Text input field that users can type into. Various decorations can be * displayed in or around the field to communicate the entry requirements. */exportconstTextInput=component$(({ label, value, error, ...props}: TextInputProps)=>{const{ name, required }=props;constinput=useSignal<string|number>();useTask$(({ track })=>{if(!Number.isNaN(track(()=>value))){input.value=value;}});return(<divclass={clsx("px-8 lg:px-10",props.class)}><InputLabelname={name}label={label}required={required}/><input{...props}class={clsx("h-14 w-full rounded-2xl border-2 bg-white px-5 text-amber-800 outline-none placeholder:text-slate-500 dark:bg-gray-900 md:h-16 md:text-lg lg:h-[70px] lg:px-6 lg:text-xl",error
? "border-red-600/50 dark:border-red-400/50"
: "border-slate-200 hover:border-slate-300 focus:border-sky-600/50 dark:border-slate-800 dark:hover:border-slate-700 dark:focus:border-sky-400/50",)}id={name}value={input.value}aria-invalid={!!error}aria-errormessage={`${name}-error`}/><InputErrorname={name}error={error}/></div>);},);
The text was updated successfully, but these errors were encountered:
You can try to filter and remove letters in toPhoneNumber with value.replace(/[a-z]/gi, '') or value.replace(/\D/g, ''). But it seems like that's already in your code.
Hey Fabian,
I'm testing modular forms with Qwik. I'm using the component from the playground Git repository and have successfully created a custom toPhoneNumber function. It formats a 10-digit number correctly when I type it in. However, I've noticed that I can still type in a string, which is not the default behavior for phone number inputs on the web. Do I need to implement separate logic to handle this, or is there a way to accomplish this through the form API?
index.tsc
toPhoneNumber.tsx
TextInput.tsx
The text was updated successfully, but these errors were encountered: