How to use <Link> and <Button> in React - reactjs

I'm currently using React.
My code uses useForm in the react to perform validation.
I want to go to another page when a user enters a nickname and presses the Enter key or clicks the Button.
Now my code is to put the <button> tag inside the <Link> tag, and it will not complete the validation and will immediately go to another page.
In the opposite case, my code does not go to another page. Help me :(
<form onSubmit={handleSubmit(onValid)}>
<input
{...register("nickName", {
required: true,
minLength: {
value: 2,
message: "error",
},
})}
className="join-input"
placeholder="nickname here"
/>
<div className="error-message">{errors?.nickName?.message}</div>
<Link to={"/office"}>
<button className="go-btn bttn-material-flat">Enter</button>
</Link>
</form>

You should handle the linking to the new page in your handleSubmit function e.g handleSubmit(onSubmit) and then:
const onSubmit = () => {
// programatically link here, implementation differs depending on what framework you are using.
};
<form onSubmit={handleSubmit(onSubmit)}>
...
</form>

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.

React Formik - app performs unwanted request (submit) after pressing Enter key in the input field

When I write something in the "name" field and press Enter, app performs a request, address bar in the web browser changes to http://localhost:3000/?name=something. But when I just add another input field to the form, app behaviour changes: it doesn't perform request in such case. I would like to ask:
1. Why app behaviour is dependent on the number of input fields?
2. How can I force app to not perform submit (request) when there is
only one field in the form, to act like there would be many fields?
import {Formik} from 'formik';
function App() {
return (
<div className='App'>
<Formik>
{props => (
<form>
<input type="text" name="name"/>
{/*If I uncomment the line below, the app will not perform request after pressing Enter*/}
{/*<input type="text" name="surname"/>*/}
</form>
)}
</Formik>
</div>
);
}
export default App;
I think your validation is just stoping it when you have two fields. HTML form should submit by default when you hit enter. You have an html form.
If you can, I would just remove the html form element and manually control the submit.
<Formik
initialValues={{ name: 'test' }}
onSubmit={(values, actions) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
actions.setSubmitting(false);
}, 1000);
}}
>
{props => (
<>
<input
type="text"
onChange={props.handleChange}
onBlur={props.handleBlur}
value={props.values.name}
name="name"
/>
{props.errors.name && <div id="feedback">{props.errors.name}</div>}
<button onClick={props.handleSubmit}>Submit</button>
</>
)}
</Formik>
Or just use the formik "Form" component and create a custom event handler for the enter key press.
you need to have a couple of things..
You need to have a validationSchema.
You can do this with yup, or write your own.
Inside the Formik tag, you should then add the following fields
<Formik
initialValues={{ name: "", surname: "" }}
onSubmit={(values) => console.log(values)}
validationSchema={validationSchema}>

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

Render a new component on the same page

I have a form component, and upon filling this form (click submit button), I would like to render a new component in place of the form, on the same page, with some comment like "congratulations for filling the form" for instance.
I am not sure what is the right way to achieve this. I am not sure it is right to do a conditional rendering here.
Also, should this be done on the page where I render the form component, or in an action creator ?
Thank you for your kind help !
It is a sample code of how to do it:
export var LoginBox = React.createClass({
getInitialState(){
return{
registered:false
}
},
Register(){
//submit registration form and change form to login form
...
this.setState({registered : true});
},
login(){
// submit login form here
},
loginForm(){
var{registered} = this.state;
if(registered){// your registeration form
return(
<form onSubmit={this.Register}>
<div><input ref="number" type="tel"/></div>
<button type="submit">register</button>
</form>
);
}else{
return (// your login form
<form onSubmit={this.login}>
<div><input type="number" ref="activationCode"/></div>
<button type="submit">login</button>
</form>
);
}
}
},
render(){
return (
<div className="loginBox">
{loginForm()}
</div>
)
}
});
It is a sample code. First, you need to initialize a state for default form. Then, on form submit change the state in order to change form on your view.
I hope it helps you to understand it.

Resources