0

I have build a Form that users can fill out and send via a send-button (see code below, button at the very end). It works perfectly fine but when a user clicks send, the input that this user sends just dissapeared (so the user could think sending didnt work, altough it did).

My very simple solution for that was to add an href="/xxx" to the button. That href works but if its in the button, the form is not sent when the user clicks send.

Does anyone know how I can have these two functions (sending the form and href) in one button or another way to solve that?

import React, { Component } from 'react'
import * as emailjs from 'emailjs-com'
import { Form } from 'reactstrap'
import { withStyles } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
import { FormGroup } from '@material-ui/core';
import TextField from "@material-ui/core/TextField";
import FormHelperText from "@material-ui/core/FormHelperText";
import {indigo} from "@material-ui/core/colors";

const ColorButton = withStyles((theme) => ({
    root: {
        color: "#fff",
        backgroundColor: "#434A7E",
        '&:hover': {
            backgroundColor: indigo[200],
        },
        fontWeight: "bold",
        fontFamily: '"Segoe UI Emoji"',
    },
}))(Button);

const styles = {
    root: {
        '& .MuiTextField-root': {
            margin: "10px",
            width: '100ch',
        },
    },
    container: {
        display: 'flex',
        flexWrap: 'wrap',
    },
    textField: {
        marginLeft: "5%",
        marginRight: "5%",
        marginTop: "10px",
        marginBottom: "10px",
        width: "90%",
    },
    messageField: {
        marginLeft: "5%",
        marginRight: "5%",
        marginTop: "10px",
        marginBottom: "10px",
        width: "90%",
    },
    heroButtons: {
        marginLeft: "25%",
        marginRight: "25%",
        marginTop: "10px",
        marginBottom: "10px",
        width: "50%",

    },
};



class Buchungsformular extends Component {
    state = {
        email: '',
        subject: '',
        message: '',
        anfahrt: '',
        abfahrt: '',
        kinder: '',
        erwachsene: '',
        vorname: '',
        nachname: '',
    }
    handleSubmit(e) {
        e.preventDefault()
        const { email, subject, message, anfahrt, abfahrt, kinder, erwachsene, vorname, nachname } = this.state
        let templateParams = {
            email: email,
            to_name: 'Altes Waschhaus',
            subject: subject,
            message_html: message,
            anfahrt: anfahrt,
            abfahrt: abfahrt,
            kinder: kinder,
            erwachsene: erwachsene,
            vorname: vorname,
            nachname: nachname,

        }
        emailjs.send(
            'gmail',
            'template_4CvV5FV9',
            templateParams,
            'user_wAhmfmSiEivROjdwXA3Ls'
        )
        this.resetForm()
    }
    resetForm() {
        this.setState({
            email: '',
            message: '',
            anfahrt: '',
            abfahrt: '',
            kinder: '',
            erwachsene: '',
            vorname: '',
            nachname: '',
        })
    }
    handleChange = (param, e) => {
        this.setState({ [param]: e.target.value })
    }
    render() {
        const { classes } = this.props; //<----- grab classes here in the props

        return (
            <div>
                <Form onSubmit={this.handleSubmit.bind(this)}>
                    <div>
                        <FormGroup controlId="formBasicName">
                            <TextField
                                required
                                id="outlined-required"
                                label="Vorname"
                                defaultValue=" "
                                variant="outlined"
                                name="vorname"
                                className={classes.textField}
                                value={this.state.vorname}
                                onChange={this.handleChange.bind(this, 'vorname')}
                            />
                        </FormGroup>
                        <FormGroup controlId="formBasicName">
                            <TextField
                                required
                                id="outlined-required"
                                label="Nachname"
                                defaultValue=" "
                                variant="outlined"
                                name="nachname"
                                className={classes.textField}
                                value={this.state.nachname}
                                onChange={this.handleChange.bind(this, 'nachname')}
                            />
                        </FormGroup>
                    </div>
                    <FormGroup controlId="formBasicEmail">
                        <TextField
                            required
                            id="outlined-required"
                            label="E-Mail"
                            defaultValue=" "
                            variant="outlined"
                            name="email"
                            className={classes.textField}
                            value={this.state.email}
                            onChange={this.handleChange.bind(this, 'email')}
                        />
                    </FormGroup>
                    <div>
                        <FormGroup controlId="formBasicErwachsene">
                            <TextField
                                required
                                id="outlined-number"
                                label="Erwachsene"
                                type="number"
                                InputLabelProps={{
                                    shrink: true,
                                }}
                                className={classes.textField}
                                variant="outlined"
                                value={this.state.erwachsene}
                                onChange={this.handleChange.bind(this, 'erwachsene')}

                            />
                        </FormGroup>
                        <FormGroup controlId="formBasicKinder">
                            <TextField
                                id="outlined-number"
                                label="Kinder (0-14 Jahre)"
                                type="number"
                                InputLabelProps={{
                                    shrink: true,
                                }}
                                className={classes.textField}
                                variant="outlined"
                                value={this.state.kinder}
                                onChange={this.handleChange.bind(this, 'kinder')}

                            />
                        </FormGroup>
                        <FormGroup controlId="formBasicEmail">
                            <TextField
                                required
                                id="date"
                                label="Anreise"
                                type="date"
                                defaultValue="2020-06-01"
                                className={classes.textField}
                                InputLabelProps={{
                                    shrink: true,
                                }}
                                variant="outlined"
                                value={this.state.anfahrt}
                                onChange={this.handleChange.bind(this, 'anfahrt')}
                            />
                        </FormGroup>
                        <FormGroup controlId="formBasicEmail">
                            <TextField
                                required
                                id="date"
                                label="Abfahrt"
                                type="date"
                                defaultValue="2020-06-01"
                                className={classes.textField}
                                InputLabelProps={{
                                    shrink: true,
                                }}
                                variant="outlined"
                                value={this.state.abfahrt}
                                onChange={this.handleChange.bind(this, 'abfahrt')}
                            />
                        </FormGroup>
                        <FormGroup className={classes.textField} controlId="formBasicMessage">
                            <TextField
                                id="outlined-multiline-static"
                                label="Ihre Nachricht"
                                multiline
                                rows={10}
                                defaultValue=" "
                                variant="outlined"
                                name="message"
                                value={this.state.message}
                                onChange={this.handleChange.bind(this, 'message')}
                            />
                            <FormHelperText>Bitte geben sie hier an ob sie sich für die Ferienwohnung "Vilm" und/oder "Altes Waschhaus" interessieren.</FormHelperText>

                        </FormGroup>

                    </div>
                    <ColorButton  className={classes.heroButtons} type="submit" value="Send" variant="contained" color="primary" size="large" >
                        Send
                    </ColorButton>

                </Form>
            </div>
        )
    }
}
export default withStyles(styles)(Buchungsformular)

4
  • this.resetForm() calling after send (handleSubmit) which is clearing the form. Commented Mar 18, 2021 at 16:54
  • add a flag property to your state gesendet and set it to true inside handleSubmit. Then whenever gesendet is true you render a "Danke" text inside your form. ;-) Commented Mar 18, 2021 at 16:55
  • @kruschid that sounds like a good solution! unfortunately I dont exactly know how I can add a flag property. Could you tell me how I could do that? Danke! :-) Commented Mar 18, 2021 at 17:21
  • I created an answer with an example for you. Commented Mar 18, 2021 at 17:54

1 Answer 1

1

You could add one property to your state and then conditionally render a "thank you" message depending on the state of that property. By default the message wouldn't be rendered since the property value is set to false initially. Then you would update the value of that property inside handleSubmit and set it to true.

I partially updated your code to give you an example:

class Buchungsformular extends Component {
    state = {
        // ... your state props: email, subject, etc.
        sent: false, // this is the new property
    }
    handleSubmit(e) {
        // ... your code, send email, reset form, etc.
        this.setState({ sent: true });
    }
    // your other methods ...

    render() {
        // ...
        return (
            <div>
                {this.state.send && <p>
                    Vielen Dank f&uuml;r Ihre Anfrage...
                </p>}
                <Form onSubmit={this.handleSubmit.bind(this)}>
                    {* ... no changes here ... *}
                </Form>
            </div>
        )
    }
}

However in case emailjs.send(...) fails you would also need to display an error message. I don't exactly know the api of that emailjs object but assuming it uses promises you would need something similar to this inside your handleSubmit method:

emailjs.send(...)
.then(() => this.setState({ sent: true }))
.catch(() => this.setState({ error: true}))

As you see there is another property error that you would need to create in order to show a error feedback (similar to the thank you message) so that the user gets informed and can try again.

Sign up to request clarification or add additional context in comments.

2 Comments

Hi thanks, for the answer! I just tried it out but unfortunately I get the following error: TypeError: Cannot destructure property 'email' of 'this.setState(...)' as it is undefined. The error is shown for the handleSubmit(e) function
sounds like you are trying to do sth like this: const { email, ... } = this.setState(...) and instead it must be const { email, ... } = this.state. But that's not related to the code in my answer as I don't utilize any destructuring in my example.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.