React Final Form Material UI creating double lines on input field - reactjs

I have a strange thing happening where I can't really figure out what is creating those double input field lines in my code (see the picture). I have literally copied the code from the official website (React Final Form) and it doesn't seem to be happening there. Does it have something to do with the browser compatibility?
My code:
import React from 'react';
import { Form } from 'react-final-form';
import {
TextField,
Select,
} from 'mui-rff';
import {
Grid,
Button,
MenuItem,
} from '#material-ui/core';
import { createMuiTheme } from '#material-ui/core/styles';
import { ThemeProvider } from '#material-ui/styles';
const theme = createMuiTheme({
palette: {
primary: {
main: '#008080',
},
}
})
const onSubmit = async values => {
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
await sleep(300);
window.alert(JSON.stringify(values, 0, 2));
};
const validate = values => {
const errors = {};
if (!values.firstName) {
errors.firstName = 'Required';
}
if (!values.lastName) {
errors.lastName = 'Required';
}
if (!values.email) {
errors.email = 'Required';
}
return errors;
};
const formFields = [
{
size: 6,
field: (
<TextField
label="First Name"
name="firstName"
margin="none"
required={true}
/>
),
},
{
size: 6,
field: (
<TextField
label="Last Name"
name="lastName"
margin="none"
required={true}
/>
),
},
{
size: 12,
field: (
<TextField
type="email"
label="Email"
name="email"
margin="none"
required={true}
/>
),
},
{
size: 12,
field: <TextField name="notes" multiline label="Notes" margin="none" />,
},
{
size: 12,
field: (
<Select
name="city"
label="Select a City"
formControlProps={{ margin: 'none' }}
>
<MenuItem value="London">London</MenuItem>
<MenuItem value="New York">New York</MenuItem>
<MenuItem value="Tallinn">Tallinn</MenuItem>
</Select>
)
}
];
const FinalForm = () => {
return (
<div className="col s12 m6">
<div className="card-panel grey lighten-3">
<h5>Please fill out this form</h5>
<Form
onSubmit={onSubmit}
validate={validate}
render={({ handleSubmit, form, submitting, pristine }) => (
<form onSubmit={handleSubmit} noValidate>
<Grid container alignItems="flex-start" spacing={2}>
{formFields.map((item, idx) => (
<Grid item xs={item.size} key={idx}>
{item.field}
</Grid>
))}
<Grid item style={{ marginTop: 16 }}>
<Button
type="button"
variant="contained"
onClick={form.reset}
disabled={submitting || pristine}
>
Reset
</Button>
</Grid>
<Grid item style={{ marginTop: 16 }}>
<ThemeProvider theme={theme}>
<Button
variant="contained"
type="submit"
color='primary'
disabled={submitting}
>
Submit
</Button>
</ThemeProvider>
</Grid>
</Grid>
</form>
)}
/>
</div>
</div>
)
};
export default FinalForm;

Related

FormData: The data is not placed in the formData, and an empty object is printed

I have a project in order to run a contracting, building and construction company, and I must create an invoice, and to create an invoice I must send a request to the backend, and the form of the request must be as shown in this picture:
And this is what the interface should look like:
The problem is that when I print "formData" it prints an empty object, even though I passed the data to "formData", how can I solve the problem?
this is the empty Object:
And the data is sent to the backend empty
and when i print:
console.log(formData.get("invoice"));
console.log(formData.get("data"));
the console was:
null
[object Object]
file.js:
import React, { useState } from "react";
import InputAdornment from "#material-ui/core/InputAdornment";
import TextField from "#material-ui/core/TextField";
import Grid from "#material-ui/core/Grid";
import "date-fns";
import DateFnsUtils from "#date-io/date-fns";
// import {
// KeyboardDatePicker,
// MuiPickersUtilsProvider,
// DatePicker,
// } from "#material-ui/pickers";
import { makeStyles } from "#material-ui/core/styles";
import Button from "#material-ui/core/Button";
import CloudUploadIcon from "#material-ui/icons/CloudUpload";
import { addInvoice } from "../../../store/invoiceSlice";
import Icon from "#material-ui/core/Icon";
import { motion } from "framer-motion";
import { useDispatch } from "react-redux";
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import { alpha } from "#material-ui/core/styles";
const useStyles = makeStyles((theme) => ({
root: {
"& > *": {
margin: theme.spacing(1),
},
},
input: {
display: "none",
},
button: {
margin: theme.spacing(1),
// padding: theme.spacing(4),
},
}));
function ShippingTab(props) {
const dispatch = useDispatch();
const classes = useStyles();
const [issueDate, setIssueDate] = useState(new Date());
const [dueDate, setDueDate] = useState(new Date());
const [netAmount, setNetAmount] = useState("");
const [taxNumber, setTaxNumber] = useState("");
const [grossAmount, setGrossAmount] = useState("");
const [file, setFile] = useState(null);
let formData = new FormData();
const fileSelectedHandler = (event) => {
console.log(event.target.files[0]);
const file = event.target.files[0];
if (event.target && file) {
formData.append("invoice", file);
setFile(file);
}
};
const uploadHandler = (event) => {
// fd.append("invoice", files);
formData.append("data", {
grossAmount,
taxNumber,
netAmount,
dueDate,
issueDate,
});
console.log("formmmmmmmmmmm Data: ", formData);
// call api
dispatch(addInvoice(formData));
};
const handleissueDateChange = (date) => {
setIssueDate(date);
console.log("date issssssssss: ", date);
console.log("date issssssssss: ", issueDate);
};
const handleDueDateChange = (date) => {
setDueDate(date);
};
const handleNetAmountChange = (event) => {
setNetAmount(event.target.value);
};
const handleTaxAmountChange = (event) => {
setTaxNumber(event.target.value);
};
const handleGrossAmountChange = (event) => {
setGrossAmount(event.target.value);
};
return (
<>
{/* <MuiPickersUtilsProvider utils={DateFnsUtils}>
<div className="flex -mx-4">
<KeyboardDatePicker
inputVariant="outlined"
className="mt-8 mb-16"
margin="normal"
id="date-picker-dialog"
label="issue Date"
format="MM/dd/yyyy"
KeyboardButtonProps={{
"aria-label": "change date",
}}
value={issueDate}
onChange={handleissueDateChange}
/> */}
<div className="flex -mx-4">
<TextField
id="date"
variant="outlined"
label="Choose Issue Date"
className="mt-8 mb-16 mr-5"
type="date"
defaultValue={issueDate}
InputLabelProps={{
shrink: true,
}}
// value={issueDate}
onChange={handleissueDateChange}
fullWidth
/>
<TextField
id="date"
variant="outlined"
className="mt-8 mb-16"
label="Choose Due Date"
type="date"
defaultValue={dueDate}
InputLabelProps={{
shrink: true,
}}
// value={dueDate}
onChange={handleDueDateChange}
fullWidth
/>
</div>
{/* <KeyboardDatePicker
inputVariant="outlined"
className="mt-8 mb-16 ml-6"
margin="normal"
id="date-picker-dialog"
label="Due Date"
format="MM/dd/yyyy"
KeyboardButtonProps={{
"aria-label": "change date",
}}
value={dueDate}
onChange={handleDueDateChange}
/>
</div>
</MuiPickersUtilsProvider> */}
<TextField
className="mt-8 mb-16"
label="Net Amount"
id="extraShippingFee"
variant="outlined"
InputProps={{
startAdornment: <InputAdornment position="start">$</InputAdornment>,
}}
value={netAmount}
onChange={handleNetAmountChange}
fullWidth
/>
<TextField
className="mt-8 mb-16"
label="Tax Number"
id="extraShippingFee"
variant="outlined"
InputProps={{
startAdornment: <InputAdornment position="start">$</InputAdornment>,
}}
value={taxNumber}
onChange={handleTaxAmountChange}
fullWidth
/>
<TextField
className="mt-8 mb-16"
label="Gross Amount"
id="extraShippingFee"
variant="outlined"
InputProps={{
startAdornment: <InputAdornment position="start">$</InputAdornment>,
}}
value={grossAmount}
onChange={handleGrossAmountChange}
fullWidth
/>
<div className={classes.root}>
<input
accept="application/pdf"
// className={classes.input}
// multiple
type="file"
onChange={fileSelectedHandler}
/>
{/* <label htmlFor="contained-button-file"> */}
{/* <Button
variant="contained"
color="primary"
size="large"
className={classes.button}
startIcon={<CloudUploadIcon />}
> */}
{/* Upload */}
{/* </Button> */}
{/* </label> */}
</div>
<motion.div
className="flex"
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0, transition: { delay: 0.3 } }}
>
<Button
className="whitespace-nowrap mx-4"
variant="contained"
color="secondary"
// onClick={handleRemoveProduct}
startIcon={<Icon className="hidden sm:flex">delete</Icon>}
>
Cancel
</Button>
<Button
className="whitespace-nowrap mx-4"
variant="contained"
color="secondary"
// disabled={_.isEmpty(dirtyFields) || !isValid}
onClick={uploadHandler}
>
Create
</Button>
</motion.div>
</>
);
}
export default ShippingTab;
#hiba-youssef This is not a problem, console logging formData always gives empty obj but that doesn't mean it is empty, to print the values you can use get() method , kindly refer this official documenation https://developer.mozilla.org/en-US/docs/Web/API/FormData/get.
--EDIT--
As per your postman screenshot you can modify the uploadHandler fn as below
const uploadHandler = (event) => {
const formData=new FormData();
formData.append('grossAmount',grossAmount);
formData.append('taxNumber',taxNumber);
formData.append('dueDate',dueDate);
formData.append('netAmount',netAmount);
formData.append('issueDate',issueDate);
formData.append('issueDate',issueDate);
formData.append('invoice',file);
// now the formData is as per postman screenshot. You can also add all keys to an array and loop it
};
Thanks ,
working fine when i used => Object.fromEntries(formData.entries())
const uploadHandler = (event) => {
const formData=new FormData();
formData.append('grossAmount',grossAmount);
formData.append('taxNumber',taxNumber);
formData.append('dueDate',dueDate);
formData.append('netAmount',netAmount);
formData.append('issueDate',issueDate);
formData.append('issueDate',issueDate);
formData.append('invoice',file);
console.log(Object.fromEntries(formData.entries()))
};
if you send data in api using formData you must remember.
1- if data with text and image you need to use inside header
headers = {
"Content-Type": "multipart/form-data",
};
2- if data only text use
headers = {
"Content-Type": "application/json",
};

Probleme with Reach-hook-form validation on update

I Working with hook-form and MaterialUI, I want to make the validation of the form, the validation working well in adding, but on update (input are ready full) in shows me erros (inputs are empty):
my code:
import Box from "#mui/material/Box";
import Button from "#mui/material/Button";
import Grid from "#mui/material/Grid";
import TextField from "#mui/material/TextField";
import axios from "axios";
import "bootstrap/dist/css/bootstrap.min.css";
import React from "react";
import { useForm } from "react-hook-form";
import { useNavigate, useParams } from "react-router-dom";
function UpdateEmployer(props) {
const { id } = useParams();
const { register, handleSubmit, formState, control } = useForm({
mode: "onChange",
});
// declare states
const [FullName, setFullName] = React.useState("");
const [cin, setCin] = React.useState("");
const [profile, setProfile] = React.useState("");
const [years, setYears] = React.useState("");
const { isSubmitting, errors, isValid } = formState;
const navigate = useNavigate();
// get data from form and post to api
const onSubmit = async (data) => {
// set state from data
const { FullName, cin, profile, years } = data;
console.log(data);
await axios.put(`http://localhost:5000/employers/${id}`, {
fullname: FullName,
cin: cin,
profile: profile,
experience: years,
});
navigate("/");
};
React.useEffect(() => {
axios.get(`http://localhost:5000/employers/${id}`).then((res) => {
setFullName(res.data.fullname);
setCin(res.data.cin);
setProfile(res.data.profile);
setYears(res.data.experience);
});
}, []);
// -------------------- render componenet --------------------
return (
<div className="container mt-4">
<div className="text-center my-3 font-weight-bold">Update Employer</div>
<form onSubmit={handleSubmit(onSubmit)} style={{ width: "100%" }}>
<Grid container spacing={2}>
<Grid item xs={8}>
<TextField
id="FullName"
name="FullName"
label="Full Name"
variant="outlined"
fullWidth
value={FullName}
{...register("FullName", { required: "Please Entre your name" })}
onChange={(e) => setFullName(e.target.value)}
/>
<span className="text-danger">
{errors.FullName && errors.FullName.message}
</span>
</Grid>
<Grid item xs={4}>
<TextField
id="cin"
name="cin"
label="CIN"
variant="outlined"
value={cin}
fullWidth
{...register(
"cin",
{ required: "Please Entre your cin" },
{
minLength: {
value: 6,
message: "Oops! the cin have to ve at least 6 characters",
},
}
)}
onChange={(e) => {
console.log(e.target.value);
setCin(e.target.value);
}}
/>
<span className="text-danger">
{errors.cin && errors.cin.message}
</span>
</Grid>
<Grid item xs={8}>
<TextField
id="profile"
name="profile"
label="Profile"
variant="outlined"
fullWidth
value={profile}
{...register("profile", {
required: "Please Entre your profile",
})}
onChange={(e) => setProfile(e.target.value)}
/>
</Grid>
<Grid item xs={4}>
<TextField
id="years"
name="years"
label="Years of Experience"
variant="outlined"
value={years}
fullWidth
{...register("years", { required: "Please Entre your years" })}
onChange={(e) => setYears(e.target.value)}
/>
</Grid>
<Grid item xs={12}>
<Box textAlign="center">
<Button
id="Update_employer"
variant="contained"
color="primary"
type="submit"
// disabled={!isValid}
>
Update Employee
</Button>
</Box>
</Grid>
</Grid>
</form>
</div>
);
}
export default UpdateEmployer;
The fill he inputs in with useEffect() and it shows me that the input are full with the right information but when I want to submit it shows me that error that the input are empty.

How to send data to Final Form

The nearest example of what I am trying to do is this
https://codesandbox.io/s/3x989zl866?file=/src/index.js
However instead of fields that people fill out, I have 3 buttons with prices: 300,500,1000
When they click on them I need to to set the value in
<TextField
name="campaignAmount"
id="campaignAmount"
component="input"
type="number"
placeholder="Total"
/>
I can set the field but it won't send the value to the final form.
My full code:
import React, { useState } from 'react';
import Wizard from '../wrappers/Wizard'
import { Form, Field } from 'react-final-form'
import ExternalModificationDetector from '../wrappers/ExternalModificationDetector';
import BooleanDecay from '../wrappers/BooleanDecay'
import {
Typography,
Paper,
Grid,
Button,
ButtonGroup,
Box,
CssBaseline,
} from '#material-ui/core';
import DateFnsUtils from '#date-io/date-fns';
import {
TextField,
Radios,
KeyboardDatePicker,
} from 'mui-rff';
const onSubmit = async values => {
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
await sleep(300);
window.alert(JSON.stringify(values, 0, 2));
};
// MAIN FORM AREA
export default function BuildAdStepper(props: MyFormProps) {
// const [selectedDate, handleDateChange] = useState(new Date());
const [txtValue, setTxtValue] = useState({})
const today = new Date();
const dateTimeFormat = new Intl.DateTimeFormat('en', { year: 'numeric', month: '2-digit', day: '2-digit' })
const [{ value: month },,{ value: day },,{ value: year }] = dateTimeFormat.formatToParts(today)
const nmonth = new Date(today.getFullYear(), today.getMonth()+1, day);
const [{ value: nextmonth },,{ value: nextday },,{ value: nextyear }] = dateTimeFormat.formatToParts(nmonth)
function schemaTypeSelectionHandle(event) {
console.log('key: ', event.target.parentNode.value);
setTxtValue(""+event.target.parentNode.value);
// console.log('key: ', event.target.attributes.getNamedItem('data-key').value);
}
const calculator = createDecorator({
field: /day\[\d\]/, // when a field matching this pattern changes...
updates: {
// ...update the total to the result of this function
total: (ignoredValue, allValues) =>
(allValues.day || []).reduce((sum, value) => sum + Number(value || 0), 0)
}
})
return (
<div style={{ padding: 16, margin: 'auto', maxWidth: 600 }}>
<CssBaseline />
<Typography variant="h5" align="center" component="h2" gutterBottom>
Create your campaign
</Typography>
<Paper style={{ padding: 16 }}>
<Form
onSubmit={onSubmit}
decorators={[calculator]}
render={({ handleSubmit, form, submitting, pristine, values }) => (
<Wizard
initialValues={{promoting:"business", startDate:`${day}-${month}-${year }`,endDate:`${nextday}-${nextmonth}-${nextyear }`}}
onSubmit={onSubmit}
>
<Wizard.Page>
<Typography variant="h5">What are you Advertising</Typography>
<Box m={2}/>
<Radios
name="promoting"
formControlProps={{ margin: 'none' }}
radioGroupProps={{ row: true }}
data={[
{ label: 'Business', value: 'business' },
{ label: 'Community Project', value: 'community' },
{ label: 'Event', value: 'event' },
]}
/>
<Box m={2}/>
</Wizard.Page>
<Wizard.Page>
<Typography variant="h5">Name Your Campaign</Typography>
<Box m={2}/>
<TextField
name="campaignName"
margin="none"
fullWidth
variant="outlined"
required={true}
/>
<Box m={2}/>
</Wizard.Page>
<Wizard.Page>
<Typography variant="h5">Set your schedule and budget</Typography>
<Box m={2} />
<KeyboardDatePicker label="Start Date" format="dd-MM-yyyy" name="startDate" dateFunsUtils={DateFnsUtils} required={true} value={new Date()} />
<Box m={2} />
<KeyboardDatePicker label="End Date" format="dd-MM-yyyy" name="endDate" dateFunsUtils={DateFnsUtils} value={new Date(nextyear,nextmonth - 1,nextday)} required={true}/>
<Box m={2} />
<Typography variant="h5">Your budget will be evenly distributed between start and end dates.</Typography>
<Grid container>
<Grid item lg={6}>
<ButtonGroup color="primary" onClick={schemaTypeSelectionHandle.bind(this)} aria-label="outlined primary button group">
<Button value='300'>$300</Button>
<Button value='500'>$500</Button>
<Button value='1000'>$1000</Button>
</ButtonGroup>
</Grid>
<Grid item lg={3}>
<ExternalModificationDetector name="total">
{externallyModified => (
<BooleanDecay value={externallyModified} delay={1000}>
{highlight => (
<TextField
name="campaignAmount"
id="campaignAmount"
component="input"
type="number"
placeholder="Total"
style={{
transition: 'background 500ms ease-in-out',
background: highlight ? 'yellow' : 'none'
}}
/>
)}
</BooleanDecay>
)}
</ExternalModificationDetector>
</Grid>
</Grid>
</Wizard.Page>
</Wizard>
)}
/>
</Paper>
</div>
);
}
I have uploaded the code to codesandbox.io
But can't seem to run it.
https://codesandbox.io/s/keen-architecture-iu02l?file=/src/core/pages/BuildAd.js
If you want to set the field value using multiple buttons, you can do the following:
Add an artificial field calling, say, budget:
<Field
name="budget"
render={({ input }) => (
<button
onClick={() => input.onChange(500)}
type="button"
>
500
</button>
)}
/>
This field renders a button, which has an onClick handler that calls the field's onChange method and sets the appropriate value.
Then, if you duplicate this field like following:
<Field name="budget" render={({ input }) => (
<button onClick={() => input.onChange(500)} type="button">500</button>)}
/>
<Field name="budget" render={({ input }) => (
<button onClick={() => input.onChange(1000)} type="button">1000</button>)}
/>
<Field name="budget" render={({ input }) => (
<button onClick={() => input.onChange(10000)} type="button">10000</button>)}
/>
you would have three buttons that update the budget to 500, 1000 and 10000 accordingly.
Since you have this value in the form state, you can copy it to the campaignAmount field using a final-form-calculate decorator:
const calculator = createDecorator({
field: "budget",
updates: {
total: (_, allValues) => allValues.budget
}
});
Here is a complete codesandbox: https://codesandbox.io/s/httpsstackoverflowcomquestions63323056how-to-send-data-to-final-form-ssoz3?file=/index.js.

React - Material-UI - How to use Select with multiple values inside react-hook-form

I am trying to use UI-Material Select with multiple options inside react-hook-form without success.
I had this working before trying to do it with multiple options
<form onSubmit={handleSubmit(onSubmit)}>
<Row className="mb-2">
<Col sm={6}>
<FormControl className="select-language">
<InputLabel> {t('Languages')}</InputLabel>
<Controller
as={
<Select>
{Config.languages.map(m => <MenuItem key={m.code} value={m.text}> {t(m.text)} </MenuItem>)}
</Select>
}
defaultValue={user.language}
name="language"
control={control}
>
</Controller>
</FormControl>
</Col>
</Row>
</form>
I tried to add multiple to the Select element which lead me to another error.
I tried also to keep only the Select element without the Controller wrapper, but then I can't get the language value in onSubmit
Very simple codeSandBox that shows that I can't get value from Select when submitting the form: https://codesandbox.io/s/react-hook-form-example-s7h5p?file=/src/index.js
I would appreciate any help
Thanks
If anyone looking for a easy solution, this might come in handy. Multiple select options become very easy now with Select Component. If you look at the Select component, you just have to set the default value to an array and pass the "multiple" prop.
import {
Button,
FormControl,
InputLabel,
MenuItem,
Select
} from "#mui/material";
import { Controller, useForm } from "react-hook-form";
const FCWidth = {
width: "20rem"
};
export default function App() {
const { control, handleSubmit } = useForm();
const formSubmitHandler = (formData) => {
console.log(formData);
};
const ages = ["10", "20", "30"];
return (
<div className="App">
<form onSubmit={handleSubmit(formSubmitHandler)}>
<Controller
name="age"
control={control}
type="text"
defaultValue={[]}
render={({ field }) => (
<FormControl sx={FCWidth}>
<InputLabel id="age">Age</InputLabel>
<Select
{...field}
labelId="age"
label="age"
multiple
defaultValue={[]}
>
{ages.map((age) => (
<MenuItem value={age} key={age}>
{age}
</MenuItem>
))}
</Select>
</FormControl>
)}
/>
<FormControl sx={FCWidth}>
<Button
type="submit"
variant="contained"
fullWidth
sx={{ marginTop: ".75rem", fontWeight: "bold" }}
>
Submit
</Button>
</FormControl>
</form>
</div>
);
}
Here is the code sandbox link https://codesandbox.io/s/select-multiple-option-with-mui-and-react-hook-form-2kv2o
I know that this old but someone may need it later, maybe this one would work for you,
just check the render Controller props
import React from "react";
import {
TextField,
ListItemText,
Checkbox,
MenuItem,
makeStyles
} from "#material-ui/core";
import { useForm, Controller } from "react-hook-form";
const useStyles = makeStyles({
root: {
width: "200px"
},
center: {
textAlign: "center"
}
});
export default function SelectTextField() {
const classes = useStyles();
const { handleSubmit, control } = useForm();
const nums = [1, 2, 3, 4];
const onSubmit = (e) => {
console.log(e);
};
return (
<form className={classes.center} onSubmit={handleSubmit(onSubmit)}>
<Controller
control={control}
name="selectedNumbers"
defaultValue={[]}
render={({ onChange, value }) => {
console.log(value);
return (
<TextField
classes={{ root: classes.root }}
select
id="Numbers"
variant="outlined"
label="Numbers"
SelectProps={{
multiple: true,
value: value,
renderValue: (selected) => selected.join(", "),
onChange: onChange
}}
>
{nums.map((n) => (
<MenuItem key={n} value={n}>
<Checkbox checked={value.includes(n)} />
<ListItemText primary={n} />
</MenuItem>
))}
</TextField>
);
}}
/>
<div>
<button type="submit">Submit</button>
</div>
</form>
);
}
also, you can and play with it here
https://codesandbox.io/s/multi-select-input-u0cr3?file=/demo.js
also can check this on the docs
https://react-hook-form.com/get-started#ReactNative
First of all, i think your version is on v3, so you may want to upgrade:
https://codesandbox.io/s/react-hook-form-example-5lrij?file=/src/index.js
import React from "react";
import ReactDOM from "react-dom";
import { useForm, Controller } from "react-hook-form";
import { Select, MenuItem } from "#material-ui/core";
import "./styles.css";
const languages = [
{
code: "en-US",
text: "English"
},
{
code: "zu",
text: "Another Language"
}
];
export default function App() {
const { register, handleSubmit, control } = useForm();
const onSubmit = data => console.log(data);
return (
<div className="container">
<div className="col-sm-12">
<h3>Client Profile</h3>
</div>
<div className="col-sm-12">
<form onSubmit={handleSubmit(onSubmit)}>
<div className="form-group">
<input
className="form-control"
type="text"
placeholder="Name"
name="Name"
ref={register}
/>
</div>
<div className="form-group">
<Controller
name="Language"
control={control}
as={
<Select>
{languages.map(m => (
<MenuItem key={m.code} value={m.text}>
{" "}
{m.text}{" "}
</MenuItem>
))}
</Select>
}
defaultValue={languages[0].text}
/>
</div>
<div className="form-group">
<input className="btn btn-primary" type="submit" />
</div>
</form>
</div>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
here is the fixed version by using Controller

How to InputRef works in material ui core 3.9.2

In Material ui core 3.9.2
On inputRef={input => {
this.input = input;
}}
Error Shows
TypeError: Cannot set property 'input' of undefined
If we use this.email instead of this.input
Then Error Shows
TypeError: Cannot set property 'email' of undefined
This is TextField Code
<TextField
id="login-email"
label="Email/MobileNo"
required
fullWidth
type="email"
className={classes.textField}
inputRef={el => {
this.input = el;
}}
or
inputRef={el => this.email = el;}
margin="normal"
/>
Here is solution for functional component.
import React, { useRef, Component } from 'react'
import { TextField, Button } from '#material-ui/core'
import SendIcon from '#material-ui/icons/Send'
export default function MultilineTextFields() {
const valueRef = useRef('') //creating a refernce for TextField Component
const sendValue = () => {
return console.log(valueRef.current.value) //on clicking button accesing current value of TextField and outputing it to console
}
return (
<form noValidate autoComplete='off'>
<div>
<TextField
id='outlined-textarea'
label='Content'
placeholder='Write your thoughts'
multiline
variant='outlined'
rows={20}
inputRef={valueRef} //connecting inputRef property of TextField to the valueRef
/>
<Button
variant='contained'
color='primary'
size='small'
endIcon={<SendIcon />}
onClick={sendValue}
>
Send
</Button>
</div>
</form>
)
}
It was this issue
I solve it by changing
From:
import { makeStyles } from '#material-ui/styles';
import { Link } from "react-router-dom";
import TextField from '#material-ui/core/TextField';
import { Button, Grid } from '#material-ui/core';
import { red } from '#material-ui/core/colors';
const useStyles = makeStyles({
container: {
background: red,
},
});
export default function Hook() {
const classes = useStyles();
const [values, setValues] = React.useState({
email: '',
password: '',
});
const handleChange = name => event => {
setValues({ ...values, [name]: event.target.value });
};
const handleSubmit = event => {
event.preventDefault();
// alert(this.password);
console.log("event ", event);
// console.log("E ",this.email)
// console.log("p ",this.password)
// console.log(this.email.value)
// console.log(this.password.value)
};
return <form className={classes.container} validate="true" onSubmit={handleSubmit} autoComplete="off">
<TextField
id="login-email"
label="Email/MobileNo"
required
fullWidth
type="email"
inputRef={el => this.email = el}
onChange={handleChange('email')}
margin="normal"
/>
<TextField
id="login-password"
label="Password"
required
fullWidth
type="password"
inputRef={el => this.password = el}
onChange={handleChange('password')}
margin="normal"
/>
<Grid container className="m-y-20" justify="center">
<Grid item md={5}>
<Button className="login-submit-btn" type="submit">Login</Button>
<Link className="t-d-none" to="/">
<Button className="login-new-btn">Create New Account</Button>
</Link>
</Grid>
<Grid item md={7}>
<span className="p-x-15">
<Link to="/forgopassword" className="black-clr">
Forgot Your Password?
</Link>
</span>
</Grid>
</Grid>
</form>
}
To:
import React from 'react';
import { Link } from "react-router-dom";
import TextField from '#material-ui/core/TextField';
import { Button, Grid } from '#material-ui/core';
class LoginForm extends React.Component {
render() {
const handleSubmit = event => {
event.preventDefault();
// alert(this.password);
console.log("event ", event);
// console.log("E ",this.email)
// console.log("p ",this.password)
console.log(this.email.value)
console.log(this.password.value)
};
return <form validate="true" onSubmit={handleSubmit} autoComplete="off">
<TextField
id="login-email"
label="Email/MobileNo"
required
fullWidth
type="email"
inputRef={el => this.email = el}
margin="normal"
/>
<TextField
id="login-password"
label="Password"
required
fullWidth
type="password"
inputRef={el => this.password = el}
margin="normal"
/>
<Grid container className="m-y-20" justify="center">
<Grid item md={5}>
<Button className="login-submit-btn" type="submit">Login</Button>
<Link className="t-d-none" to="/">
<Button className="login-new-btn">Create New Account</Button>
</Link>
</Grid>
<Grid item md={7}>
<span className="p-x-15">
<Link to="/forgopassword" className="black-clr">
Forgot Your Password?
</Link>
</span>
</Grid>
</Grid>
</form>
}
}
export default LoginForm;
try
<TextField
id="login-email"
label="Email/MobileNo"
required
fullWidth
type="email"
className={classes.textField}
inputRef={input => this.input = input}
margin="normal"
/>
with this you are returning nothing
inputRef={input => {
this.input = input;
}}

Resources