Submit form on checkbox change and keep built-in browser validation - javascript

My form consists of text input and a checkbox.
The text input cannot be empty upon form submit, hence the required parameter.
I want to submit the form on each checkbox change and still keep this built-in validation. Currently, if the text input is empty and I click the checkbox, it WILL submit.
How can keep the validation on checkbox change?
const Form = () => {
const handleSubmit = (e: any) => {
e.preventDefault()
alert('submitted')
}
return (
<form onSubmit={handleSubmit}>
<input type="text" required />
<input type="checkbox" onChange={(e) => handleSubmit(e)} />
<button type="submit">Submit</button>
</form>
)
}
const root = document.getElementById('root')
ReactDOM.render(<Form />, root)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

You can try to trigger the submit button, in this case the html5 validation should run:
const Form = () => {
const handleSubmit = (e: any) => {
e.preventDefault()
alert('submitted')
}
const handleChange = (e: any) => {
const btn = document.getElementById('btnSubmit');
btn.click();
}
return (
<form onSubmit={handleSubmit}>
<input type="text" required />
<input type="checkbox" onChange={(e) => handleChange(e)} />
<button id="btnSubmit" type="submit">Submit</button>
</form>
)
}
const root = document.getElementById('root')
ReactDOM.render(<Form />, root)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Related

How can I submit the form?

I am currently making a blog website with "reactjs".In this component, I am creating new blogs by putting values of author, title, and body. I cant submit the form by hitting 'Enter' on the keyboard on any fields.
This problem gets fixed when I remove my input field of author. Please guide me as I am new to Reactjs
import React, { useState } from "react";
function Create() {
const [title, setTitle] = useState();
const [author, setAuthor] = useState();
const [body, setBody] = useState();
const submitFunc = (e) => {
e.preventDefault();
const blog = { title, body, author };
};
return (
<div className="create container ">
<form onSubmit={submitFunc}>
<label className="text-danger" htmlFor="title">
Title:
</label>
<input
name="title"
type="text"
onChange={(e) => setTitle(e.target.value)}
required
/>
<label className="text-danger" htmlFor="body">
Content:
</label>
<textarea
onChange={(e) => setBody(e.target.value)}
required
name="body"
></textarea>
<label className="text-danger" htmlFor="author">
Author:
</label>
<input
name="author"
id="author"
type="text"
onChange={(e) => setAuthor(e.target.value)}
required
/>
</form>
<p>{title}</p>
<p>{author}</p>
<p>{body}</p>
</div>
);
}
export default Create;
From the snippet you reported it is not clear how it should handle the Enter pressing.
If you want to do anything when the user presses Enter on any text area you can use the onKeyPress event handler.
const handleKeyPress = (e) => {
if(e.keyCode === 13){
e.preventDefault();
// ...check title, boby and author exists
const blog = { title, body, author };
// ...submit the form
};
<textarea
name="body"
required
onChange={(e) => setBody(e.target.value)}
onKeyPress={handleKeyPress}
></textarea>

using button to increment divs in react

I am fairly new to React/Next and I had a quick question.
I am trying to create a button that will increment the number of divs in real time.
Here is my code:
import React from 'react'
const Clown = () => {
const [clownCounter, setClownCounter] = React.useState(1);
function addClown(event) {
event.preventDefault();
}
return(
<React.Fragment>
<div>
<form>
{Array.from({ length: clownCounter}, (_unused, index) => index + 1).map(
(clownIndex) => {
const clownid = `${clownIndex}`
return (
<div key={clownid } className="clown-box">
<label htmlFor={clownid }>Activity {clownIndex}</label>
<br />
<input type="text" onChange={(e)=> onChangeForm(e)} name={activityId} id={activityId} />
<br />
</div>
)
},
)}
<span className="clown-add">
<button onClick={addClown} onChange={() => { setClownCounter(clownCounter++) }}>Add Clown</button>
</span>
<br />
</form>
</div>
</React.Fragment>
)
}
export default Clown
As you can see the goal is to increase the amount of clown-box divs everytime the button is clicked. I think I am close but it is not currently working. Can anyone help?
There are few small this wrong with your code.
First, you have an extra comma(,) after the return statement in map function
Second, you are updating state clownCounter on onChange event in button, which is incorrect. You should update it on click and also prevent the default behaviour of form submit on click of button or you can define the button type to be type="button"
Lastly, you need to define your onChangeForm function
const Clown = () => {
const [clownCounter, setClownCounter] = React.useState(1);
function onChangeForm() {
}
function addClown(event) {
event.preventDefault();
setClownCounter(prev=> prev+1);
}
console.log(clownCounter);
return(
<div>
<form>
{Array.from({ length: clownCounter}, (_unused, index) => index + 1).map(
(clownIndex) => {
const clownid = `${clownIndex}`;
return (
<div key={clownid } className="clown-box">
<label htmlFor={clownid }>Activity {clownIndex}</label>
<br />
<input type="text" onChange={(e)=> onChangeForm(e)} name={'activityId'} id={'activityId'} />
<br />
</div>
)
})
}
<span className="clown-add">
<button type="button" onClick={addClown}>Add Clown</button>
</span>
<br />
</form>
</div>
)
}
ReactDOM.render(<Clown />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="app" />
Edit: Thought issue was caused by Array.from, but, it's not. I've removed that part, but kept the example since OP might find it useful
const { useState } = React;
const Clowns = ({ title }) => {
const [clownCounter, setClownCounter] = React.useState(1);
return (
<div>
<button onClick={() => setClownCounter(clownCounter + 1)}>
Add clown
</button>
<div className='clowns'>
{Array.from({ length: clownCounter}, (_unused, index) => index + 1).map((e, i) => (
<div>
<h4>{`Clown #${i + 1}`}</h4>
<img src={`https://placehold.it/150x150&text=Clown%20%23${i + 1}`} />
</div>
))}
</div>
</div>
);
};
ReactDOM.render(<Clowns />, document.getElementById("react") );
.clowns { display: flex; flex-direction: column; }
h4 { margin-bottom: 5px; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>

Input reset in react

I am working on a react app. Where I am talking a two inputs in form after submitting the form my fields are not reseting. How to do those. I am attaching my form component code can anyone help me out with this.
import React, { Component } from 'react';
class Form extends Component {
render() {
return (
<form onSubmit={this.props.getWeather}>
<input type="text" name="city" placeholder="city.." />
<input type="text" name="country" placeholder="country.." /><br></br>
<button >Submit</button>
</form>
);
}
}
export default Form;
Inside the getWeather method you will have access the React synthetic event object, say event. Get the native dom element out of it using event.target, and then call the reset() method as event.target.reset(). This will clear all the form input values.
Play with the below example.
function App() {
const onFormSubmit = e => {
e.preventDefault();
e.target.reset();
};
return (
<div className="App">
<form onSubmit={onFormSubmit}>
<div>
<label htmlFor="name">Enter your name: </label>
<input type="text" name="name" id="name" required />
</div>
<div>
<input type="submit" value="Reset!" />
</div>
</form>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

How to totally disable a react component?

I have a react component which has some buttons and text inputs. I want to totally disable all the things inside this component until some other works are complete. How to make the entire inner component disabled?
You can add disabled props and use CSS to disable div
const MyComponent = ({disabled}) => {
return (
<div style={disabled ? {pointerEvents: "none", opacity: "0.4"} : {}}>
<h1> Text</h1>
<input type="text"/>
<input type="password"/>
<button>Login</button>
</div>
)
}
Better to use form and fieldset, and put all the input/button elements inside that. You can disable all of them by setting the property disabled to fieldset.
Refer MDN Doc for more details.
Working example:
class App extends React.Component {
constructor () {
super()
this.state = { disable: false }
}
toggleDisable = () => this.setState(prevState => ({disable: !prevState.disable}))
buttonClick = (e) => {
e.preventDefault();
console.log('button clicked');
}
render (){
return (
<div>
<button className='toggle' onClick={this.toggleDisable}>Toggle Disable</button>
<form>
<fieldset disabled={this.state.disable}>
<input />
<button onClick={this.buttonClick}>Button</button>
</fieldset>
</form>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
.toggle {
margin-bottom: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app' />
All you need to do is add a disabled prop on the component and pass it on to the inner fields like
<MyComponent disabled={shouldComponentBeDisabled} {...otherProps} />
and in implementation
const MyComponent = ({disabled}) => {
return <div>
<button disabled={disabled}>someBtn</button>
<input type="text" disabled={disabled}/>
</div>
}
You can use disabled prop pattern to save the day.
const App = () => {
return (
<div>
<SomeComponent disabled />
</div>
);
};
const SomeComponent = ({ disabled = false }) => {
return (
!disabled && (
<div>
<h2>Disable SomeComponent to see magic happen!</h2>
</div>
)
);
};

onClick vs onSubmit in React

I have a simple input in react that won't work with onSubmit but with onClick. Why is that? Here is the link to an example.
const styles = {
fontFamily: 'sans-serif',
textAlign: 'center',
};
const clicked = e => {
alert("Hi")
}
const App = () => (
<div style={styles}>
<input type='submit' value='click' onSubmit={clicked}/>
</div>
);
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root" />
onSubmit is a prop for <form>, you should add the handler on to that element:
<form onSubmit={onSubmit}>
<input ... />
</form>
I think it needs to be in a <form></form> for submit to work
Because you're not submitting anything. onSubmit is for submitting forms...

Categories

Resources