Disable input field when click edit button using React Hooks - javascript

I don't understand what I'm doing wrong in here.
The scenario is that I am on the user profile details and I want to edit the information but one input must be disable at all the time.
When I'm loading the page the input it is actually disabled but as soon as I click the edit button it is becoming editable like the rest of the other input.
Any suggestion on how to make it works, please?
const [disabled, setDisabled] = useState(false);
const handleClickEditMember = () => {
Actions.enableMemberEdit();
setDisabled(!disabled);
};
<Card className={clsx(classes.root, className)}>
<CardHeader
action={
<Button
color="primary"
id="edit-member-button"
onClick={() => handleClickEditMember()}
size="small"
variant="contained"
>
{t('members.edit')}
</Button>
}
title={member.companyName}
/>
<Divider />
<CardContent className={classes.content}>
<CardHeader title={t('members.company_profile')} />
<Grid container spacing={3}>
<Grid item xs={6}>
<TextField
className={classes.textField}
fullWidth
id="companyName"
InputProps={{
readOnly: true,
}}
label={t('members.company_name')}
margin="dense"
name="companyName"
placeholder={t('members.company_name')}
value={member.companyName}
variant="outlined"
/>
</Grid>
<Grid item xs={3}>
<TextField
className={classes.textField}
fullWidth
id="Id"
InputProps={{
readOnly: true,
}}
disabled={!disabled}
label={t('members.id')}
margin="dense"
name="Id"
placeholder={t('members.id')}
value={member.id}
variant="outlined"
/>
</Grid>
</Grid>

You're updating the state everytime in the handleClickEditMember() by doing setDisabled(!disabled); which will eventually set to true as its false initially.
So you'll have to
Remove that piece of code and the state update won't be triggered again!
And For the ID input field just use disabled={disabled}

<TextField
className={classes.textField}
fullWidth
id="Id"
InputProps={{
readOnly: true,
}}
**disabled**
label={t('members.id')}
margin="dense"
name="Id"
placeholder={t('members.id')}
value={member.id}
variant="outlined"
/>
Just disable the textfield. Don't assign any value to disabled property

Just resolved by doing this:
InputProps={{
readOnly: memberId ? true : false,
}}

Related

Adding a button on other webpages causing the common buttons in navbar to change

Hello I am facing a odd issue with the button.Whenever I insert a button from MUI , it just disrupts the common buttons in the Navbar that are present on every pages. Here is my signup page.Also I had a drop down menu(earlier but I got rid of and now have them as buttons instead on the navbar) that was common on all pages as well and adding a button anywhere would basically cause the menus to appear in disorientation.The buttons in Navbar are in a different page
Here is what my signup page looks like.
import { Grid,Paper, Avatar, TextField, Button, Typography,Link } from '#material-ui/core'
const Signup=()=>{
const stylePaper={padding :'20px', height:'80vh',maxWidth: 400, marginLeft:500}
const btnstyle={margin:'20px 0' }
return(
<Grid>
<Paper elevation={10} style={stylePaper}>
<Grid align='center'>
<Avatar src = "/Login logo.png"/>
<h2>Sign Up</h2>
</Grid>
<Grid container spacing={7}>
<Grid item xs = {6}>
<TextField label='First Name' placeholder='Enter first name' variant='outlined' fullWidth />
</Grid>
<Grid item xs = {6}>
<TextField label='Last Name' placeholder='Enter last name' variant='outlined' fullWidth />
</Grid>
</Grid>
<Grid container spacing = {3}>
<Grid item xs = {5}>
<TextField label='SSN' placeholder='Enter SSN' variant='outlined' />
</Grid>
<Grid item xs ={7}>
<TextField label='Address' placeholder='Enter address' variant='outlined' />
</Grid>
</Grid>
<TextField label='Email' placeholder='Enter email' fullWidth required/>
<TextField label='Password' placeholder='Enter password' type='password' fullWidth required />
<Grid item>
<TextField label='Password' placeholder='Enter password' type='password' fullWidth required />
<Button type='submit' color='primary' variant="contained">Create Account</Button>
</Grid>
<Typography >
<Link href="#" >
Forgot password ?
</Link>
</Typography>
<Typography > Have an account already?
<Link href="Login" >
Log in
</Link>
</Typography>
</Paper>
</Grid>
)
}
export default Signup

How to Add input fields in form when "Other" option is selected in dropdown in React.js

I have a multi select dropdown input and I am saving all the selected items in an (useState) array when user click add icon.
I want to render input field when "Other" option is selected in dropdown.
and also want that the value entered in other should be added in the array.
handle change :-
const handleCareerChoice = (event) => {
setValues({ ...values, careerChoice: event.target.value });
};
const handleChange = (input) => (event) => {
setValues({ ...values, error: false, [input]:event.target.value});
};
const [otherState, setOtherState] = useState(false);
dropdown
<Grid container className={classes.grid} style={{ marginBottom: "10px" }}>
<Grid item xs={11} sm={5} lg={11} sx={{ m: 1 }}>
<FormControl variant="outlined" fullWidth sx={{ mt: 1 }}>
<InputLabel id="demo-mutiple-checkbox-label">
Top Career Choice
</InputLabel>
<Select
label="Top Career Choice"
id="demo-mutiple-checkbox"
multiple
value={values.careerChoice}
onChange={handleChange("careerChoice")}
renderValue={(selected) => selected.join(", ")}
>
<TextField variant="outlined" style={{ width: "100%" }} />
{careerChoice.map((name) => (
<MenuItem key={name} value={name}>
<Checkbox checked={values.careerChoice.indexOf(name) > -1} />
<ListItemText primary={name} />
</MenuItem>
))}
<MenuItem >
<Checkbox onClick={setOtherCareerChoice(!otherCareerChoice)} />
<ListItemText primary={"Others"} />
</MenuItem>
</Select>
</FormControl>
</Grid>
{ otherCareerChoice && (
<Grid item xs={11} sm={5} lg={11} sx={{ m: 1 }}>
<FormControl variant="outlined" fullWidth sx={{ mt: 1 }}>
<InputLabel htmlFor="outlined-adornment-password">
Other Career Choice
</InputLabel>
<OutlinedInput
id="careerChoice"
name="careerChoice"
label="Additional Career Choice"
fullWidth
autoComplete="careerChoice"
// value={values.careerChoice}
onChange={handleCareerChoice}
endAdornment={
<InputAdornment position="end">
<IconButton
edge="end"
>
<Add/>
</IconButton>
</InputAdornment>
}
/>
</FormControl>
</Grid>
)}
currently, input is looking like
this but on clicking other text field, I see a blank screen with error
TypeError: selected.join is not a function
Please suggest me a good approach to do this
Here's a codesandbox for the full code
First you want to render the "Other Career Text" input box when it is selected from the dropdown. For that, add an onClick for Others in the dropdown
<MenuItem onClick={() => setOtherCareerChoice(!otherCareerChoice)}>
<Checkbox />
<ListItemText primary={"Others"} />
</MenuItem>
Now that the input field is rendered, at a value and onChange attribute to let the user type a text
<OutlinedInput
value={otherCareerText}
onChange={(event) => setOtherCareerText(event.target.value)}
Finally when the user clicks the "+" button, push this text to your state in an onClick
<IconButton
onClick={() => {
setValues({
...values,
careerChoice: [...values.careerChoice, otherCareerText]
});
setOtherCareerChoice(false);
setOtherCareerText("");
}}
>

React+JavaScript How to create an object in React with all the given fields

I have the following Sign-up page and I console log each time in the function called 'sign' once the Sign Up button is clicked. While each field is individually visible in the console, I need to make them appear as one object. Any help is appreciated, here is my code for the react function SignUp:
export default function SignUp() {
const [firstName, setFirstName] = React.useState("");
const [email, setEmail] = React.useState("");
const [password, setPassword] = React.useState("");
let sign = (event) => {
event.preventDefault();
console.log(firstName);
};
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign up
</Typography>
<form className={classes.form} noValidate>
<Grid container spacing={2}>
<Grid item xs={12} sm={6}>
<TextField
autoComplete="fname"
name="firstName"
variant="outlined"
required
fullWidth
id="firstName"
label="First Name"
autoFocus
onChange={(event) => setFirstName(event.target.value)}
/>
</Grid>
<Grid item xs={12}>
<TextField
variant="outlined"
required
fullWidth
id="email"
label="Email Address"
name="email"
autoComplete="email"
onChange={(event) => setEmail(event.target.value)}
/>
</Grid>
<Grid item xs={12}>
<TextField
variant="outlined"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="current-password"
onChange={(event) => setPassword(event.target.value)}
/>
</Grid>
</Grid>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
onClick={sign}
>
Sign Up
</Button>
You can use useReducer to create a state object of your component like this:
import React, { useReducer } from 'react'
const initialState = {
firstName: '',
email: '',
password: '',
}
const reducer = (state = initialState, action) => {
switch (action.type) {
case 'SET_FIRSTNAME':
return { ...state, firstName: action.payload }
case 'SET_EMAIL':
return { ...state, email: action.payload }
case 'SET_PASSWORD':
return { ...state, password: action.payload }
default:
return state
}
}
export default function SignUp() {
const [state, dispatch] = useReducer(reducer, initialState)
let sign = (event) => {
event.preventDefault();
console.log(state);
};
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign up
</Typography>
<form className={classes.form} noValidate>
<Grid container spacing={2}>
<Grid item xs={12} sm={6}>
<TextField
autoComplete="fname"
name="firstName"
variant="outlined"
required
fullWidth
id="firstName"
label="First Name"
autoFocus
onChange={(event) => dispatch({ type: 'SET_FIRSTNAME', payload: event.target.value })}
/>
</Grid>
<Grid item xs={12}>
<TextField
variant="outlined"
required
fullWidth
id="email"
label="Email Address"
name="email"
autoComplete="email"
onChange={(event) => dispatch({ type: 'SET_EMAIL', payload: event.target.value })}
/>
</Grid>
<Grid item xs={12}>
<TextField
variant="outlined"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="current-password"
onChange={(event) => dispatch({ type: 'SET_PASSWORD', payload: event.target.value })}
/>
</Grid>
</Grid>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
onClick={sign}
>
Sign Up
</Button>
You can do something like this :
console.log({ firstName , email , password });

ReactJS and Material UI CheckBox State Change

Im using Material UI Checkbox to create a form that takes input and then in theory adds the new values or updates the values into a state object. This form is used for both editing a holiday or creating a new holiday.
I'm struggling with finding why my state isnt being updated upon clicking on a checkbox or typing in an input box. The checkbox wont change to checked/unchecked and the input wont remvoe the value when i use backspace to remove characters or enter new characters.
Dialog Box:
HolidayData:
{
"id": 1,
"ID": 1,
"HolidayName": "New Year's Day",
"HolidayDate": "05/20/2020",
"Branch": null,
"Hours": null,
"Web": true,
"Phone": true,
"CoOp": false,
"Active": true,
"Submitted": null,
"SubmittedBy": null,
"Published": "05/20/2020",
"PublishedBy": "John.Doe"
}
DialogBox Code:
const HolidayDialog = (props) => {
const [noticeModal, setNoticeModal] = React.useState(false);
const [selectedDate, setSelectedDate] = React.useState(new Date());
const [holidayData, setHolidayData] = React.useState(props.data);
useEffect(() => {
setHolidayData(props.data);
setNoticeModal(props.open)
});
const handleDateChange = (date) => {
setSelectedDate(date);
};
const handleClose = () => {
setNoticeModal(false);
};
const handleChange = (e) => {
const { name, checked } = e.target;
setHolidayData((prevState) => ({ ...prevState, [name]: checked }));
};
const updateValues = (e) => {
const { name, value } = e.target;
setHolidayData((prevState) => ({ ...prevState, [name]: value }));
};
return (
<Dialog
open={noticeModal}
TransitionComponent={Transition}
keepMounted
onClose={handleClose}
aria-labelledby="notice-modal-slide-title"
aria-describedby="notice-modal-slide-description"
>
<DialogTitle id="customized-dialog-title" onClose={handleClose}>
{holidayData.HolidayName ? holidayData.HolidayName : 'Create New Holiday'}
</DialogTitle>
<DialogContent dividers>
<form noValidate autoComplete="off">
<div className="row">
<div className="col">
<TextField required name="HolidayName" id="outlined-basic" label="Holiday Name" variant="outlined" onChange={updateValues} value={holidayData.HolidayName ? holidayData.HolidayName : ''}/>
</div>
<div className="col">
<TextField id="outlined-basic" label="Branch" variant="outlined" onChange={updateValues} value={holidayData.Branch ? holidayData.Branch : 'ALL'}/>
</div>
</div>
<div className="row mt-3">
<div className="col">
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<KeyboardDatePicker
disableToolbar
variant="inline"
format="MM/dd/yyyy"
margin="normal"
id="date-picker-inline"
label="Date picker inline"
value={selectedDate}
onChange={handleDateChange}
KeyboardButtonProps={{
'aria-label': 'change date',
}}
/>
</MuiPickersUtilsProvider>
</div>
<div className="col">
<TextField id="outlined-basic" label="Hours" variant="outlined" onChange={updateValues} value={holidayData.Hours ? holidayData.Hours : 'Closed'}/>
</div>
</div>
<div className="row mt-3">
<div className="col d-flex flex-column">
<FormControlLabel
control={
<Checkbox
checked={holidayData.Web ? holidayData.Web : false}
onChange={handleChange}
name="Web"
color="primary"
/>
}
label="Show on Web?"
/>
<FormControlLabel
control={
<Checkbox
checked={holidayData.CoOp ? holidayData.CoOp : false}
onChange={handleChange}
name="CoOp"
color="primary"
/>
}
label="CoOp Holiday?"
/>
</div>
<div className="col d-flex flex-column">
<FormControlLabel
control={
<Checkbox
checked={holidayData.Phone ? holidayData.Phone : false}
onChange={handleChange}
name="Phone"
color="primary"
/>
}
label="Use in IVR?"
/>
<FormControlLabel
control={
<Checkbox
checked={holidayData.Active ? holidayData.Active : false}
onChange={handleChange}
disabled
name="active"
color="primary"
/>
}
label="Active"
/>
</div>
</div>
</form>
</DialogContent>
<DialogActions>
<Button autoFocus onClick={handleClose} color="default">
Cancel
</Button>
<Button autoFocus onClick={handleClose} color="primary">
Create Holiday
</Button>
</DialogActions>
</Dialog>
)
}
When i check a box or try to edit an input the handleChange and updateValues are firing. I believe it may be a syntax issue, but i cant seem to find anything. When console.log'ing event.target.name i get the correct name: Web for example
EDIT: The issue appears to be with the value and checked being equal to {holidayData.Phone ? holidayData.Phone : false} or the sorts. However if i bring the values down to {holidayData.Phone} itll start to throw errors:
A component is changing an uncontrolled input of type checkbox to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa).
It'll now allow me to check a checkbox but only once and throws this error over and over again and im not sure why or how to correct this?
Most probably the useEffect is causing the issue. You're resetting the data each time the component gets updated. You don't need that if you're already doing that with useState.
Check my example here with only the textbox: https://codesandbox.io/s/fancy-shape-14r63?file=/src/App.js
If you uncomment the useEffect, it stops working.

Force a disabled MI TextField to be clickable

I have a TextField that is disabled and I'm updating it with React Hooks useState by changing the value property of the TextField.
const [employee , setEmployee] = React.useState('')
<TextField
fullWidth
disabled
value={employee}
variant="outlined"
InputProps={{
startAdornment: (
<InputAdornment position="start">
<BackupIcon onClick={handleClick}/>
</InputAdornment>
),
}}
/>
It's only clickable on the Icon BackupIcon.
How can we make it clickable all over the TextField ?
Have you tried putting the onClick like this:
handleClick: function(e) {
this.setState({
textFieldValue: e.target.value
});
},
<TextField fullWidth
disabled
value={employee}
variant="outlined"
onChange={handleClick}
>
<BackupIcon />
<TextField />

Categories