React hook form + Modal + data-bs-dismiss - reactjs

I want to use a tailwind modal, who open & close with data-bs-dismiss argument.
I put on my button : data-bs-dismiss='modal'
But with react hook form, it's doesn't work like i want. If the form contains error or bad input, the data-bs-dismiss was execute and not payed attention to the form errors.
I want close the modal & submit, when the form validation is ok, and contains no other error.
If anyone have a solution.. thank's
My code :
const methods = useForm()
return(
<FormProvider {...methods}>
<form id={props.id} onSubmit={methods.handleSubmit(onSubmit)}>
<input id='...'> ... <input/>
<input id='...'> ... <input/>
<input id='...'> ... <input/>
...
<li>
<Button
btnId={`${props.btnContent}Btn`}
btnContent={props.btnContent}
btnClass='btn'
btnType='submit'
btnRipple
dismiss={'modal'}
form={props.id}
/>
<li/>
<form/>
</FormProvider>
)

Well, what you can do is, Instead of using dismiss you can check in your onSubmit function for any errors. And if the form has any errors then keep the modal open otherwise submit the form and close it.

Related

Can't get formik validation to work with react-router

Good morning,
I want a react-router link to forward ONLY when the form has no errors, unfortunately the code that's below does forward before the form is even validated so no error shows up and so on. Can you please guide me on how to fix this, so that the form is validated and if it has no errors, the link forwards further?
Here's my code:
<Link to={this.props.formikProps.isValid?'mainMenu': 'itemDetail'}>{!this.props.disabled && <button className="buttons-panel__button" type="button" onClick={() => (this.props.handleSubmit(false), this.props.formikProps.isValid? '' : this.onValidationFail())} >Save</button>}</Link>
The method is(it's basically only to display a popup error, and it's working):
onValidationFail() {
setAlertMessage("You need to fill all mandatory fields")
}
So far the best I've achieved is that it works as intended in every case, but if the form hasn't been touched at all. I've tried several different ways, including formValidate from formik, for some reason it didn't work too.
I'm looking forward to some tips/hints/solutions on the case.
I think that your solution looks bit overcomplicated. Maybe just use simple form submit, and after form submission redirect user to route.
It would look like that:
import { Formik, Form, Field } from 'formik'
class MyForm {
render() {
return (
<Formik
initialValues={...}
onSubmit={() => {this.props.history.push('/go-somewhere')}}
>
<Form>
<Field name="firstName" type="text" />
<button type="submit">Submit</button>
</Form>
</Formik>
)
}
}

How to Link A certain Keyboard Key to a function in React JS

I have made an App that is simple you can check it out here but the problem is now that when a user is logged in and creating a post there is a button that adds a post now I want "Enter" key to perform the same task the code to my button is
<Button variant="contained" color="secondary" onClick = {updateList}>Add item</Button>
now I want to bind the same updateList function to Enter key please guide me on how can I do that???
The button is from Material-ui
also currently as I click enter key it reloads the page I also want to stop that from happening
Also, can anyone tell me that is it possible to take multikey stroke input like ctrl + Z ?
If you want to bind function to some key you can do it by event listeners called onKeyDown or onKeyPress:
handleKeyPress = (event) => {
if(event.key === 'Enter'){
console.log('enter press here! ')
}
}
function App(){
return(
<div>
<input type="text" id="one" onKeyPress={this.handleKeyPress} />
</div>
);
}
Because you pager is reloading im guessing your using the HTML form tag. To prevent it the page from reloading your need to prevent the default event behavior after submitting.
<form onSubmit={(event) => {event.preventDefault() /* this stops reloading the page */ }} ></form>
To be able to submit on enter, you should add a button in side the form tag and add type "submit" to it.
<form onSubmit={(event) => {event.preventDefault() /* this stops reloading the page */ }} >
<button type={"submit"}/>
</form>
That should do it.

passing down functions correctly for onSubmit and handleChange on a form

I am trying to handle navigation around my application. I want to include a link back to the form component from displayweather using conditional statements. I can get the form to show correctly, however when you press submit on the form it just refreshes back to the Form under App
I am trying to pass the functions down from App to Navbar which holds a second instance of the Form
However, using react dev tools the functions are still showing as undefined?
Here is a gist of the code:
https://gist.github.com/dhuang612/6c683b6ccd0ce6299631db76ed76ccd7
The two functions I am trying to hand down from App
handleChange = e => {
this.setState({
[e.target.name]: e.target.value
});
};
//handles submit on the form and runs the api call
onSubmit = e => {
e.preventDefault();
this.fetchWeatherData();
this.setState({ fetchedweatherdata: !this.state.fetchedweatherdata }, () =>
console.log(this.state.fetchedweatherdata)
);
};
this is how I am trying to pass the functions down to this second instance of form
<DisplayWeather
currentweather={this.state.currentweather}
currentforecast={this.state.currentforecast}
currenttime={this.state.currenttime}
weatherIcon={this.state.weatherIcon}
hourlyWeather={this.state.hourlyWeather}
/>
<Navbar fetchedweatherdata={this.state.fetchedweatherdata}>
<Form
onChange={this.handleChange}
{...this.state}
onSubmit={this.onSubmit}
/>
</Navbar>
and this is how I am trying to call the functions on the form
return (
<div>
{!this.state.fetchedweatherdata ? (
<div>
<button onClick={this.resetState}>return to form</button>
</div>
) : (
<Form onChange={handleChange} {...this.state} onSubmit=
{onSubmit} />
)}
</div>
I am not getting any error messages, the screen refreshes and reloads the origin Form under App, I would like the application to re-send out the api request and show current weather for the new location. Please see gist to see all the code together.
Thanks for any help!
The issue was that you did not pass nothing to Navbar itself.
I did put a codesandbox up for you, please, for the future question if there is more code included try to do the same with codesandbox, this can save lifes!
Here is the mentioned sandbox

Convenient way to mark a complete form as readonly

I have an antd form with multiple form items and try to find a way to mark the complete form as readonly. I could for sure set each input component to 'disabled' but I wonder if there is a convenient way to do so on the form via an API call that I do not know yet.
Wrapping the antd form inside a fieldset and setting this to 'disabled' works pretty well.
<fieldset disabled={editorDisabled}>
<Form>
...
<Form/>
<fieldset/>
I don't see such an option in the form api, and I think it's the rare use case, so I doubt it exists. However, you can simply add variable which will track the disabled status, i.e.:
const YourAwesomeComponent = (props) => {
const disabled = someLogicToCalculateTheDisabledStatus(props);
return <Form ...>
<Input disabled={disabled} ... />
<Select disabled={disabled} ... />
<Button disabled={disabled} ... />
</Form>
}
Hope it helps.
As of version 4.21.0 (Jun 6, 2022) the disabled prop can be used in the form to disable all fields, i.e.:
<Form disabled={true}>
...
</Form>
It is enforced as long as a <Form.Item/> isn't explicitly marked as not disabled with disabled={false}. You can see the reference in antd docs here.

Form in Material UI Dialog using React

I am trying to get a form working inside of a Material UI Dialog component. If I wrap the Dialog in the form tags, they do not even show up in the resulting html (no idea why yet)...
<form onSubmit={someFunction}>
<Dialog>
...
</Dialog>
</form>
If I reverse it and put the form tags inside the Dialog, the form elements show up in the resulting html, but then the action button set to type="submit" will not fire the form's onSubmit.
<Dialog>
<form onSubmit={someFunction}>
...
</form>
</Dialog>
Has anyone had any success getting this combination to work? I know I can just call the function directly from the action button click, but I am also using Redux Form and have other non-dialog forms in the app, so I have it bound to the form element. So I really need to invoke the form submit from a Dialog somehow.
Actually - I have/had the onSubmit={handleSubmit(this.myFunction)} to begin with and that was not the issue. The issue turned out to be how Material UI mounts the Dialog (which apparently is different than react-toolbox). They mount it on the body - I assume for easier positioning - so anything outside of the Dialog is ignored.
With the form inside the Dialog, the buttons are outside the form (which is again apparently different than react-toolbox). So to make it work, you have to use the HTML 5 'form' attribute as detailed here (along with a poly-fill for older browsers if needed). The form needs an id attribute and then the button outside it needs a form attribute with the value set to the id of the form. Then the form elements inside the dialog behave as expected. Thanks for the response though!
The material-ui Dialog component inherits from the material-ui Modal component, which means it accepts the prop "disablePortal" - which is false by default.
from the docs:
"Disable the portal behavior. The children stay within it's parent DOM hierarchy."
https://material-ui.com/api/modal/#props
by default, the dialog is rendered as a child of your root html node, to have it render inside the <form> tag, you need to disable the portal behavior.
<form onSubmit={someFunction}>
<Dialog disablePortal>
<DialogTitle>
title!
</DialogTitle>
<DialogContent>
form fields go here
</DialogContent>
<DialogActions>
<button type="submit">submit!</button>
</DialogActions>
</Dialog>
</form>
<form onSubmit={someFunction}>
<Dialog disablePortal>
<DialogTitle>
title!
</DialogTitle>
<DialogContent>
form fields go here
</DialogContent>
<DialogActions>
<button type="submit">submit!</button>
</DialogActions>
</Dialog>
</form>
Hey yeah I have this combo working... well I am using the Dialog component from react-toolbox which is very similar to Material-ui but they use Css-modules for styles instead of inline.
So the function you provide to the onSubmit attribute of the form element is going to be the handleSubmit function from redux-form. If you want to do anything such as dispatch actions and store the data then you will need to pass in an onSubmit function to the handleSubmit function. What happens is your onSubmit function is called with the values(object with properties of the values of your form) and the dispatch function from the redux store. You can see the project I have which has the setup you are looking for.
Instead of onSubmit={someFunction}, make it
<Dialog>
<form onSubmit={this.someFunction}>
...
</form>
</Dialog>

Resources