I want to clear all fields on click of reset button in the form. How can I
do it using state? I am using material ui theme. I dont want to set states
individually. Is that possible?
<form className={classes.form}>
<FormControl margin="normal" required fullWidth>
<InputLabel htmlFor="Name">Name</InputLabel>
<Input id="name" name="name" autoComplete="name" autoFocus />
</FormControl>
<div className ='switchdesign'>
<FormControlLabel required
label="Private ? "
labelPlacement="start"
control={
<Switch
checked={this.state.checkedA}
onChange={this.handleChange('checkedA')}
value="checkedA" />
} />
</div>
<div className ='switchdesign'>
<FormControl className={classes.formControl}>
<Select
labelPlacement="start"
value={this.state.age}
onChange={this.onhandleChange}
name="tenant"
displayEmpty
className={classes.selectEmpty}
>
<MenuItem value="" disabled>
Choose Option
</MenuItem>
<MenuItem value="a">A</MenuItem>
<MenuItem value="b">B</MenuItem>
<MenuItem value="c">C</MenuItem>
</Select>
<FormHelperText>Tenant</FormHelperText>
</FormControl>
</div>
<Button
type="reset"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
>
Reset
</Button>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
>
Submit
</Button>
</form>
Do I need to compulsorily use refs? is this a better approach? or using
states is better?
You can do it by set the inital state into variable then reset it like this
class MyComponent extends Component {
static initialState = {
// your object state
}
constructor(props) {
super(props)
//set your state here when init component
this.state = {
}
}
resetForm() {
this.setState(initialState)
}
}
Let me know if you still have problem
Related
I have a form that has a few textfields in it. If you have a certain role then you should be able to click in the fields and type but if you do not have the admin role then they should all be disabled. How would I disable all the textfields given this situation? Here is my code. I am fairly new to react and any help would be appreciated.
I could do something like this but is there an easier way with less repetition as this form is most definitely to get bigger and more complex and I should be able to disable the entire thing if not given the correct role.
export default function BasicTextFields() {
const classes = useStyles();
const hasRole = authService.verifyRole(role.admin)
return (
{hasRole ? (
<form className={classes.root} noValidate autoComplete="off">
<TextField id="standard-basic" label="Title" />
<TextField id="filled-basic" label="Description" />
<TextField id="outlined-basic" label="Data" variant="outlined" />
</form>
);
) : (
<form className={classes.root} noValidate autoComplete="off">
<TextField id="standard-basic" label="Title" disabled/>
<TextField id="filled-basic" label="Description" disabled/>
<TextField id="outlined-basic" label="Data" variant="outlined" disabled/>
</form>
}
Rather than duplicating your elements and passing disabled as a single keyword (which is a shorthand for disabled={true}, you can explicitly pass a boolean value to it:
export default function BasicTextFields() {
const classes = useStyles();
const hasRole = authService.verifyRole(role.admin)
return (
<form className={classes.root} noValidate autoComplete="off">
<TextField id="standard-basic" label="Title" disabled={!hasRole}/>
<TextField id="filled-basic" label="Description" disabled={!hasRole}/>
<TextField id="outlined-basic" label="Data" variant="outlined" disabled={!hasRole}/>
</form>
);
}
Little simpler...
<form className={classes.root} noValidate autoComplete="off">
<TextField id="standard-basic" label="Title" disabled={!hasRole}/>
<TextField id="filled-basic" label="Description" disabled={!hasRole} />
<TextField id="outlined-basic" label="Data" variant="outlined" disabled={!hasRole}/>
</form>
There is this dynamic form component.
Main.js
import RegistrationItemfrom "./RegistrationItem"
.......
<Form onSubmit={(e) => {e.preventDefault();}}>
<RegistrationItem
inputtype="email"
inputplaceholder="Email Address*"
icon={faEnvelope}
/>
<RegistrationItem
inputtype="password"
inputplaceholder="Password*"
icon={faLock}
/>
<button onClick={handleLogin()} > Login </Login>
</Form>
File for input fields with styling and icons add to it.
RegistrationItem.js.
const RegistrationItem = () ={
return(
<InputGroup className=" mb-4">
<Input
type={inputtype}
name={inputname}
id={inputid}
placeholder={inputplaceholder}
className="border-right-0"
/>
<InputGroupAddon addonType="append">
<InputGroupText className="bg-transparent text-primary border-left-0">
<FontAwesomeIcon className="text-primary" icon={icon} />
</InputGroupText>
</InputGroupAddon>
</InputGroup>
)
}
How to implement submit of the form from the Login button <button onClick={handleLogin()} > Login </Login>
Based on the code given we need two values. One is the email and the other is the password.
So two states needed to be added to the Form element email and password. These values need to be changed based on the change in the input.
So when the form is submitted these values can be used to perform whatever action is needed
The code could be like this if we are using only react and not other form libraries like react hook form
Main.js
import RegistrationItemfrom "./RegistrationItem"
.......
const [email,setEmail] = useState('');
const [password,setPasword] = useState('')
<Form onSubmit={(e) => {e.preventDefault();handleSubmit(email,password,...otherArgs);}}>
<RegistrationItem
inputtype="email"
inputplaceholder="Email Address*"
icon={faEnvelope}
value={email}
setValue={setEmail}
/>
<RegistrationItem
inputtype="password"
inputplaceholder="Password*"
icon={faLock}
value={password}
setValue={setPassword}
/>
<button type="submit" > Login </button>
</Form>
RegistrationItem.js
const RegistrationItem = ({inputtype,inputname,inputid,inputplaceholder,value,setValue,icon}) ={
return(
<InputGroup className=" mb-4">
<Input
type={inputtype}
name={inputname}
id={inputid}
placeholder={inputplaceholder}
value={value}
onChange={e=>setValue(e.target.value)}
className="border-right-0"
/>
<InputGroupAddon addonType="append">
<InputGroupText className="bg-transparent text-primary border-left-0">
<FontAwesomeIcon className="text-primary" icon={icon} />
</InputGroupText>
</InputGroupAddon>
</InputGroup>
)
}
you need to declare state and pass that to your child component and can update the state from child element and when you click on login you can use the state.
below i have shown you how you can declare the state and how you can pass it to your child element and in child element you can use it.
note : i have just passed it in your child component and over ther in argument you can see it so wherever you want to use them you can use it.
const [registrationTypeValue,setRegistrationTypeValue]=useState("")
<Form onSubmit={(e) => {e.preventDefault();}}>
<RegistrationItem
inputtype="email"
inputplaceholder="Email Address*"
icon={faEnvelope}
registrationTypeValue={registrationTypeValue}
setRegistrationTypeValue={setRegistrationTypeValue}/>
<RegistrationItem
inputtype="password"
inputplaceholder="Password*"
icon={faLock}
/>
<button onClick={handleLogin()} > Login </Login></Form>
const RegistrationItem = ({registrationTypeValue,setRegistrationTypeValue}) ={
return(
<InputGroup className=" mb-4">
<Input
type={inputtype}
name={inputname}
id={inputid}
placeholder={inputplaceholder}
className="border-right-0"
/>
<InputGroupAddon addonType="append">
<InputGroupText className="bg-transparent text-primary border-left-0">
<FontAwesomeIcon className="text-primary" icon={icon} />
</InputGroupText>
</InputGroupAddon>
</InputGroup>
)
}
I want to make a textField clickable so that a dialog box opens for the user to type in more text.
Do you have any idea how can I make that happen with the help of MaterialUI?
This is my current solution, where a button is displayed to open the dialogbox (instead of making the textField itself clickable):
<form noValidate autoComplete="off">
<TextFieldDialog />
<TextField
id="outlined-multiline-static"
label="Frage"
multiline
rows={4}
placeholder="Tippe hier die Frage ein!"
onChange={this.handleChange.bind(this)}
variant="outlined"
style={{
backgroundColor: "white",
}}
>
</form>
You could implement onClick on TextField
const [dialogOpen, setDialogOpen] = useState(false)
return (
<div>
<TextField
id="outlined-basic"
label="Outlined"
variant="outlined"
onClick={() => setDialogOpen(true)}
/>
<Dialog open={dialogOpen} onClose={() => setDialogOpen(false)}>
<DialogTitle>Sample Dialog</DialogTitle>
<DialogContent dividers>
<Typography>Your content here</Typography>
</DialogContent>
</Dialog>
</div>
)
Codesandbox demo
I want to display like an error with red color unless there is a selected option.
Is there any way to do it.
For setting a required Select field with Material UI, you can do:
class SimpleSelect extends React.PureComponent {
state = {
selected: null,
hasError: false
}
handleChange(value) {
this.setState({ selected: value });
}
handleClick() {
this.setState(state => ({ hasError: !state.selected }));
}
render() {
const { classes } = this.props;
const { selected, hasError } = this.state;
return (
<form className={classes.root} autoComplete="off">
<FormControl className={classes.formControl} error={hasError}>
<InputLabel htmlFor="name">
Name
</InputLabel>
<Select
name="name"
value={selected}
onChange={event => this.handleChange(event.target.value)}
input={<Input id="name" />}
>
<MenuItem value="hai">Hai</MenuItem>
<MenuItem value="olivier">Olivier</MenuItem>
<MenuItem value="kevin">Kevin</MenuItem>
</Select>
{hasError && <FormHelperText>This is required!</FormHelperText>}
</FormControl>
<button type="button" onClick={() => this.handleClick()}>
Submit
</button>
</form>
);
}
}
Working Demo on CodeSandBox
Material UI has other types of Select(native) also where you can just use plain HTML required attribute to mark the element as required.
<FormControl className={classes.formControl} required>
<InputLabel htmlFor="name">Name</InputLabel>
<Select
native
required
value={this.state.name}
onChange={this.handleChange}
inputProps={{
name: 'name',
id: 'name'
}}
>
<option value="" />
<option value={"lala"}>lala</option>
<option value={"lolo"}>lolo</option>
</Select>
</FormControl>
P.S. https://material-ui.com/demos/selects/#native-select
The required prop only works when you wrap your elements inside a <form> element, and you used the submit event to submit the form.
this is not related to react, this is pure HTML.
In MUI v5 (2022), it works like this:
const handleSubmit = (e)=>{
e.preventDefault()
// ...
}
return (
<form onSubmit={handleSubmit}>
<Select required value={val} onChange={handleChange} required>
<MenuItem value="yes">Yes</MenuItem>
<MenuItem value="no">No</MenuItem>
</Select>
<Button type="submit">Submit</Button>
</form>
)
As you can see, it works the same way you think it should work, so what your code should probably be similar to this.
But the required prop only works when you wrap your elements inside a element, and you used the submit event to submit the form.
And if you're using <FormControl>, but the required prop on both elements:
<FormControl required>
<Select required>
// ...
</FormControl>
I'm using react-bootstrap in my current Meteor project. I can't seem to get this form to work. What am I doing wrong? I can't seem to be able to read the value of the FormControl input.
At the moment I am getting this error:
"imports/ui/components/add-spark.js:35:61: Unexpected token (35:61)"
Also my modal doesn't work anymore when I add 'ref="city"' to FormControl.
Then I get this error: "Uncaught Invariant Violation: Stateless function components cannot have refs"
UPDATE:
I have managed to get the ref in my modal working. But still I can't get the value from the form.
I ofcourse forgot to make it a class object which caused a lot of the problems. Now I am getting a different error though:
"Uncaught TypeError: Cannot read property 'cityInput' of undefined"
When I try to add my function like this:
<form onSubmit={ this.handleInsertSpark.bind(this) }>
My modal won't work anymore. I then get this error code:
"add-spark.js:53 Uncaught TypeError: Cannot read property 'bind' of undefined(…)"
This is my current code:
const handleInsertSpark = (event) => {
event.preventDefault();
var city = ReactDOM.findDOMNode(this.refs.cityInput).value
console.log(city);
};
function FieldGroup({ id, label, help, ...props }) {
return (
<FormGroup controlId={id}>
<ControlLabel>{label}</ControlLabel>
<FormControl {...props} />
{help && <HelpBlock>{help}</HelpBlock>}
</FormGroup>
);
}
export default class AddSpark extends Component {
render() {
return (<div>
<form onSubmit={ handleInsertSpark }>
<FormGroup controlId="formControlsCity">
<ControlLabel>Select your city</ControlLabel>
<FormControl componentClass="select" placeholder="Choose your city" ref="cityInput" onClick={ moreOptions }>
<option value="select">Choose your city</option>
<option value="0">Beijing</option>
<option value="1">Shanghai</option>
<option value="2">Chengdu & Chongqing</option>
</FormControl>
</FormGroup>
<FormGroup controlId="formControlsPerson">
<ControlLabel>Select your person</ControlLabel>
<FormControl componentClass="select" placeholder="Choose your person">
<option value="select">First select your city</option>
</FormControl>
</FormGroup>
<FormGroup controlId="formControlsLocation">
<ControlLabel>Select your location</ControlLabel>
<FormControl componentClass="select" placeholder="Choose your location">
<option value="select">First select your city</option>
</FormControl>
</FormGroup>
<FieldGroup
id="formControlsText"
type="text"
label="Title"
placeholder="Enter your title"
/>
<FormGroup controlId="formControlsTextarea">
<ControlLabel>Content</ControlLabel>
<FormControl componentClass="textarea" placeholder="textarea" />
</FormGroup>
<div className="upload-area">
<p className="alert alert-success text-center">
<span>Click or Drag an Image Here to Upload</span>
<input type="file" onChange={this.uploadFile} />
</p>
</div>
<Button
type="submit">
Submit
</Button>
</form>
</div>
)}
}
I managed to solve this myself by reading the React documentation again. Seems like I was just not using React in the way it is intended.
Here is my the code that works and does what I want it to do:
function FieldGroup({ id, label, help, ...props }) {
return (
<FormGroup controlId={id}>
<ControlLabel>{label}</ControlLabel>
<FormControl {...props} />
{help && <HelpBlock>{help}</HelpBlock>}
</FormGroup>
);
}
export default class AddSpark extends Component {
constructor(props){
super(props)
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('Text field value is: ' + this.state.value);
}
render() {
return (<div>
<form >
<FormGroup controlId="formControlsCity">
<ControlLabel>Select your city</ControlLabel>
<FormControl componentClass="select" placeholder="Choose your city" onClick={ moreOptions } value={this.state.value} onChange={this.handleChange} >
<option value="select">Choose your city</option>
<option value="Beijing">Beijing</option>
<option value="Shanghai">Shanghai</option>
<option value="Chengdu & Chongqing">Chengdu & Chongqing</option>
</FormControl>
</FormGroup>
<FormGroup controlId="formControlsPerson">
<ControlLabel>Select your person</ControlLabel>
<FormControl componentClass="select" placeholder="Choose your person">
<option value="select">First select your city</option>
</FormControl>
</FormGroup>
<FormGroup controlId="formControlsLocation">
<ControlLabel>Select your location</ControlLabel>
<FormControl componentClass="select" placeholder="Choose your location">
<option value="select">First select your city</option>
</FormControl>
</FormGroup>
<FieldGroup
id="formControlsText"
type="text"
label="Title"
placeholder="Enter your title"
/>
<FormGroup controlId="formControlsTextarea">
<ControlLabel>Content</ControlLabel>
<FormControl componentClass="textarea" placeholder="textarea" />
</FormGroup>
<div className="upload-area">
<p className="alert alert-success text-center">
<span>Click or Drag an Image Here to Upload</span>
<input type="file" onChange={this.uploadFile} />
</p>
</div>
<Button
onClick={this.handleSubmit}>
Submit
</Button>
</form>
</div>
)}
}