Solución:
En su mayor parte, debe validar los formularios a mano. Sin embargo, RSUI incluye un par de herramientas para facilitar un poco las cosas, en particular el apoyo de error en <Form>
y <Form.Input>
Aquí hay un ejemplo de un formulario que armé recientemente. Podría necesitar un poco de refactorización, pero básicamente funciona vinculando cada entrada al estado con un onChange()
y pasar una devolución de llamada a la función de envío que controla la visibilidad de la pantalla de carga y la parte “Éxito. Gracias por enviar” del formulario.
export default class MeetingFormModal extends Component {
constructor(props) {
super(props)
this.state = {
firstName: '',
lastName: '',
email: '',
location: '',
firstNameError: false,
lastNameError: false,
emailError: false,
locationError: false,
formError: false,
errorMessage: 'Please complete all required fields.',
complete: false,
modalOpen: false
}
this.submitMeetingForm = this.submitMeetingForm.bind(this);
this.successCallback = this.successCallback.bind(this);
}
successCallback() {
this.setState({
complete: true
})
setTimeout( () => {this.setState({modalOpen: false})}, 5000);
this.props.hideLoading();
}
handleClose = () => this.setState({ modalOpen: false })
handleOpen = () => this.setState({ modalOpen: true })
submitMeetingForm() {
let error = false;
if (this.state.studentFirstName === '') {
this.setState({firstNameError: true})
error = true
} else {
this.setState({firstNameError: false})
error = false
}
if (this.state.studentLastName === '') {
this.setState({lastNameError: true})
error = true
} else {
this.setState({lastNameError: false})
error = false
}
if (this.state.email === '') {
this.setState({emailError: true})
error = true
} else {
this.setState({emailError: false})
error = false
}
if (this.state.location === '') {
this.setState({locationError: true})
error = true
} else {
this.setState({locationError: false})
error = false
}
if (error) {
this.setState({formError: true})
return
} else {
this.setState({formError: false})
}
let meeting = {
first_name: this.state.firstName,
last_name: this.state.lastName,
email: this.state.email,
location: this.state.location,
this.props.createMeeting(meeting, this.successCallback)
this.props.showLoading();
}
capitalize(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
render() {
return(
<Modal
trigger={<Button onClick={this.handleOpen} basic color="blue">Schedule Now</Button>}
open={this.state.modalOpen}
onClose={this.handleClose}
closeIcon={true}
>
<Modal.Header>Schedule Your Interview</Modal.Header>
<Modal.Content>
{!this.state.complete ?
<Modal.Description>
<Form error={this.state.formError}>
<Form.Group widths="equal">
<Form.Field>
<Form.Input required={true} onChange={(e) => this.setState({firstName: e.target.value})} label="First Name" placeholder="First Name..." error={this.state.firstNameError}/>
</Form.Field>
<Form.Field>
<Form.Input required={true} onChange={(e) => this.setState({lastName: e.target.value})} label="Last Name" placeholder="Last Name..." error={this.state.lastNameError}/>
</Form.Field>
</Form.Group>
<Form.Field >
<Form.Input required={true} onChange={(e) => this.setState({email: e.target.value})} label="Email" placeholder="Email..." error={this.state.emailError}/>
</Form.Field>
<Form.Field>
<Form.Input required={true} onChange={(e) => this.setState({location: e.target.value})} label="Location" placeholder="City, State/Province, Country..." error={this.state.locationError}/>
</Form.Field>
</Form>
</Modal.Description>
:
<div className="modal-complete">
<Image src="https://foroayuda.es/images/check.png" />
<p>Thanks for scheduling a meeting, {this.capitalize(this.state.name)}. We've received your information and we'll be in touch shortly.</p>
</div>
}
</Modal.Content>
{!this.state.complete ?
<Modal.Actions>
<Button color="red" onClick={this.handleClose}>Close</Button>
<Button positive icon='checkmark' labelPosition='right' content="Submit" onClick={this.submitMeetingForm} />
</Modal.Actions>
: null }
</Modal>
)
}
}
¡Espero que ayude!
Incluso tenemos una mejor opción, aunque no proporcionada por semantic-ui-react -> Formik + yup
Formik: ayuda en la gestión del estado del formulario Sí: ayuda en la validación de ese estado
Tengo el siguiente componente que es básicamente un formulario de edición creado usando semantic-ui-react.
import React, { Component } from "react";
import { Button, Form, Modal, Message, Divider } from "semantic-ui-react";
import { Formik } from "formik";
import * as yup from "yup";
class EditAboutGrid extends Component {
render() {
const {
userBasic,
editBasicModal,
closeModal
} = this.props;
return (
<Formik
initialValues={{
firstName: userBasic.firstName,
lastName: userBasic.lastName,
bio: userBasic.bio,
}}
validationSchema={yup.object().shape({
firstName: yup
.string()
.required("Name cannot be empty"),
lastName: yup
.string()
.required("Name cannot be empty"),
bio: yup
.string()
.max(1000, "Maximum characters exceed 1000")
.nullable()
})}
onSubmit={(values, actions) => {
//do your stuff here like api calls
}}
render={({
values,
errors,
handleChange,
handleSubmit,
isSubmitting,
dirty,
setFieldValue
}) => (
<Modal open={editBasicModal} size="small">
<Modal.Header>Your basic details</Modal.Header>
<Modal.Content scrolling>
{errors.firstName && <Message error content={errors.firstName} />}
{errors.lastName && <Message error content={errors.lastName} />}
{errors.bio && <Message error content={errors.bio} />}
<Form loading={isSubmitting}>
<Form.Group inline widths="equal">
<Form.Input
required
label="First Name"
fluid
type="text"
name="firstName"
value={values.firstName}
onChange={handleChange}
error={errors.firstName !== undefined}
/>
<Form.Input
required
label="Last Name"
fluid
type="text"
name="lastName"
value={values.lastName}
onChange={handleChange}
error={errors.lastName !== undefined}
/>
</Form.Group>
<Form.TextArea
label="Bio"
type="text"
name="bio"
value={values.bio}
onChange={handleChange}
rows={3}
error={errors.bio !== undefined}
/>
</Form>
</Modal.Content>
<Modal.Actions open={true}>
<Button
onClick={() => (dirty ? closeModal(true) : closeModal(false))}>
Cancel
</Button>
<Button
primary
type="submit"
onClick={handleSubmit}
loading={isSubmitting}
disabled={isSubmitting || !isEmpty(errors) || !dirty}>
Update
</Button>
</Modal.Actions>
</Modal>
)}
/>
);
}
}
Y este formulario se llama usando:
<EditAboutGrid
editBasicModal={this.state.editBasicModal}
userBasic={this.state.user.basic}
closeModal={this.closeModal}
/>
initialValues
es el lugar donde empiezan las cosas. Aquí pasa los valores iniciales / predeterminados a las entradas de su formulario. values
(en forma) seleccionará el valor de los datos de este valor predeterminado.
validationSchema
es el lugar donde ocurre toda la validación usando yup
onSubmit
se llamará en el envío del formulario.
Manejar formularios usando Formik + yup es muy fácil. Lo estoy amando.