Dynamic Forms in Netlify

274 views Asked by At

I have two components in React that in a sense are both forms. One component is a parent form of some sorts that contains a map function that iterates over a children state item to produce a number of children sub forms. This means that people using the forms can click a button to add a new instance of a ChildSubForm component beneath the button in the parent form.

My current issue is that I cannot get the form to pick up the children in Netlify forms. I have data-netlify="true" and the hidden input so the parent form is recognised, however when I submit the form, only the inputs in the parent form are picked up, how can I change my settings or code to allow netlify to detect the dynamic components' values so that they are sent alongside the other data?

As you can see, I also attempted to store all form data in state items and submit them, but I cannot see the values still. Is it something to do with Netlify building the static site and detecting all form values beforehand?

BookNow.js (The parent form)

import React, { Component } from 'react'

import ChildSubForm from './ChildSubForm'

export default class BookNow extends Component {
    state = {
        name: "",
        email: "",
        otherInfo: "",
        children: []
    }

    constructor(props) {
        super(props)
        this.addChild = this.addChild.bind(this);
        this.decrementChild = this.decrementChild.bind(this);
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    addChild() {
        this.setState({
            children: [...this.state.children, { name: "", year: "Year 7" }]
        })
    }

    decrementChild(i) {
        this.setState({
            children: this.state.children.filter((item, j) => i !== j)
        })
    }

    handleChange(e) {
        if (["name", "year"].includes(e.target.className)) {
            let children = [...this.state.children]
            children[e.target.dataset.id][e.target.className] = e.target.value
            this.setState({ children }, () => console.log(this.state.children))
        } else {
            this.setState({ [e.target.name]: e.target.value })
        }
    }

    handleSubmit(e) {
        e.preventDefault()
    }


    render() {
        if(this.props.isChild) {
            return (
                <form name="Booking Form" method="POST" data-netlify="true">
                    <input type="hidden" name="form-name" value="Booking Form" />
                    <input type="text" name="name" placeholder="Your Name" />
                    <select name="year-group">
                        <option value="Year 7">Year 7</option>
                        <option value="Year 8">Year 8</option>
                        <option value="Year 9">Year 9</option>
                        <option value="Year 10">Year 10</option>
                        <option value="Year 11">Year 11</option>
                        <option value="Year 12">Year 12</option>
                        <option value="Year 13">Year 13</option>
                        <option value="GCSE Retake">GCSE Retake</option>
                    </select><br />
                    <input type="email" name="email" placeholder="Your Email Address" /><br />
                    <textarea name="otherInfo" placeholder="Any more information..." /><br />
                    <button type="submit">Book Now</button>
                </form>
            )
        } else {
            return (
                <form onChange={this.handleChange} onSubmit={this.handleSubmit} name="Booking Form" method="POST" data-netlify="true">
                    <input type="hidden" name="form-name" value="Booking Form" />
                    <input type="text" name="name" placeholder="Your Name" /><br />
                    <input type="email" name="email" placeholder="Your Email Address" /><br />
                    <button onClick={this.addChild} name="add">+ Add Child</button><br />
                    {
                        this.state.children.map((child, i) => <ChildSubForm key={i} childNum={i} value={this.state.children[i]} dec={() => this.decrementChild(i)} />)
                    }
                    <textarea name="otherInfo" placeholder="Any more information..." /><br />
                    <button type="submit">Book Now</button>
                </form>
            )
        }
    }
}

ChildSubForm.js

import React, { Component } from 'react'

export default class ChildSubForm extends Component {
    render() {
        const values = {
            name: `child-name-${this.props.childNum}`,
            year: `child-${this.props.childNum}-year-group`
        }
        return (
            <div className="ChildSubForm">
                <input type="text" id={values.name} name={values.name} data-id={this.props.childNum} value={this.props.value.name} className="name" placeholder="Child's Name" required />
                <select name={values.year} id={values.year} data-id={this.props.childNum} id={values.year} value={this.props.value.year} className="year">
                    <option value="Year 7">Year 7</option>
                    <option value="Year 8">Year 8</option>
                    <option value="Year 9">Year 9</option>
                    <option value="Year 10">Year 10</option>
                    <option value="Year 11">Year 11</option>
                    <option value="Year 12">Year 12</option>
                    <option value="Year 13">Year 13</option>
                    <option value="GCSE Retake">GCSE Retake</option>
                </select>
                <button onClick={this.props.dec} name="remove">- Remove Child</button><br />
            </div>
        )
    }
}

UPDATE:

So I did some reading and found a post looking to do the same thing and the Director of Support for Netlify saying it isn't possible yet unless you predefine all of the form fields beforehand (for each of the mapped components). Has anybody found a workaround for this?

Netlify Post

0

There are 0 answers