Cant reset form after submit in formik - javascript

I cant reset my form on submit or modal close event using formik. I tried using resetForm({}), resetForm(initialValues),resetForm('') nothing works for me.
RestaurantDetails.js
setting initial values
// setting formik initialValues
const setFromikInitialValue = (product_option_groups) => {
let updatedOption = product_option_groups;
product_option_groups.forEach((option, optionIndex) => {
if (option.minimum === 1 && option.maximum === 1) {
//If displaying radio buttons for modifier
//selected option is kept in a key selected_modifier
updatedOption[optionIndex] = {
...option,
selected_modifier: option.product_options[0].id,
};
} else {
//If displaying check box for modifier
//selected_modifier_count key is added to track checked box count
updatedOption[optionIndex] = {
...option,
selected_modifier_count: 0,
};
}
//For each check box selected key is added
//selected is true if check box is checked & if unchecked it is false
option.product_options.forEach((item, itemIndex) => {
updatedOption[optionIndex].product_options[itemIndex] = {
...item,
selected: false,
};
});
});
return updatedOption;
};
const initialValues = {
product_id: selectedFoodItem.id,
options: setFromikInitialValue(modifiersData),
};
render part of formik
{/* Modal */}
<div
className="modal fade dish-modal"
id={`dishModal-${selectedFoodItem.id}`}
tabIndex={-1}
role="dialog"
aria-labelledby="exampleModalLabel"
aria-hidden="true"
data-backdrop="static"
data-keyboard="false"
>
<div className="modal-dialog" role="document">
<div className="modal-content">
<Formik
initialValues={initialValues}
enableReinitialize
//form submition
onSubmit={async (values, { setSubmitting, resetForm }) => {
console.log(values);
setSubmitting(false);
resetForm(initialValues);
window.$(`#dishModal-${selectedFoodItem.id}`).modal("hide");
}}
//yup form validation
validationSchema={Yup.object().shape({
options: Yup.array().of(
Yup.object().shape({
selected_modifier_count: Yup.number()
.min(
Yup.ref("minimum"),
"minimum number of modifier not choosed"
)
.max(
Yup.ref("maximum"),
"maximum number of modifier exeded"
),
})
),
})}
>
{({
isSubmitting,
setFieldValue,
values,
errors,
touched,
resetForm,
}) => (
<Form>
<div className="modal-body">
<button
type="button"
className="close"
data-dismiss="modal"
aria-label="Close"
onClick={() => {
resetForm({});
}}
>
<span aria-hidden="true">×</span>
</button>
<div className="item-details">
<h4>{selectedFoodItem.name}</h4>
<h4>
{dollar}
{selectedFoodItem.price}
</h4>
</div>
<div className="modifiers">
{/* mapping modifier items */}
{values.options && values.options.length
? values.options.map((modifier, optionIndex) => (
<div
key={`${modifier.id}-${optionIndex}`}
className="modifiers"
>
<h5>{modifier.name}</h5>
<h6>
{modifier.minimum || modifier.maximum ? (
errors.options && touched.options ? (
errors.options[optionIndex] &&
touched.options[optionIndex] ? (
<span className="text-danger">
Minimum {modifier.minimum} Maximum{" "}
{modifier.maximum}
</span>
) : (
<span>
Minimum {modifier.minimum} Maximum{" "}
{modifier.maximum}
</span>
)
) : (
<span>
Minimum {modifier.minimum} Maximum{" "}
{modifier.maximum}
</span>
)
) : (
<span className="text-danger">
Minimum {modifier.minimum} Maximum{" "}
{modifier.maximum}
</span>
)}
{modifier.minimum > 0 ? (
<span className="badge badge-light float-right">
Required
</span>
) : null}
</h6>
<ul>
{modifier.minimum === 1 &&
modifier.maximum === 1
? modifier.product_options.map(
(item, itemIndex) => (
<li key={itemIndex}>
<div className="form-check">
<input
defaultChecked={
itemIndex === 0 ? true : false
}
className="form-check-input"
type="radio"
name="temp"
id={`exampleCheck${item.id}`}
onChange={(
event,
value = item.id
) => {
setFieldValue(
`options[${optionIndex}]`,
{
...modifier,
selected_modifier: value,
}
);
}}
/>
<label
className="form-check-label"
htmlFor={`exampleCheck${item.id}`}
>
{item.name}
<span>
{dollar}
{item.price}
</span>
</label>
</div>
</li>
)
)
: modifier.product_options.map(
(item, itemIndex) => (
<li key={`${item.id}-${itemIndex}`}>
<div className="form-check">
<input
type="checkbox"
className="form-check-input"
id={`exampleCheck${item.id}`}
onClick={() => {
if (!item.selected) {
setFieldValue(
`options[${optionIndex}]`,
{
...modifier,
selected_modifier_count:
modifier.selected_modifier_count
? modifier.selected_modifier_count +
1
: 1,
}
);
} else {
setFieldValue(
`options[${optionIndex}]`,
{
...modifier,
selected_modifier_count:
modifier.selected_modifier_count -
1,
}
);
}
setFieldValue(
`options[${optionIndex}][product_options][${itemIndex}]`,
{
...item,
selected: !item.selected,
}
);
}}
defaultChecked={
item.selected ? true : false
}
/>
<label
className="form-check-label"
htmlFor={`exampleCheck${item.id}`}
>
{item.name}
<span>
{dollar}
{item.price}
</span>
</label>
</div>
</li>
)
)}
</ul>
</div>
))
: null}
</div>
<button
type="submit"
className="btn btn-primary continue-btn"
// disabled={isSubmitting || !dirty}
>
Continue
</button>
</div>
</Form>
)}
</Formik>
</div>
</div>
</div>
{/* Modal end */}

Related

Configurate Custome amount field

How to configurate custom amount field?
When I am trying to submit my own price, I have problem.
When I submit just one digit, I am getting empty value,
if I am submitting two digits or more, it seems last digit of amount is missing.
If I submit button, I am getting value. Buttons are ok.
let v = 0
const [price, setPrice] = useState(0)
const [yourPrice, setYourPrice] = useState('')
const handleSubmit = (e) => {
e.preventDefault()
clickEvent()
console.log(price)
setYourPrice('')
}
function clickEvent (e, v){
if(v === 5 || v === 10 || v === 15) {
setPrice(v)
setYourPrice('')
} else {
return
}
}
const onChangeSuma = e => {
e.preventDefault()
setYourPrice(e.target.value)
setPrice(yourPrice)
}
here is form
<form onSubmit={handleSubmit}>
<div className="d-flex justify-content-between">
<button className={ `${price === 5 ?
'active' : 'noActive' }`}
onClick={e => clickEvent(e, 5)}>
$5
</button>
<button className={ `${price === 10 ?
'active' : 'noActive'}`}
onClick={e => clickEvent(e, 10)}>
$10
</button>
<button className={` ${price === 15 ?
'active' : 'noActive '}`}
onClick={e => clickEvent(e, 15)}>
$15
</button>
</div>
<div className="col text-center pt-1 fs-5 m-1 py-2 ">
<label>Your Price</label>
<input
type="number"
className={yourPrice ? 'active' : 'noActive'}
placeholder='$ Other'
id="inputID"
autoFocus={yourPrice}
value={yourPrice}
onChange={onChangeSuma}
/>
</div>
<button className='btn btn-secondary
border-0 rounded-0 py-2
w-100' type='submit'>SUBMIT</button>
</form>
When you do setState, it doesn't update the state immediately. You will get the updated state in the next re-render.
const onChangeSuma = (e) => {
e.preventDefault()
setYourPrice(e.target.value)
// setPrice(yourPrice)
// The following line changed
setPrice(e.target.value)
}

Edit User Details using React

I am stuck on editing user details and updating it.
What I'm trying to accomplish is when I click on "update" button, I can edit their name and email. And I can also delete the entry by clicking the "delete" button.
I have added the ability to add new User which I am able to code.
This is my code: https://codesandbox.io/s/zen-browser-5ifrel?file=/src/User.js
How do I add a if-else statement in my render so that IF i click on "update" button on one of the entry (e.g., id === selected.id), it will transform the "name" and "email" to textboxes to allow for edit. And 2 buttons for them to "confirm" their update or "cancel" their update.
render() {
return (
<div className="App">
{
this.state.users.map((u) => {
return (
<React.Fragment key={u._id}>
<div className="box">
<h3>{u.name}</h3>
<h4>{u.email}</h4>
<button onClick={() => {
this.beginEdit(u);
}}
>Update
</button>
<button onClick={() => {
this.deleteUser(u);
}}
>Delete
</button>
</div>
</React.Fragment>
);
})}
{this.renderAddUser()}
</div>
);
}
Use conditional rendering.
render() {
return (
<div className="App">
{
this.state.users.map((u) => {
return (
<React.Fragment key={u._id}>
<div className="box">
{u.isEditing ? (
<React.Fragment>
<input type="text" placeholder="name" />
<input type="text" placeholder="email" />
</React.Fragment>
) : (
<React.Fragment>
<h3>{u.name}</h3>
<h4>{u.email}</h4>
</React.Fragment>
)}
<button onClick={() => {
this.beginEdit(u);
}}
>Update
</button>
<button onClick={() => {
this.deleteUser(u);
}}
>Delete
</button>
</div>
</React.Fragment>
);
})}
{this.renderAddUser()}
</div>
);
}
You can probably figure out the rest.
you can use this that render output depends on the condition of (id === selectedUser.id)
state = {
selected = null;
}
render() {
return (
<div className="App">
{this.state.users.map((user) => {
return (
<div className="box" >
{selected?.id === user?._id ? (
<>
<input type="text" placeholder="name" defaultValue={user.name} />
<input type="text" placeholder="email" defaultValue={user.email} />
<button onClick={() => { this.handleCancel(user);}}>
Cancel
</button>
<button onClick={() => { this.handleConfirm(user);}}>
Confirm
</button>
</>
) : (
<>
<h3>{user.name}</h3>
<h4>{user.email}</h4>
<button onClick={() => { this.beginEdit(user);}}>
Update
</button>
<button onClick={() => { this.deleteUser(user);}}>
Delete
</button>
</>
)}
</div>
);
})}
{this.renderAddUser()}
</div>
);
}

Multiple submit buttons on Kendo Form

Is it possible to have multiple submit buttons, each of them calling another function in Kendo?
For example I have a form like this:
<Form
onSubmit={handleSubmit}
render={(formRenderProps) => (
<FormElement
style={{
maxWidth: 650,
}}
>
<fieldset className={"k-form-fieldset"} style={{marginTop:'2vh'}}>
<legend className={"k-form-legend"}>
Atributes:
</legend>
<div className="mb-3">
{tempAtr.map((data) =>
<Field
name={data.naziv}
component={ data.id === 1 ?Input:
data.id === 2 ?Input:
data.id === 3 ?DatePicker:
data.id === 4 ?Input:
data.id === 5 ?Input:
data.id === 6 ?DropDownList:
data.id === 7 ?DropDownList:
data.id === 8 ?MultiSelect:
data.id === 9 ?MultiSelect:
Input}
label={data.name}
/>)}
</div>
</fieldset>
<div className="k-form-buttons">
<Button
type={"submit"}
className='appBar-containers'
disabled={!formRenderProps.allowSubmit}
>
Save
</Button>
<Button
type={"submit"}
className='appBar-containers'
disabled={!formRenderProps.allowSubmit}
>
Start
</Button>
</div>
</FormElement>
)}
/>
So when I click Save, it goes to SaveFunction, and when I click Start, it goes to StartFunction. Any help would be very appreciated.
If anybody is looking for an answer, I did it this way. Added an id to each of the buttons:
<Button id='SaveButton'>Save</Button>
<Button id='StartButton'>Start</Button>
and in the onSubmit function added this:
const handleSubmit = (dataItem,event) =>
{
if(event.nativeEvent.submitter.id=='StartButton')
{
startSession(dataItem);
}
else
{
saveChanges(dataItem);
}
};

when I try to type something in the form field, It doesn't let me type anything

I need to do a form in react.js but when I try to type something in the form field, It doesn't let me type anything. I create a function for the input e my form. what am i doing wrong? please help me. thanks.
renderInput(title, value, onChange, validateField, placeholder) {
return (
<div className="col-12 col-md-4">
<div className="form-groud">
<label>{title}</label>
<input type="text" className="form-control"
name={title}
value={value}
onChange={e => onChange(e)}
onBlur={validateField}
placeholder={placeholder} />
</div>
</div>
)
}
renderForm() {
return (
<div className="form">
<div className="row">
{this.renderInput("Avatar", this.state.member.avatar, e => this.updateField(e), this.validateField, "profile picture" )}
{this.renderInput("Name", this.state.member.name, e => this.updateField(e), this.validateField, "name" )}
{this.renderInput("Email", this.state.member.email, e => this.updateField(e), this.validateField, "email" )}
{this.renderInput("Project", this.state.member.project, e => this.updateField(e), this.validateField, "project" )}
{this.renderInput("Devices", this.state.member.devices, e => this.updateField(e), this.validateField, "devices" )}
{this.renderInput("MainStack", this.state.member.mainstack, e => this.updateField(e), this.validateField,"main stack" )}
</div>
<hr />
<div className="row">
<div className="col-12 d-flex justify-content-end">
<button className="btn btn-primary"
onClick={e => this.save(e)}>
Save
</button>
<button className="btn btn-secondary ml-2"
onClick={e => this.clear(e)}>
Cancel
</button>
</div>
</div>
</div>
)
}
My updateField method:
updateField (event) {
const member = {...this.state.member}
member[event.target.avatar] = event.target.value
member[event.target.name] = event.target.value
member[event.target.project] = event.target.value
member[event.target.devices] = event.target.value
member[event.target.mainstack] = event.target.value
this.setState({ member })
}
you should controll input form value's using react state, in React is called a “controlled component”. So check your updateField function and make sure that it change the state value.
https://reactjs.org/docs/forms.html

Formik lost fields when trigger a modal confirm

I have a form using Formik library, all are right but when i want to confirm and submit i need to pass first a modal, the problem is when i launch the confirm modal all data i put in the form are eliminate and nothing is send, i noticed when the i launch the modal, the form tag are upload and then lost the data, someone has the same problem ? o are something to prevent the form tag upload when change the state of the modal ?
here is part of my code, i use CSSTransition on the modal, that mount and unmount the component, and i call previous fields on the form using FieldArray
<Formik
enableReinitialize
initialValues={INITIAL_VALUES}
onSubmit={(values) => {
this.props.onSubmitForm(values.rows);
}}
>
{({ values, errors, touched, isValid }) => (
<Form>
<Title />
<div className="wrapper__brick wrapper__brick--to-up">
<FieldArray
name="rows"
render={({ push }) => (
<>
<div className="wrapper__block">
<div className="master-table">
<FieldArray
name="rows"
render={({ remove }) => (
<div className="master-table__container">
{values.rows.length > 0 &&
values.rows.map((rows, index) => (
<div
className="master-table__row"
key={index}
>
<div className="master-table__item">
<Field
className={errors.rows && errors.rows[index] && touched.rows && touched.rows[index] ?
'input input--empty is-danger'
:
'input input--empty'
}
name={`rows.${index}.name`}
placeholder="Name"
type="text"
validate={validateName}
/>
<ErrorMessage
name={`rows.${index}.name`}
component="p"
className="help is-danger"
/>
</div>
<div className="master-table__item">
<div className={rows.default ? 'select select--disabled' : 'select select--empty'}>
<Field
as="select"
disabled={rows.default}
name={`rows.${index}.kind`}
>
{this.allowedKinds.map((row) => (
<option
value={row.internal}
key={row.internal}
>
{row.name}
</option>
))}
</Field>
</div>
</div>
<div className="master-table__item">
<button
className="button button--trigger tooltip is-tooltip-right"
data-tooltip={rows.default ? t('common.deleteNotAvailable') : t('common.delete')}
onClick={() => remove(index)}
type="button"
disabled={rows.default}
>
<span className="icon">
<i className="far fa-trash-alt" />
</span>
</button>
</div>
</div>
))}
</div>
)}
/>
</div>
</div>
<Footer
onAddRow={() => push({
id: UUID.v4(),
name: '',
kind: 'string',
type: 'generic',
required: false,
default: false
})}
validForm={!isValid}
/>
<TransitionWrapper stateToggle={this.state.openModal}>
<ModalDialog
iconModal="fas fa-info-circle"
titleText={t('modals.descriptionContinue')}
onCloseMethod={this.handleShowModal}
onAcceptMethod={this.props.onSubmitForm}
/>
</TransitionWrapper>
</>
)}
/>
</div>
</Form>
)}
</Formik>

Categories