admin管理员组文章数量:1327843
I'm trying to add a react-bootstrap alert to my Formik form so that the handleSubmit includes an alert to the user that the form has submitted.
I have used the react-bootstrap documented form of Alert, however I had to change the last line because that seems not to work (the error says that I haven't exported anything if I use the react-bootstrap documented form of alert.
My alert is:
import React from 'react';
import {
Alert,
Button,
} from "react-bootstrap";
class AlertDismissible extends React.Component {
constructor(props) {
super(props);
this.state = { show: true };
}
render() {
const handleHide = () => this.setState({ show: false });
const handleShow = () => this.setState({ show: true });
return (
<>
<Alert show={this.state.show} variant="light">
<Alert.Heading>Thanks for your interest </Alert.Heading>
<p>
We'll be in touch with login details shortly.
</p>
<hr />
<div className="d-flex justify-content-end">
<Button onClick={handleHide} variant="outline-success">
Close
</Button>
</div>
</Alert>
{!this.state.show && <Button onClick={handleShow}>Show Alert</Button>}
</>
);
}
}
export default AlertDismissible;
The documentation shows a final line as:
render(<AlertDismissible />);
If I try to use that, an error message saying that render is not defined, and that nothing has been exported appears. So - I replaced that line with my final line.
Then, in my form I have:
handleSubmit = (formState, { resetForm }) => {
// Now, you're getting form state here!
const payload = {
...formState,
role: formState.role.value,
createdAt: firebase.firestore.FieldValue.serverTimestamp()
}
console.log("formvalues", payload);
fsDB
.collection("register")
.add(payload)
.then(docRef => {
resetForm(initialValues);
})
.then => {<AlertDismissible />}
.catch(error => {
console.error("Error adding document: ", error);
});
}
I don't actually know how to get the alert to work (the then statement above is a guess - I can't find any examples. This guess gives an error that says:
Parsing error: Unexpected token, expected ";"
I've tried adding ";" in every place I can think to put one, but it keeps generating errors.
If I try it like this:
.then(<AlertDismissible />)
I get no errors and the form submits, but the alert is not displayed.
Does anyone know how to call a react-bootstrap alert in the handle submit function?
Submit button has:
<Button
variant="outline-primary"
type="submit"
style={style3}
id="submitRegistration"
onClick={handleSubmit}
disabled={!dirty || isSubmitting}>
Register
</Button>
The onSubmit has:
onSubmit={
this.handleSubmit
}
My entire form looks like this:
import React from 'react';
import { Link } from "react-router-dom";
import { Formik, Form, Field, ErrorMessage, withFormik } from "formik";
import * as Yup from "yup";
import Select from "react-select";
import { fsDB, firebase, settings } from "../../firebase";
import Temporarynav from '../navigation/Temporarynav.jsx';
import Demo from '../landing/Demo.jsx';
import Footer from '../footer/Footer.jsx';
import "./preregister/Form.css";
import AlertDismissible from '../auth/preregister/Alert';
import {
Badge,
Button,
Col,
ComponentClass,
Feedback,
FormControl,
FormGroup,
Table,
Row,
Container
} from "react-bootstrap";
import Alert from 'react-bootstrap/Alert';
const style1 = {
width: "60%",
margin: "auto"
};
const style2 = {
paddingTop: "2em"
};
const style3 = {
marginRight: "2em"
};
const initialValues = {
firstName: "",
lastName: "",
email: "",
role: "",
consent: false,
createdAt: ''
}
class PreregForm extends React.Component {
// constructor(props) {
// super(props);
// // the flag isFormDone will control where you will show the Alert ponent
// this.state = {
// isFormDone: false
// };
// }
handleSubmit = (formState, { resetForm }) => {
// Now, you're getting form state here!
const payload = {
...formState,
role: formState.role.value,
createdAt: firebase.firestore.FieldValue.serverTimestamp()
}
console.log("formvalues", payload);
fsDB
.collection("preregistrations")
.add(payload)
.then(docRef => {
resetForm(initialValues);
})
.then(() => {
// Here is where you flag your form pletion and allow the alert to be shown.
// this.setState((prevState) => {...prevState, isFormDone: true});
.catch(error => {
console.error("Error adding document: ", error);
});
}
render() {
const options = [
{ value: "academic", label: "Academic Researcher" },
{ value: "student", label: "Student (inc PhD)" },
]
// const {isFormDone} = this.state;
return(
<Formik
initialValues={initialValues}
validationSchema={Yup.object().shape({
firstName: Yup.string().required("First Name is required"),
lastName: Yup.string().required("Last Name is required"),
email: Yup.string()
.email("Email is invalid")
.required("Email is required"),
role: Yup.string().nullable().required(
"It will help us get started if we know a little about your background"
),
consent: Yup.boolean().oneOf(
[true],
"You must accept the Terms of Use and Privacy Policy"
)
})}
onSubmit={
this.handleSubmit
}
render={({
errors,
status,
touched,
setFieldValue,
setFieldTouched,
handleSubmit,
isSubmitting,
dirty,
values
}) => {
return (
<div>
<Temporarynav />
<Form style={style1}>
<h1 style={style2}>Get Started</h1>
<p>
We're almost ready to open this up to the research munity. By
registering now, you'll be first in line when the doors open.
</p>
<div className="form-group">
<label htmlFor="firstName">First Name</label>
<Field
name="firstName"
type="text"
className={
"form-control" +
(errors.firstName && touched.firstName ? " is-invalid" : "")
}
/>
<ErrorMessage
name="firstName"
ponent="div"
className="invalid-feedback"
/>
</div>
<div className="form-group">
<label htmlFor="lastName">Last Name</label>
<Field
name="lastName"
type="text"
className={
"form-control" +
(errors.lastName && touched.lastName ? " is-invalid" : "")
}
/>
<ErrorMessage
name="lastName"
ponent="div"
className="invalid-feedback"
/>
</div>
<div className="form-group">
<label htmlFor="email">Email</label>
<Field
name="email"
type="text"
placeholder="Please use your work email address"
className={
"form-control" +
(errors.email && touched.email ? " is-invalid" : "")
}
/>
<ErrorMessage
name="email"
ponent="div"
className="invalid-feedback"
/>
</div>
<div className="form-group">
<label htmlFor="role">
Which role best describes yours?
</label>
<Select
key={`my_unique_select_keyrole`}
name="role"
className={
"react-select-container" +
(errors.role && touched.role ? " is-invalid" : "")
}
classNamePrefix="react-select"
value={values.role}
onChange={selectedOptions => {
// Setting field value - name of the field and values chosen.
setFieldValue("role", selectedOptions)}
}
onBlur={setFieldTouched}
options={options}
/>
{errors.role && touched.role &&
<ErrorMessage
name="role"
ponent="div"
className="invalid-feedback d-block"
/>}
</div>
<div className="form-group">
<div className="checkbox-wrapper">
<Field
name="consent"
type="checkbox"
checked={values.consent}
className={
"checkbox" +
(errors.consent && touched.consent ? " is-invalid" : "")
}
/>
<label htmlFor="consent" className="checkbox_label_wrapper">
You must accept the{" "}
<Link className="links" to={"/Terms"}>
Terms of Use
</Link>{" "}
and{" "}
<Link className="links" to={"/Privacy"}>
Privacy Policy
</Link>
</label>
</div>
{errors.consent && touched.consent &&
<ErrorMessage
name="consent"
ponent="div"
className="invalid-feedback d-block"
/>
}
</div>
<div className="form-group">
<Button
variant="outline-primary"
type="submit"
style={style3}
id="submitRegistration"
onClick={handleSubmit}
disabled={!dirty || isSubmitting}
>
Register
</Button>
</div>
</Form>
<Demo />
<Footer />
</div>
);
}
}
/>
)
}
}
export default PreregForm;
Next attempt
When I try Julius solution, the alert appears, but as a footer beneath the form - not as a popup alert.
I'm trying to add a react-bootstrap alert to my Formik form so that the handleSubmit includes an alert to the user that the form has submitted.
I have used the react-bootstrap documented form of Alert, however I had to change the last line because that seems not to work (the error says that I haven't exported anything if I use the react-bootstrap documented form of alert.
My alert is:
import React from 'react';
import {
Alert,
Button,
} from "react-bootstrap";
class AlertDismissible extends React.Component {
constructor(props) {
super(props);
this.state = { show: true };
}
render() {
const handleHide = () => this.setState({ show: false });
const handleShow = () => this.setState({ show: true });
return (
<>
<Alert show={this.state.show} variant="light">
<Alert.Heading>Thanks for your interest </Alert.Heading>
<p>
We'll be in touch with login details shortly.
</p>
<hr />
<div className="d-flex justify-content-end">
<Button onClick={handleHide} variant="outline-success">
Close
</Button>
</div>
</Alert>
{!this.state.show && <Button onClick={handleShow}>Show Alert</Button>}
</>
);
}
}
export default AlertDismissible;
The documentation shows a final line as:
render(<AlertDismissible />);
If I try to use that, an error message saying that render is not defined, and that nothing has been exported appears. So - I replaced that line with my final line.
Then, in my form I have:
handleSubmit = (formState, { resetForm }) => {
// Now, you're getting form state here!
const payload = {
...formState,
role: formState.role.value,
createdAt: firebase.firestore.FieldValue.serverTimestamp()
}
console.log("formvalues", payload);
fsDB
.collection("register")
.add(payload)
.then(docRef => {
resetForm(initialValues);
})
.then => {<AlertDismissible />}
.catch(error => {
console.error("Error adding document: ", error);
});
}
I don't actually know how to get the alert to work (the then statement above is a guess - I can't find any examples. This guess gives an error that says:
Parsing error: Unexpected token, expected ";"
I've tried adding ";" in every place I can think to put one, but it keeps generating errors.
If I try it like this:
.then(<AlertDismissible />)
I get no errors and the form submits, but the alert is not displayed.
Does anyone know how to call a react-bootstrap alert in the handle submit function?
Submit button has:
<Button
variant="outline-primary"
type="submit"
style={style3}
id="submitRegistration"
onClick={handleSubmit}
disabled={!dirty || isSubmitting}>
Register
</Button>
The onSubmit has:
onSubmit={
this.handleSubmit
}
My entire form looks like this:
import React from 'react';
import { Link } from "react-router-dom";
import { Formik, Form, Field, ErrorMessage, withFormik } from "formik";
import * as Yup from "yup";
import Select from "react-select";
import { fsDB, firebase, settings } from "../../firebase";
import Temporarynav from '../navigation/Temporarynav.jsx';
import Demo from '../landing/Demo.jsx';
import Footer from '../footer/Footer.jsx';
import "./preregister/Form.css";
import AlertDismissible from '../auth/preregister/Alert';
import {
Badge,
Button,
Col,
ComponentClass,
Feedback,
FormControl,
FormGroup,
Table,
Row,
Container
} from "react-bootstrap";
import Alert from 'react-bootstrap/Alert';
const style1 = {
width: "60%",
margin: "auto"
};
const style2 = {
paddingTop: "2em"
};
const style3 = {
marginRight: "2em"
};
const initialValues = {
firstName: "",
lastName: "",
email: "",
role: "",
consent: false,
createdAt: ''
}
class PreregForm extends React.Component {
// constructor(props) {
// super(props);
// // the flag isFormDone will control where you will show the Alert ponent
// this.state = {
// isFormDone: false
// };
// }
handleSubmit = (formState, { resetForm }) => {
// Now, you're getting form state here!
const payload = {
...formState,
role: formState.role.value,
createdAt: firebase.firestore.FieldValue.serverTimestamp()
}
console.log("formvalues", payload);
fsDB
.collection("preregistrations")
.add(payload)
.then(docRef => {
resetForm(initialValues);
})
.then(() => {
// Here is where you flag your form pletion and allow the alert to be shown.
// this.setState((prevState) => {...prevState, isFormDone: true});
.catch(error => {
console.error("Error adding document: ", error);
});
}
render() {
const options = [
{ value: "academic", label: "Academic Researcher" },
{ value: "student", label: "Student (inc PhD)" },
]
// const {isFormDone} = this.state;
return(
<Formik
initialValues={initialValues}
validationSchema={Yup.object().shape({
firstName: Yup.string().required("First Name is required"),
lastName: Yup.string().required("Last Name is required"),
email: Yup.string()
.email("Email is invalid")
.required("Email is required"),
role: Yup.string().nullable().required(
"It will help us get started if we know a little about your background"
),
consent: Yup.boolean().oneOf(
[true],
"You must accept the Terms of Use and Privacy Policy"
)
})}
onSubmit={
this.handleSubmit
}
render={({
errors,
status,
touched,
setFieldValue,
setFieldTouched,
handleSubmit,
isSubmitting,
dirty,
values
}) => {
return (
<div>
<Temporarynav />
<Form style={style1}>
<h1 style={style2}>Get Started</h1>
<p>
We're almost ready to open this up to the research munity. By
registering now, you'll be first in line when the doors open.
</p>
<div className="form-group">
<label htmlFor="firstName">First Name</label>
<Field
name="firstName"
type="text"
className={
"form-control" +
(errors.firstName && touched.firstName ? " is-invalid" : "")
}
/>
<ErrorMessage
name="firstName"
ponent="div"
className="invalid-feedback"
/>
</div>
<div className="form-group">
<label htmlFor="lastName">Last Name</label>
<Field
name="lastName"
type="text"
className={
"form-control" +
(errors.lastName && touched.lastName ? " is-invalid" : "")
}
/>
<ErrorMessage
name="lastName"
ponent="div"
className="invalid-feedback"
/>
</div>
<div className="form-group">
<label htmlFor="email">Email</label>
<Field
name="email"
type="text"
placeholder="Please use your work email address"
className={
"form-control" +
(errors.email && touched.email ? " is-invalid" : "")
}
/>
<ErrorMessage
name="email"
ponent="div"
className="invalid-feedback"
/>
</div>
<div className="form-group">
<label htmlFor="role">
Which role best describes yours?
</label>
<Select
key={`my_unique_select_keyrole`}
name="role"
className={
"react-select-container" +
(errors.role && touched.role ? " is-invalid" : "")
}
classNamePrefix="react-select"
value={values.role}
onChange={selectedOptions => {
// Setting field value - name of the field and values chosen.
setFieldValue("role", selectedOptions)}
}
onBlur={setFieldTouched}
options={options}
/>
{errors.role && touched.role &&
<ErrorMessage
name="role"
ponent="div"
className="invalid-feedback d-block"
/>}
</div>
<div className="form-group">
<div className="checkbox-wrapper">
<Field
name="consent"
type="checkbox"
checked={values.consent}
className={
"checkbox" +
(errors.consent && touched.consent ? " is-invalid" : "")
}
/>
<label htmlFor="consent" className="checkbox_label_wrapper">
You must accept the{" "}
<Link className="links" to={"/Terms"}>
Terms of Use
</Link>{" "}
and{" "}
<Link className="links" to={"/Privacy"}>
Privacy Policy
</Link>
</label>
</div>
{errors.consent && touched.consent &&
<ErrorMessage
name="consent"
ponent="div"
className="invalid-feedback d-block"
/>
}
</div>
<div className="form-group">
<Button
variant="outline-primary"
type="submit"
style={style3}
id="submitRegistration"
onClick={handleSubmit}
disabled={!dirty || isSubmitting}
>
Register
</Button>
</div>
</Form>
<Demo />
<Footer />
</div>
);
}
}
/>
)
}
}
export default PreregForm;
Next attempt
When I try Julius solution, the alert appears, but as a footer beneath the form - not as a popup alert.
Share edited May 30, 2019 at 20:19 Samuel Bolduc 19.2k8 gold badges36 silver badges58 bronze badges asked May 21, 2019 at 2:26 MelMel 2,71531 gold badges135 silver badges312 bronze badges 2- Don't worry everyone. I can't get the alert to work - but I have found a workaround. I can use a modal to give the alert instead. Thanks for trying to help. So weird how things that must be used by so many people don't work for me – Mel Commented May 23, 2019 at 22:31
- I think your question was answered, just that you were using alert which gets displayed where it was inserted instead of popping up. – Junius L Commented May 30, 2019 at 7:32
2 Answers
Reset to default 5 +50Use state and conditional rendering. Instead of returning a ponent set state to a variable, in your render use conditional rendering to check if the value is true.
handleSubmit = (formState, { resetForm }) => {
// Now, you're getting form state here!
const payload = {
...formState,
role: formState.role.value,
createdAt: firebase.firestore.FieldValue.serverTimestamp()
};
console.log('formvalues', payload);
fsDB
.collection('register')
.add(payload)
.then(docRef => {
resetForm(initialValues);
})
.then(e => this.setState({ alert: true }))
.catch(error => {
console.error('Error adding document: ', error);
});
};
In your render
render() {
...
return(
....
{this.state.alert && <AlertDismissible />}
...
)
}
Example Demo
Complete form
import React from 'react';
import { Link } from 'react-router-dom';
import { Formik, Form, Field, ErrorMessage, withFormik } from 'formik';
import * as Yup from 'yup';
import Select from 'react-select';
import { fsDB, firebase, settings } from '../../firebase';
import Temporarynav from '../navigation/Temporarynav.jsx';
import Demo from '../landing/Demo.jsx';
import Footer from '../footer/Footer.jsx';
import './preregister/Form.css';
import AlertDismissible from '../auth/preregister/Alert';
import {
Badge,
Button,
Col,
ComponentClass,
Feedback,
FormControl,
FormGroup,
Table,
Row,
Container
} from 'react-bootstrap';
import Alert from 'react-bootstrap/Alert';
const style1 = {
width: '60%',
margin: 'auto'
};
const style2 = {
paddingTop: '2em'
};
const style3 = {
marginRight: '2em'
};
const initialValues = {
firstName: '',
lastName: '',
email: '',
role: '',
consent: false,
createdAt: ''
};
class PreregForm extends React.Component {
constructor(props) {
super(props);
// the flag isFormDone will control where you will show the Alert ponent
this.state = {
showAlert: false
};
}
handleSubmit = (formState, { resetForm }) => {
// Now, you're getting form state here!
const payload = {
...formState,
role: formState.role.value,
createdAt: firebase.firestore.FieldValue.serverTimestamp()
};
console.log('formvalues', payload);
fsDB
.collection('preregistrations')
.add(payload)
.then(docRef => {
resetForm(initialValues);
})
.then(e => this.setState({ showAlert: true }))
.catch(error => {
console.error('Error adding document: ', error);
});
};
render() {
const options = [
{ value: 'academic', label: 'Academic Researcher' },
{ value: 'student', label: 'Student (inc PhD)' }
];
// const {isFormDone} = this.state;
return (
<div>
{!this.state.showAlert ? (
<div>
<Formik
initialValues={initialValues}
validationSchema={Yup.object().shape({
firstName: Yup.string().required('First Name is required'),
lastName: Yup.string().required('Last Name is required'),
email: Yup.string()
.email('Email is invalid')
.required('Email is required'),
role: Yup.string()
.nullable()
.required(
'It will help us get started if we know a little about your background'
),
consent: Yup.boolean().oneOf(
[true],
'You must accept the Terms of Use and Privacy Policy'
)
})}
onSubmit={this.handleSubmit}
render={({
errors,
status,
touched,
setFieldValue,
setFieldTouched,
handleSubmit,
isSubmitting,
dirty,
values
}) => {
return (
<div>
<Temporarynav />
<Form style={style1}>
<h1 style={style2}>Get Started</h1>
<p>
We're almost ready to open this up to the research
munity. By registering now, you'll be first in line
when the doors open.
</p>
<div className="form-group">
<label htmlFor="firstName">First Name</label>
<Field
name="firstName"
type="text"
className={
'form-control' +
(errors.firstName && touched.firstName
? ' is-invalid'
: '')
}
/>
<ErrorMessage
name="firstName"
ponent="div"
className="invalid-feedback"
/>
</div>
<div className="form-group">
<label htmlFor="lastName">Last Name</label>
<Field
name="lastName"
type="text"
className={
'form-control' +
(errors.lastName && touched.lastName
? ' is-invalid'
: '')
}
/>
<ErrorMessage
name="lastName"
ponent="div"
className="invalid-feedback"
/>
</div>
<div className="form-group">
<label htmlFor="email">Email</label>
<Field
name="email"
type="text"
placeholder="Please use your work email address"
className={
'form-control' +
(errors.email && touched.email ? ' is-invalid' : '')
}
/>
<ErrorMessage
name="email"
ponent="div"
className="invalid-feedback"
/>
</div>
<div className="form-group">
<label htmlFor="role">
Which role best describes yours?
</label>
<Select
key={`my_unique_select_keyrole`}
name="role"
className={
'react-select-container' +
(errors.role && touched.role ? ' is-invalid' : '')
}
classNamePrefix="react-select"
value={values.role}
onChange={selectedOptions => {
// Setting field value - name of the field and values chosen.
setFieldValue('role', selectedOptions);
}}
onBlur={setFieldTouched}
options={options}
/>
{errors.role && touched.role && (
<ErrorMessage
name="role"
ponent="div"
className="invalid-feedback d-block"
/>
)}
</div>
<div className="form-group">
<div className="checkbox-wrapper">
<Field
name="consent"
type="checkbox"
checked={values.consent}
className={
'checkbox' +
(errors.consent && touched.consent
? ' is-invalid'
: '')
}
/>
<label
htmlFor="consent"
className="checkbox_label_wrapper"
>
You must accept the{' '}
<Link className="links" to={'/Terms'}>
Terms of Use
</Link>{' '}
and{' '}
<Link className="links" to={'/Privacy'}>
Privacy Policy
</Link>
</label>
</div>
{errors.consent && touched.consent && (
<ErrorMessage
name="consent"
ponent="div"
className="invalid-feedback d-block"
/>
)}
</div>
<div className="form-group">
<Button
variant="outline-primary"
type="submit"
style={style3}
id="submitRegistration"
onClick={handleSubmit}
disabled={!dirty || isSubmitting}
>
Register
</Button>
</div>
</Form>
<Demo />
<Footer />
</div>
);
}}
/>
</div>
) : (
<AlertDismissible />
)}
</div>
);
}
}
export default PreregForm;
You can't return a ponent like that within the then
function.
You should manage a state flag that shows the alert based on the form pletion.
Maybe you could share your whole ponent where you are handling the submit
shown here so we can give you more help (will update the answer if you update the question).
But I think it would be something along the following lines:
class MyFormComponent extends React.Component {
constructor(props) {
super(props);
// the flag isFormDone will control where you will show the Alert ponent
this.state = {
isFormDone: false
};
}
/** Here your form handling as you posted */
handleSubmit = (formState, { resetForm }) => {
const payload = {
...formState,
role: formState.role.value,
createdAt: firebase.firestore.FieldValue.serverTimestamp()
}
console.log("formvalues", payload);
fsDB
.collection("register")
.add(payload)
.then(docRef => {
resetForm(initialValues);
})
.then(() => {
// Here is where you flag your form pletion and allow the alert to be shown.
this.setState((prevState) => ({...prevState, isFormDone: true}));
})
.catch(error => {
console.error("Error adding document: ", error);
});
}
render() {
const {isFormDone} = this.state;
// this will only render the Alert when you plete your form submission
const alert = isFormDone ? <AlertDismissible/> : null;
return(
{/* syntax sugar for React Fragment */}
<>
{/* if it is null, it won't render anything */}
{alert}
{/* Your Form here with your handler */}
{/* ... */}
</>
);
}
}
本文标签: javascriptAdd a reactbootstrap alert to handleSubmit in FormikStack Overflow
版权声明:本文标题:javascript - Add a react-bootstrap alert to handleSubmit in Formik - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742220637a2435390.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论