Next.js Discord

Discord Forum

Fetch form data after change

Unanswered
Collared Plover posted this in #help-forum
Open in Discord
Collared PloverOP
Hey, I'm trying to create a booking system, which checks based on the values you've entered if there is any spots available based on the requirements you got.

We have a few values:

Spot type
Disabled spot
Arrive date
Leave date

When you've entered everything untill "arrive date" it should get all the data you've entered automatically do a fetch and return it to the body so we can set it correctly for "leave date" so it only shown untill when there are spots availiable.

29 Replies

Collared PloverOP
My code right now:
Also the spot type and spot facilities are pulled from an API
Which makes it even more difficult
@Collared Plover Click to see attachment
// action.ts
'use server'

export async function login(formData) {
    const test = formData.get('test')
    const spotFacility = formData.get('spotFacility')
    const residenceType= formData.get('residenceType')

    return 
}


import Form from './form'

async function getResidenceType() {}
async function getSpotFacilities() {}

export default async function Booking() {
    const residenceTypes = await getResidenceType();
    const spotFacilities = await getSpotFacilities();

    return <Form residenceTypes={residenceTypes} spotFacilities={spotFacilities} />
}

// form.ts
'use client'

import {login} from './action'

export default function Form({spotFacilities,residenceTypes}) {
    return(
        <form action={login} className="relative z-10">
            <div className="absolute top-0 left-0 w-full h-40 bg-primary-600 -z-10">
                <div className="p-5 w-4/5 flex items-center justify-start">
                    <LogoIcon white={true} size={1}/>
                    <h1 className="text-white text-2xl">Campinger.</h1>
                </div>
            </div>
            
            <div className="pt-20 wrapper grid grid-cols-3 gap-4">
                <div className="lg:col-span-2 col-span-3 bg-white rounded-md p-5">
                    <span className="font-medium text-secondary-700">Configureer boeking</span>
                    {residenceTypes.map((type) => (
                        <div key={type.id}>
                            <label htmlFor={type.name}>{type.name}</label>
                            <input
                                type="radio"
                                name="residenceType"
                                value={type.id}
                                id={type.name}
                            />
                        </div>
                    ))}
                    {spotFacilities.map((facility) => (
                        <div key={facility.id}>
                            <label htmlFor={facility.name}>{facility.name}</label>
                            <input
                                type="radio"
                                name="spotFacility"
                                value={facility.id}
                                id={facility.name}
                            />
                        </div>
                    ))}
                    <DatePicker />
                    <Button buttonType='submit' className={'w-full flex justify-center mt-2'}>Submit</Button>
                </div>
                <div className="lg:col-span-1 col-span-3 bg-white rounded-md p-5">
                    <span className="font-medium text-secondary-700">Overzicht
                    </span>
                </div>
            </div>
        </form>
    )
}
1. you should query the data directly in the server component instead of fetching self api
2. use server action instead of route handler
what do you mean Spot type and Disabled spot? I don't see it in the code?
Collared PloverOP
this is the end result
But it's in Dutch, so I think it's confusing for people
is it a select input?
@Ray is it a select input?
Collared PloverOP
Which one?
Spot type and Disabled spot
Collared PloverOP
Spot type is an radio option
And disabled is part of spotFacilities which will be a checkbox
oh ok
Collared PloverOP
It's very complicated, but what've made is already very useful
@Collared Plover It's very complicated, but what've made is already very useful
// action.ts
'use server'

export async function login(formData) {
    const test = formData.get('test')
    const spotFacility = formData.get('spotFacility')
    const residenceType= formData.get('residenceType')

    return 
}

export async function getArriveDate(residenceTypeId) {}
export async function getLeaveDate(spotFacilityId) {}


import Form from './form'

async function getResidenceType() {}
async function getSpotFacilities() {}

export default async function Booking() {
    const residenceTypes = await getResidenceType();
    const spotFacilities = await getSpotFacilities();

    return <Form residenceTypes={residenceTypes} spotFacilities={spotFacilities} />
}

// form.ts
'use client'

import {login} from './action'

export default function Form({spotFacilities,residenceTypes}) {
    const [arriveDate, setArriveDate] = useState()
    const [leaveDate, setLeaveDate] = useState()
    return(
        <form action={login} className="relative z-10">
            <div className="absolute top-0 left-0 w-full h-40 bg-primary-600 -z-10">
                <div className="p-5 w-4/5 flex items-center justify-start">
                    <LogoIcon white={true} size={1}/>
                    <h1 className="text-white text-2xl">Campinger.</h1>
                </div>
            </div>
            
            <div className="pt-20 wrapper grid grid-cols-3 gap-4">
                <div className="lg:col-span-2 col-span-3 bg-white rounded-md p-5">
                    <span className="font-medium text-secondary-700">Configureer boeking</span>
                    {residenceTypes.map((type) => (
                        <div key={type.id}>
                            <label htmlFor={type.name}>{type.name}</label>
                            <input
                                type="radio"
                                name="residenceType"
                                value={type.id}
                                id={type.name}
                                onChange={async e => {
                                   const arriveDate = await getArriveDate(e.target.value)
                                   setArriveDate(arriveDate)
                                }}
                            />
                        </div>
                    ))}
                    {spotFacilities.map((facility) => (
                        <div key={facility.id}>
                            <label htmlFor={facility.name}>{facility.name}</label>
                            <input
                                type="radio"
                                name="spotFacility"
                                value={facility.id}
                                id={facility.name}
                                onChange={async e => {
                                    const leaveDate = await getLeaveDate(e.target.value)
                                    setLeaveDate(arriveDate)
                                 }}
                            />
                        </div>
                    ))}
                    <DatePicker />
                    <Button buttonType='submit' className={'w-full flex justify-center mt-2'}>Submit</Button>
                </div>
                <div className="lg:col-span-1 col-span-3 bg-white rounded-md p-5">
                    <span className="font-medium text-secondary-700">Overzicht
                    </span>
                </div>
            </div>
        </form>
    )
}
Collared PloverOP
is this page.ts?
import Form from './form'

async function getResidenceType() {}
async function getSpotFacilities() {}

export default async function Booking() {
    const residenceTypes = await getResidenceType();
    const spotFacilities = await getSpotFacilities();

    return <Form residenceTypes={residenceTypes} spotFacilities={spotFacilities} />
}
you could use server action in the form component and set the result to state
yep
Collared PloverOP
alright
and in page.js I handel the form submission
or is that in action.ts?
ohw it's in action.ts
alright
I will do my best
I appriciate your help a lot
yea server action are defined in action.ts
with 'use server' on top of the file