why does handleSubmit in react hook useform is not being called - reactjs

I am using useform hook but the handlesubmit function is not being called . here is the code:
This is the useform hook i am using
const {
register,
handleSubmit,
formState: { errors },
watch,
reset, } = useForm<SellingInvoiceClientDetails>({
resolver: yupResolver(SellingInvoiceScheme),
defaultValues: {
rib: "",
cardNumber: "",
cardType: CardType.IDENTITY_CARD,},});
The function i want to call in the hundleSubmit is the following
const addSellingInvoiceClientDetails = (
sellingInvoiceDetails: SellingInvoiceClientDetails
) => {
console.log(sellingInvoiceDetails.cardType);
props.setSelectedClient();
props.updateSellingInvoiceInfo(
sellingInvoiceDetails.cardType,
sellingInvoiceDetails.cardNumber,
sellingInvoiceDetails.rib
);
handleClose(); };
The code of the Form :
return (
<>
<Modal.Header closeButton>
<Modal.Title>
<FormattedMessage id={"client.info"} />
</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form onSubmit={handleSubmit(addSellingInvoiceClientDetails)}>
<Form.Group className="mb-3">
<Form.Label>
<FormattedMessage id={"card.number"} />
</Form.Label>
<Form.Control
{...register("cardNumber")}
placeholder={intl.formatMessage({ id: "card.number" })}
/>
<Form.Text className=" text-danger">
{errors.cardNumber?.message}
</Form.Text>
</Form.Group>
<Form.Group className="mb-3">
<Form.Label>
<FormattedMessage id={"card.type"} />
</Form.Label>
<Form.Check
{...register("cardType")}
type={"radio"}
label={intl.formatMessage({ id: CardType.IDENTITY_CARD })}
value={CardType.IDENTITY_CARD}
id={"identity_card"}
/>
<Form.Check
{...register("cardType")}
type={"radio"}
label={intl.formatMessage({ id: CardType.DRIVING_LICENCE })}
value={CardType.DRIVING_LICENCE}
id={"driving_licence"}
/>
<Form.Text className=" text-danger">
{errors.cardType?.message}
</Form.Text>
</Form.Group>
<Form.Group className="mb-3">
<Form.Label>RIP</Form.Label>
<input
type="text"
className="form-control"
{...register("rib")}
placeholder="XXXXXXXXXXXXX"
/>
<Form.Text className=" text-danger">
{errors.rib?.message}
</Form.Text>
</Form.Group>
</Form>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
<FormattedMessage id={"cancel"} />
</Button>
<Button
type="submit"
variant="primary"
onClick={handleSubmit(addSellingInvoiceClientDetails)}
>
<FormattedMessage id={"ok"} />
</Button>
</Modal.Footer>
</>
);
the function addSellingInvoiceClientDetails is not being excuted and when i click the Ok button nothing happens altough the handleClose function called in cancel button is working just fine.

You have put the Button element out of the form.
Try to move it inside the <form> tag

Related

Reactjs Modal Form Submission with MySql (axios & sequelize)

Good Day,
I have a header outline with both Login and Sign Up Modal. At the moment I am working on the Sign Up Modal where for now I can insert a new User but I want to display another Modal to confirm signup successful as well as close the Sign Up Modal. Also to display error messages via Modal. Here is the outline of my header Code so far. along with the Authentication Controller Class.
AUTHENTICATION CODE
import { Op } from 'sequelize'
import bcryptjs from 'bcryptjs'
import jwt from 'jsonwebtoken'
import UsersModel from "../models/users_model.js"
export const register = (request, response, next) => {
const name = request.body.name
const surname = request.body.surname
const salt = bcryptjs.genSaltSync(10)
const passcode = bcryptjs.hashSync(request.body.passcode, salt)
const username = request.body.username
const email = request.body.email
UsersModel.findOrCreate({
where: { [Op.or]: [ { username }, { email } ] },
defaults: { name, surname, username, email, passcode }
}).then((created) => {
if (!created) return response.status(404).json('User exists')
else return response.status(200).json(created)
}).catch((error) => {
return response.status(500).json(error)
})
}
HEADER CODE
import React, { useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { Button, Modal, CloseButton, Form, Row, Col, FloatingLabel, ModalBody } from 'react-bootstrap'
import 'bootstrap/scss/bootstrap.scss'
import axios from 'axios'
import './Header.scss'
function LoginModal(modal) {
return (
<>
<Modal {...modal} size={'lg'} aria-labelledby={'contained-modal-title-vcenter'} centered>
<Modal.Header closeButton={CloseButton}>
<Modal.Title>Login Panel</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form action='/' method={'POST'}>
<Form.Group className='mb-3' controlId='formBasicEmail'>
<Row className='align-items-center'>
<Col xs={'auto'}>
<FloatingLabel controlId='floatingInput' label='Username' className='mb-3'>
<Form.Control type={'text'} name={'username'} placeholder={'Type Username'} id={'username'} />
</FloatingLabel>
</Col>
<Col xs={'auto'}>
<FloatingLabel controlId='floatingInput' label='Passcode' className='mb-3'>
<Form.Control type={'password'} name={'passcode'} placeholder={'Type Passcode'} id={'passcode'} />
</FloatingLabel>
</Col>
</Row>
</Form.Group>
<Button variant={'primary'} type={'submit'}>Submit</Button>
</Form>
</Modal.Body>
<Modal.Footer>
<Button onClick={modal.onHide}>Close</Button>
</Modal.Footer>
</Modal>
</>
)
}
function RegisterModal(modal) {
const [inputs, dataSet] = useState({
name: '',
surname: '',
username: '',
email: '',
passcode: ''
})
const [ error, setError] = useState(null)
const navigate = useNavigate()
const dataEntry = (event) => {
dataSet((previous) => ({...previous, [event.target.name]: event.target.value }))
}
const dataSubmit = async (event) => {
event.preventDefault()
try {
await axios.post('auth/register/', inputs)
navigate('/')
} catch (error) {
setError(error.response.data)
}
}
return (
<>
<Modal {...modal} size={'lg'} aria-labelledby={'contained-modal-title-vcenter'} centered>
<Modal.Header closeButton={CloseButton}>
<Modal.Title>Sign Up</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form>
<Row className='mb-3'>
<Form.Group as={Col} controlId='formGridName'>
<Form.Label>Name</Form.Label>
<Form.Control type={'text'} name={'name'} placeholder={'Type Name'} id={'name'} onChange={dataEntry} />
</Form.Group>
<Form.Group as={Col} controlId='formGridSurname'>
<Form.Label>Surname</Form.Label>
<Form.Control type={'text'} name={'surname'} placeholder={'Type Surname'} id={'surname'} onChange={dataEntry} />
</Form.Group>
</Row>
<Row className='mb-3'>
<Form.Group as={Col} controlId='formGridEmail'>
<Form.Label>Email</Form.Label>
<Form.Control type={'email'} name={'email'} placeholder={'Type Email'} onChange={dataEntry} />
</Form.Group>
<Form.Group as='mb-3' controlId='formGridUsername'>
<Form.Label>Username</Form.Label>
<Form.Control type={'text'} name={'username'} placeholder={'Enter Userame'} id={'username'} onChange={dataEntry} />
</Form.Group>
<Form.Group as='mb-3' controlId='formGridPasscode'>
<Form.Label>Passcode</Form.Label>
<Form.Control type={'password'} name={'passcode'} placeholder={'Enter Passcode'} id={'passcode'} onChange={dataEntry} />
</Form.Group>
<Form.Group as='mb-3' controlId='formGridConfirm'>
<Form.Label>Passcode</Form.Label>
<Form.Control type={'password'} name={'confirm'} placeholder={'Confirm Passcode'} id={'confirm'} />
</Form.Group>
</Row>
<Form.Group as='mb-3' controlId='formGridSubmit'>
<Button variant={'primary'} type={'submit'} onClick={dataSubmit} >Submit</Button>
</Form.Group>
<Modal>
<ModalBody>{error && {error} }</ModalBody>
</Modal>
</Form>
</Modal.Body>
<Modal.Footer>
<Button onClick={modal.onHide}>Close</Button>
</Modal.Footer>
</Modal>
</>
)
}
export default function Header() {
const [loginModal, setLoginModal] = useState(false)
const [registerModal, setRegisterModal] = useState(false)
return (
<>
<header className='main-header'>
<nav className='nav-content'>
<ul className='nav-content-list'>
<li className='nav-content-item'>
<Button variant='primary' onClick={() => setLoginModal(true)}>Login</Button>
</li>
<li className='nav-content-item'>
<Button variant='primary' onClick={() => setRegisterModal(true)}>Sign Up</Button>
</li>
</ul>
</nav>
</header>
<LoginModal show={loginModal} onHide={() => setLoginModal(false)} />
<RegisterModal show={registerModal} onHide={() => setRegisterModal(false)} />
</>
)
}

Formik : Require validation only if the field is visible

I have a form including a checkbox which if it is true causes a new field to appear.
and I would like that when the field is visible it can be considered as Required and no required if it is invisible.
Here endComment should be required only when show is true
Would you have a solution ?
The global code :
const Form = {
const [show, setShow] = useState<boolean>(props.event.endDate ? true : false);
const addEndComment = (value: boolean) => {
setShow(value);
};
const schema = yup.object().shape({
comment: yup.string().required(),
endComment: yup.string().required(),
});
return (
<>
<Formik
enableReinitialize
initialValues={{
comment: props.event.comment,
endComment: props.event.endComment,
}}
onSubmit={(values) => {
....
}}
validationSchema={schema}
>
{(formikProps) => (
<form onSubmit={formikProps.handleSubmit}>
<section>
<p>
<I18nWrapper
translateKey={'event.form-create-event.explanations'}
/>
</p>
</section>
<section>
<Form.Group controlId="eventComment">
<Form.Label>
<I18nWrapper
translateKey={'event.form-create-event.comment-label'}
/>
</Form.Label>
<Form.Control
value={formikProps.values.comment || ''}
onChange={formikProps.handleChange}
as="textarea"
rows={3}
name="comment"
isInvalid={!!formikProps.errors.comment}
/>
<Form.Control.Feedback
type="invalid"
role="alert"
aria-label="no comment"
>
<FontAwesomeIcon icon={faTimes} className="me-2" size="lg"/>
<I18nWrapper
translateKey={'reminder.modal.phone-reminder.error'}
/>
</Form.Control.Feedback>
</Form.Group>
</section>
<section>
<SimpleGrid columns={columns} rows={rows}/>
</section>
<section>
<Form.Group controlId="formBasicCheckbox">
<Form.Check
type="checkbox"
label={t('event.form-resolve-event.checkbox-label')}
checked={show}
onChange={(e) => addEndComment(e.target.checked)}
/>
</Form.Group>
</section>
{show ? (
<React.Fragment>
<section>
<I18nWrapper
translateKey={'event.form-resolve-event.comment-end-label'}
/>
<Form.Control
value={formikProps.values.endComment || ''}
onChange={formikProps.handleChange}
as="textarea"
rows={3}
name="endComment"
isInvalid={!!formikProps.errors.endComment}
/>
<Form.Control.Feedback
type="invalid"
role="alert"
aria-label="no comment"
>
<FontAwesomeIcon
icon={faTimes}
className="me-2"
size="lg"
/>
<I18nWrapper
translateKey={'reminder.modal.phone-reminder.error'}
/>
</Form.Control.Feedback>
</section>
</React.Fragment>
) : null}
<div className="text-center">
<GenericButton
label={'button'}
type="submit"
disabled={!formikProps.isValid}
/>
</div>
</form>
)}
</Formik>
</>
);
};
export default Form;
You can simply change the schema based on the show state
Example:
const schema = yup.object().shape({
comment: yup.string().required(),
endComment: show ? yup.string().required() : yup.string(),
});
OR
If you have the show state as a part of formik's state you can use formik's conditional validation, for example
const schema = yup.object().shape({
comment: yup.string().required(),
endComment: Yup.string().when('show', {
is: true,
then: Yup.string().required()
}),
});
Refer yup docs for more info

focus of field controls with formik

I have a form using formik, comprising a date field and a text field.
when I add a date in the form the text field is automatically put in error.
I think it comes from the initavalues
initialValues={{
comment: '',
endDate: '',
}}
it checks the value of the comment field which is empty and declares it in error.
if I remove comment from initialvalues I end up with an error :
Property 'comment' does not exist on type '{ endDate: string; }'.
How to make so that the field comment is not in error when I empty it or I validate the form?
const FormTest = (props: {
mvts: Movement[];
tiersRef: string;
masterRef: string;
submitCallback: any;
}) => {
const schema = yup.object().shape({
comment: yup.string().required(),
endDate: yup.string().required(),
});
return (
<>
<Formik
initialValues={{
comment: '',
endDate: '',
}}
onSubmit={(values) => {}}
validationSchema={schema}
>
{(formikProps) => (
<form
onSubmit={formikProps.handleSubmit}
aria-label="form-add-promise"
>
<section>
<p>
<I18nWrapper
translateKey={'event.form-create-promise.explanations'}
/>
</p>
</section>
<section>
<Row>
<Form.Group controlId="datePromise" as={Row}>
<Form.Label column lg={6}>
<I18nWrapper
translateKey={'event.form-create-promise.date-promise'}
/>
</Form.Label>
<Col lg={6}>
<Form.Control
value={formikProps.values.comment}
type="date"
name="endDate"
aria-label="from date"
role="date"
onChange={formikProps.handleChange}
isInvalid={!!formikProps.errors.endDate}
/>
<Form.Control.Feedback
type="invalid"
role="alert"
aria-label="no date promise"
>
<FontAwesomeIcon
icon={faTimes}
className="me-2"
size="lg"
/>
<I18nWrapper
translateKey={'event.form-create-promise.error.date'}
/>
</Form.Control.Feedback>
</Col>
</Form.Group>
</Row>
</section>
<section>
<Form.Group controlId="eventComment">
<Form.Label>
<I18nWrapper
translateKey={'event.form-create-promise.error.comment'}
/>
</Form.Label>
<Form.Control
value={formikProps.values.comment}
onChange={formikProps.handleChange}
as="textarea"
aria-label="from textarea"
rows={3}
name="comment"
role="textbox"
isInvalid={!!formikProps.errors.comment}
/>
<Form.Control.Feedback
type="invalid"
role="alert"
aria-label="no comment"
>
<FontAwesomeIcon icon={faTimes} className="me-2" size="lg" />
<I18nWrapper
translateKey={'reminder.modal.phone-reminder.error'}
/>
</Form.Control.Feedback>
</Form.Group>
</section>
<div className="text-center">
<GenericButton
label={'event.form-create-promise.btn-creation'}
type="submit"
disabled={!formikProps.isValid}
/>
</div>
</form>
)}
</Formik>
</>
);
};
export default FormTest;

React-bootstrap, not closed modal window

I use the standard 'useState' for closing Modal. As long as the form does not transmit information, everything works. But when on pressing the 'submit' button I pass the function for execution, the function is executed, and stops closing the modal window. My button's cod: onClick= {(e) => Auth.handle_login(e, state)}.
My code:
<Modal show={show} **onHide={handleClose}**>
<Modal.Header closeButton>
<Modal.Title> Вход </Modal.Title>
</Modal.Header>
<Modal.Body>
<Form>
<Form.Group controlId='fromBasicEmail'>
<Form.Label> Email </Form.Label>
<Form.Control type='email' placeholder='Введите Email' />
</Form.Group>
<Form.Group controlId="formBasicPassword">
<Form.Label>Пароль</Form.Label>
<Form.Control type='password' placeholder='Введите пароль' />
</Form.Group>
<Form.Group controlId="formBasicCheckbox">
<Form.Check type="checkbox" label="Запомнить меня"/>
</Form.Group>
<Button variant="primary" type="submit" className='mb-5' size="lg" block
/*onClick={(e) => {e.preventDefault(); alert('32')}}*/
//onClick= {(e) => {Auth.handle_login(e, state); setModalStatus(false)}}
**onClick= {(e) => Auth.handle_login(e, state)}**
>Войти</Button>
<Form.Text className='text-muted'>
Ещё нет аккаунта? Зарегистрируйтесь
</Form.Text>
</Form>
</Modal.Body>

Pass form data to modal component React/Boostrap

I have a modal component and form component. I am trying to pass the data using React hooks from the form back to the modal. I am having trouble doing this. Here is what I have so far -
Modal(Parent)
interface ISystem {
systemName: string;
allowNumber: number;
statusCode: string;
createdBy?: string;
createdDate?: string;
}
const ModalForm = (props) => {
const { buttonLabel, className } = props;
const [modal, setModal] = useState(false);
const toggle = () => setModal(!modal);
const addButtonHandler = () => {
toggle();
console.log(FORM DATA SHOULD BE HERE)
};
return (
<div>
<Button color="primary" onClick={toggle}>
{buttonLabel}
</Button>
<Modal
isOpen={modal}
toggle={toggle}
className={className}
centered
size="lg"
>
<ModalHeader toggle={toggle}>{buttonLabel}</ModalHeader>
<ModalBody>
<AddSystem></AddSystem>
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={addButtonHandler}>
Add
</Button>{" "}
<Button color="secondary" onClick={toggle}>
Cancel
</Button>
</ModalFooter>
</Modal>
</div>
);
};
export default ModalForm;
This is my Form component
const AddSystem = (props) => {
const [systemId, setSystemId] = useState("");
const [systemName, setSystemName] = useState("");
const [allowNumber, setAllowNumber] = useState("");
const [statusCode, setStatusCode] = useState("");
const [lastModifiedBy, setLastModifiedBy] = useState("");
const submitHandler = (event) => {
event.preventDefault();
};
return (
<Fragment>
<Form onSubmit={submitHandler} className="mx-auto">
<Form.Group as={Row} controlId="systemId">
<Form.Label column sm="2">
{" "}
ID{" "}
</Form.Label>
<Col sm="10">
<Form.Control
type="text"
name="systemId"
placeholder="Leave blank for new system"
value={systemId}
disabled
onChange={(event) => setSystemId(event.target.value)}
/>
</Col>
</Form.Group>
<Form.Group as={Row} controlId="systemName">
<Form.Label column sm="2">
{" "}
Systen Name{" "}
</Form.Label>
<Col sm="10">
<Form.Control
type="text"
name="systemName"
placeholder=""
value={systemName}
onChange={(event) => setSystemName(event.target.value)}
/>
</Col>
</Form.Group>
<Form.Group as={Row} controlId="allowNumber">
<Form.Label column sm="2">
{" "}
Allow Number{" "}
</Form.Label>
<Col sm="10">
<Form.Control
as="select"
name="allowNumber"
value={allowNumber}
onSelect={(event) => setAllowNumber(event.target.value)}
>
<option>Choose...</option>
{["1", "2", "3", "4", "5"].map((opt) => (
<option>{opt}</option>
))}
</Form.Control>
</Col>
</Form.Group>
<Form.Group as={Row} controlId="statusCode">
<Form.Label column sm="2">
{" "}
Status Code{" "}
</Form.Label>
<Col sm="10">
<Form.Control
as="select"
name="statusCode"
value={statusCode}
onSelect={(event) => setStatusCode(event.target.value)}
>
<option>Choose...</option>
{["Active", "Draft"].map((opt) => (
<option>{opt}</option>
))}
</Form.Control>
</Col>
</Form.Group>
<Form.Group as={Row} controlId="lastModifiedBy">
<Form.Label column sm="2">
{" "}
Last Modified By{" "}
</Form.Label>
<Col sm="10">
<Form.Control
type="text"
name="lastModifiedBy"
placeholder=""
value={lastModifiedBy}
disabled
onChange={(event) => setLastModifiedBy(event.target.value)}
/>
</Col>
</Form.Group>
</Form>
</Fragment>
);
};
export default AddSystem;
I don't want to have the button inside the form. The button needs to stay in the modal footer but somehow receive information from the form...This is so that the modal can become re-usable and have any type of form passed into it perhaps

Resources