How to edit a row in Material UI Table? - javascript

I trying to make a crud table using material UI,but as my first react project I have some issues.I don't know how to make the edit.I take the data to the edit-modal but I don't know how to make the update in the table.
export default function ResponsiveDialog({dataParent1,dataParent2}) {
const [open, setOpen] = React.useState(false);
const theme = useTheme();
const fullScreen = useMediaQuery(theme.breakpoints.down('md'));
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
return (
<div>
<Button variant="outlined" color='success' onClick={handleClickOpen}>
Edit
</Button>
<Dialog
fullScreen={fullScreen}
open={open}
onClose={handleClose}
aria-labelledby="responsive-dialog-title"
>
<DialogTitle id="responsive-dialog-title">{"Edit Post"}
</DialogTitle>
<DialogContent>
<Divider variant="middle"/>
<DialogContentText>
Title
</DialogContentText>
<TextField id="outlined-basic" defaultValue={dataParent1} style = {{width: 500}} variant="outlined" />
<DialogContentText>
Description
</DialogContentText>
<TextField id="outlined-basic" multiline rows={4} defaultValue={dataParent2} style = {{width: 500}} variant="outlined" />
</DialogContent>
<DialogActions>
<Button autoFocus variant="outlined" color='error' onClick={handleClose}>
Exit
</Button>
<Button color='success' variant="outlined" onClick={handleClose} autoFocus>
Save Changes
</Button>
</DialogActions>
</Dialog>
</div>
);}
Codesandbox:
https://codesandbox.io/s/angry-panka-7wd7ye?file=/src/App.js

Related

React native invariant violation: text strings must be rendered within a <Text> component in a form (TextField)

This is my code for a form in React Native which is where i seem to be getting the error. I'm confused as this renders perfectly fine in my web simulator (expo):
working form but I get this error when I use ios simulator. I don't have any conditional logic or spaces/semicolons(at least what i can find) so not sure why I'm getting this error, also i'm using material ui core for my text fields in my form (which is where the error is supposedly coming from if you ref the image above). Any help would be appreciated!! pls help
import React, { useRef, useState } from 'react'
import { StyleSheet, View, Text, Modal } from 'react-native';
import { Formik, Form, FieldArray } from 'formik';
import { makeStyles } from '#material-ui/core/styles';
import { Button, TextField } from "#material-ui/core";
import { recipeService } from '../services/RecipeService';
const useStyles = makeStyles((theme) => ({
root: {
display: 'flex',
flexWrap: 'wrap',
},
textField: {
marginLeft: theme.spacing(1),
marginRight: theme.spacing(1),
marginTop: theme.spacing(1),
},
}));
export default function NewRecipe({ route }) {
const [showAlert, setShowAlert] = useState(false);
const { userId } = route.params;
const instructions = [''];
const ingredients = [{ name: '', amount: '', optional: false }];
const classes = useStyles();
const input = useRef();
return (
<View style={styles.container}>
<Formik
initialValues={{ userId: userId, name: "", summary: "", instructions: instructions, ingredients: ingredients }}
onSubmit={(values, actions) => {
recipeService.createRecipe(values).then(
(response) => {
console.log(response);
setShowAlert(true);
console.log("alert = " + showAlert);
actions.resetForm({});
return (
<Modal
animationType="slide"
transparent={false}
visible={true}
onRequestClose={
() => { setShowAlert(false); }
}>
<View style={styles.modalView}>
<Text>Recipe saved!</Text>
<Button
margin="normal"
type="button"
variant="contained"
color="default"
className={classes.textField}
onClick={() => actions.resetForm({})}
>
New Recipe
</Button>
</View>
</Modal>
)
}
)
.catch((error) => {
console.log(error);
});
}
}
>{({ values, handleChange, handleBlur }) => (
<Form>
<TextField
fullWidth
variant="outlined"
id="name"
name="name"
label="Name"
value={values.name}
onChange={handleChange}
/>
<TextField
fullWidth
multiline
variant="outlined"
id="summary"
name="summary"
label="Summary"
className={classes.textField}
value={values.summary}
onChange={handleChange}
/>
<View style={styles.row}>
<FieldArray
name="ingredients"
render={arrayHelpers => (
<div>
{values.ingredients.map((item, index) => (
<div key={index}>
<TextField
variant="outlined"
label="Ingredient Name"
name={`ingredients.${index}.name`}
value={item.name}
margin="normal"
className={classes.textField}
onChange={handleChange}
style={{ margin: 8, width: 233 }}
onBlur={handleBlur}
/>
<TextField
variant="outlined"
label="Amount"
name={`ingredients.${index}.amount`}
value={item.amount}
margin="normal"
className={classes.textField}
onChange={handleChange}
style={{ margin: 8, width: 100 }}
onBlur={handleBlur}
/>
<Button
margin="normal"
type="button"
color="secondary"
variant="outlined"
margin="dense"
style={{ margin: 8, width: 30 }}
className={classes.textField}
onClick={() => arrayHelpers.remove(index)}
> x
</Button>
<Button
margin="normal"
type="button"
variant="contained"
color="default"
className={classes.textField}
onClick={() => arrayHelpers.push({ name: '', amount: '', optional: false })}
>Add
</Button>
</div>
))}
</div>
)}
/>
</View>
<FieldArray
name="instructions"
render={arrayHelpers => (
<div>
{values.instructions.map((item, index) => (
<div key={index}>
<TextField
variant="outlined"
label="Instruction"
name={`instructions.${index}`}
value={item}
margin="normal"
className={classes.textField}
onChange={handleChange}
style={{ margin: 8, width: 350 }}
onBlur={handleBlur}
/>
<Button
margin="normal"
type="button"
color="secondary"
variant="outlined"
margin="dense"
style={{ margin: 8, width: 30 }}
className={classes.textField}
onClick={() => arrayHelpers.remove(index)}
> x
</Button>
</div>
))}
<Button
margin="normal"
type="button"
variant="contained"
color="default"
className={classes.textField}
onClick={() => arrayHelpers.push('')}
>Add
</Button>
</div>
)}
/>
<div>
<Button color="primary" variant="contained" className={classes.textField} fullWidth type="submit">
Submit
</Button>
</div>
</Form>
)}
</Formik>
You cannot use #material-ui/core for React Native projects.
#material-ui/core can work for expo because it's web based. But I'm pretty sure that it won't work for native environments.
I'd like to recommend alternatives, but I don't use material design for React Native because it simply doesn't fit to iOS.

how to open modal2 from a button of modal1 in react

I have two modals one is Login modal and another is Signup modal now I want to open signup modal by clicking on a button which is present in login modal, I tried many different ways but not able to achieve it, also I tried to make a signupModalSwitch with useReducer and by making different function calls but it was saying against hooks rule, I am very new to react not able to figure out how to do it. Thanks in Advance :)
modal1 ->
function LoginModal() {
const [open, setOpen] = React.useState(false);
const handleOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
return (
<div>
<Button
onClick={handleOpen}
variant="outlined"
className={classNames(
classes.textNeonGreen,
classes.outlinedNeonGreen,
classes.navButton
)}
classes={{ disabled: classes.disabled }}
>
<Typography noWrap>Login</Typography>
</Button>
<Modal
className={classes.modal}
open={open}
onClose={handleClose}
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500,
}}
>
<Fade in={open}>
<LoginCard LoginClose={handleClose} />
</Fade>
</Modal>
</div>
);
}
function LoginCard({ LoginClose }) {
return (
<Card className={classes.modalCard}>
<span>
<button
onClick={LoginClose}
type="button"
className="close px-2 pt-2"
aria-label="Close"
>
<span aria-hidden="true">×</span>
</button>
</span>
<CardContent className={classes.modalCardContent}>
<Typography variant="h4" className={classes.modalHeading}>
<b>Login</b>
</Typography>
<Account>
<Login />
</Account>
<div>
<Grid
container
direction="column"
justify="center"
alignItems="center"
>
<p className="mb-2 mt-4 text-center">
Don't have Account?
</p>
//###### BY CLICKING THIS BUTTON I WANT TO OPEN MY SIGNUP MODAL #######//
<button
className="btn btn-outline-success btn-block btn-md"
onClick={() => {
LoginClose();
signupModalSwitch(null,{type:'open'})
}
}
>
Signup
</button>
</Grid>
</div>
</CardContent>
</Card>
);
}
MODAL2 ->
function signupModalSwitch(state, action){
switch(action.type){
case 'open':
return { open: true }
case 'close':
return { open: false }
default:
console.log(action);
}
}
function SignupModal() {
const classes = useStyles();
const [state, dispatch] = useReducer(signupModalSwitch, { open: false })
function handleOpen() {
dispatch({type: "open"});
}
function handleClose() {
dispatch({type: "close"});
};
return (
<div>
<Button
onClick={handleOpen}
variant="outlined"
className={classNames(
classes.textNeonGreen,
classes.outlinedNeonGreen,
classes.navButton
)}
classes={{ disabled: classes.disabled }}
>
<Typography noWrap>Signup</Typography>
</Button>
<Modal
className={classes.modal}
open={state.open}
onClose={handleClose}
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500,
}}
>
<Fade in={state.open}>
<SignupCard signupClose={handleClose} />
</Fade>
</Modal>
</div>
);
}
function SignupCard({ signupClose }) {
return (
<Card className={classes.modalCard}>
<span>
<button
onClick={signupClose}
type="button"
className="close px-2 pt-2"
aria-label="Close"
>
<span aria-hidden="true">×</span>
</button>
</span>
<CardContent className={classes.modalCardContent}>
<Typography variant="h4" className={classes.modalHeading}>
<b>Signup</b>
</Typography>
<Signup />
</CardContent>
</Card>
);
}
A better way to do this would be to create a container and move all the logic to the container. Your login and sign up modals should be dumb components, i.e, do not maintain the state in these components.
In your container, keep two states, openLoginModal and openSignupModal.
const [openLoginModal, setOpenLoginModal] = useState(false)
const [openSignupModal, setOpenSignupModal] = useState(false)
You can pass these as props to your login and signup components. When you click the button in the login modal, you will need one more function that closes login modal and opens sign up modal. You can pass this as prop as well.
const onSignupButtonClick = () => {
setOpenLoginModal(false)
setOpenSignupModal(true)
}
You can conditionally render login and signup modal based on the state values.

React - Material-UI radio button group won't fill button on click

I'm building an app in React using Material-UI components. In one window there are four true/false choices represented by radio buttons. On render the window renders as expected, but clicking on a non-default value only causes the default radio button to lose its fill, and does not fill the clicked-on choice.
Example: if User can mint defaults to false, then false will be filled on render, but clicking true for that option won't fill true (though false will become 'unfilled').
The actual state does change, though. So this seems to only be a render problem, not an underlying problem with the state.
Here's the code (I'll try to take out the unnecessary parts):
const UpdateDefaultRole = props => {
const [open, setOpen] = React.useState(false);
const [canMint, setCanMint] = React.useState(false);
const [canBurn, setCanBurn] = React.useState(false);
const [payFee, setPayFee] = React.useState(true);
const [paySplit, setPaySplit] = React.useState(true);
const handleMintChange = e => setCanMint(e.target.value);
const handleBurnChange = e => setCanBurn(e.target.value)
const handleFeeChange = e => setPayFee(e.target.value)
const handleSplitChange = e => setPaySplit(e.target.value)
return (
<div>
<Button variant="outlined" color="primary" onClick={handleClickOpen}>
Update Default Role
</Button>
<Dialog open={open} onClose={handleClose} aria-labelledby="form-dialog-title">
<DialogTitle id="form-dialog-title">Update Default Role</DialogTitle>
<DialogContent>
<DialogContentText>
Please enter the new permissions for the default role.<br/> WARNING: Be careful!
Improper use of this function is dangerous!
</DialogContentText>
<FormControl component="fieldset" style={{padding: "20px", margin: "10px"}}>
<FormLabel component="legend">User Can Mint Tokens:</FormLabel>
<RadioGroup aria-label="mint" name="can-mint" value={canMint} onChange={handleMintChange}>
<FormControlLabel value={true} control={<Radio />} label="True" />
<FormControlLabel value={false} control={<Radio />} label="False" />
</RadioGroup>
</FormControl>
<FormControl component="fieldset" style={{padding: "20px", margin: "10px"}}>
<FormLabel component="legend">User Can Burn Tokens:</FormLabel>
<RadioGroup aria-label="burn" name="can-burn" value={canBurn} onChange={handleBurnChange}>
<FormControlLabel value={true} control={<Radio />} label="True" />
<FormControlLabel value={false} control={<Radio />} label="False" />
</RadioGroup>
</FormControl>
<FormControl component="fieldset" style={{padding: "20px", margin: "10px"}}>
<FormLabel component="legend">User Must Pay Fee:</FormLabel>
<RadioGroup aria-label="fee" name="pay-fee" value={payFee} onChange={handleFeeChange}>
<FormControlLabel value={true} control={<Radio />} label="True" />
<FormControlLabel value={false} control={<Radio />} label="False" />
</RadioGroup>
</FormControl>
<FormControl component="fieldset" style={{padding: "20px", margin: "10px"}}>
<FormLabel component="legend">User Must Pay Split:</FormLabel>
<RadioGroup aria-label="split" name="pay-split" value={paySplit} onChange={handleSplitChange}>
<FormControlLabel value={true} control={<Radio />} label="True" />
<FormControlLabel value={false} control={<Radio />} label="False" />
</RadioGroup>
</FormControl>
</DialogContent>
<DialogActions>
<Button onClick={handleClose} color="primary">
Cancel
</Button>
<Button onClick={submitUpdateDefaultRole} color="primary">
Submit
</Button>
</DialogActions>
</Dialog>
</div>
);
}
I've tried to follow the code on Material-UI's site as loyally as possible, but I'm obviously messing up somewhere.
Thank you for taking the time to read my question!
Probably it's a string and not a boolean and that is causing the issue. Try as:
const handleMintChange = e => setCanMint(e.target.value === 'true');

How to use multiple material ui dialog with React?

I want to use two dialog in sign up page and login page.
the implement that I want to do are signup screen showing up when click to sign up button on the Top page, and login screen showing up when click to login Button on signup page.
I wrote open state on App.js.
but the trouble is when it's written in App.js, two of modal open..
Does anyone know how to settle it?
App.js
const App = () => {
const [open, setOpen] = useState(false);
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
return (
<div>
<Top handleClickOpen={handleClickOpen}/>
<SignupModal open={open} handleClose={handleClose} />
<LoginModal open={open} handleClose={handleClose} />
</div>
)
Top.js
const Top = (props) => {
const classes = useStyles();
return (
<React.Fragment>
<div style={style}>
<Button variant="outlined" className={classes.loginButton} onClick={props.handleClickOpen}>
Login
</Button>
</div>
<h1>Toppage</h1>
</React.Fragment>
);
}
SignupModal.js
const SignupModal = (props) => {
return (
<div>
<Dialog
open={props.open}
onClose={props.handleClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title" className={classes.title}>Sign up</DialogTitle>
<DialogContent className={classes.content}>
<div className={classes.text}>
<TextField id="standard-basic" label=“name” fullWidth/>
<TextField id="standard-basic" label=“email” fullWidth/>
<TextField id="standard-basic" label=“password” fullWidth/>
<TextField id="standard-basic" label=“pass”word fullWidth/>
</div>
</DialogContent>
<p className={classes.toLogin}>to Login</p>
<DialogActions>
<Button onClick={props.handleClose} className={classes.signUpButton}>
Send
</Button>
</DialogActions>
</Dialog>
</div>
);
}
LoginModal.ls
const LoginModal = (props) => {
return (
<div>
<Dialog
open={props.open}
onClose={props.handleClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title" className={classes.title}>Login</DialogTitle>
<DialogContent className={classes.content}>
<div className={classes.text}>
<TextField id="standard-basic" label=“name” fullWidth/>
<TextField id="standard-basic" label=“pass”word fullWidth}/>
</div>
</DialogContent>
<DialogActions>
<Button onClick={props.handleClose} className={classes.signUpButton}>
Login
</Button>
</DialogActions>
</Dialog>
</div>
);
}
export default LoginModal
You are sharing the state on both of your modals that's why.
The solution is simple, have 2 states; one that will determine if SignupModal is opened or not and another one for LoginModal.
const App = () => {
const [openLogin, setOpenLogin] = useState(false);
const [openSignup, setOpenSignup] = useState(false);
return (
<div>
<Top
onClickLogin={() => setOpenLogin(true)}
onClickSignup={() => setOpenSignup(true)}
/>
<SignupModal open={openLogin} handleClose={() => setOpenLogin(false)} />
<LoginModal open={openSignup} handleClose={() => setOpenSignup(false)} />
</div>
);
};
const Top = (props) => {
return (
<React.Fragment>
<div>
<Button
variant="outlined"
className={classes.loginButton}
onClick={props.onClickLogin}
>
Login
</Button>
<Button
variant="outlined"
className={classes.loginButton}
onClick={props.onClickSignup}
>
Signup
</Button>
</div>
<h1>Toppage</h1>
</React.Fragment>
);
};

React Button unable to call method in Function component

I have a React button that is a form and I intend to submit the form when I click on the Button. Unfortunately, when I click on the button, nothing happens and the page only reloads. Even when I just try to output to the console nothing happens but when you check the network, you could see an action being performed.
Below is my code which is just a simple login form and a functionality that validates user input. I need the button to call the function handleSubmit when I click on the button.
export default function Signin() {
const classes = useStyles();
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [usernameError, setUsernameError] = useState('');
const [passwordError, setPasswordError] = useState('');
const validateUsername = () => {
setUsernameError(username.length > 3 ? null : 'Username must be longer than 3 characters')
}
const validatePassword = () => {
setPasswordError(password.length > 7 ? null : 'Password must be longer than 8 characters')
}
const handleSubmit = () => {
//const { history } = this.props;
console.log('testing button')
}
return (
<Grid
className={classes.root}
component="main"
container
>
<CssBaseline />
<Grid
className={classes.image}
item
md={4}
sm={7}
xs={false}
/>
<Grid
component={Paper}
elevation={6}
item
md={8}
sm={5}
square
xs={12}
>
<MuiThemeProvider theme={theme}>
<div className={classes.paper}>
<img
alt="logo"
src={process.env.PUBLIC_URL + '/images/....'}
/>
<Typography
component="h1"
style={{ color: '#E60000' }}
variant="h5"
>
Sign In
</Typography>
<form
className={classes.form}
noValidate
>
<Grid
container
spacing={2}
>
<Grid
item
xs={3}
/>
<Grid
item
xs={6}
>
<TextField
autoComplete="username"
className={`form-control ${usernameError ? 'is-invalid' : ''}`}
fullWidth
id="username"
label="Enter Username"
margin="normal"
name="username"
onBlur={validateUsername}
onChange={e => setUsername(e.target.value)}
required
value={username}
variant="outlined"
/>
<div className={classes.invalidFeedback}>{usernameError}</div>
</Grid>
<Grid
item
xs={3}
/>
<Grid
item
xs={3}
/>
<Grid
item
xs={6}
>
<TextField
autoComplete="current-password"
className={`form-control ${passwordError ? 'is-invalid' : ''}`}
fullWidth
id="password"
label="Password"
margin="normal"
name="password"
onBlur={validatePassword}
onChange={e => setPassword(e.target.value)}
required
type="password"
value={password}
variant="outlined"
/>
<div className={classes.invalidFeedback}>{passwordError}</div>
</Grid>
<Grid
item
xs={3}
/>
<Grid
item
xs={3}
/>
<Grid
item
xs={3}
>
<Button
className={classes.submit}
color="primary"
fullWidth
onClick={handleSubmit}
type="submit"
variant="contained"
>
Sign In
</Button>
<Grid
item
xs={3}
/>
</Grid>
</Grid>
<Grid container>
<Grid
item
xs={3}
/>
<Grid
item
xs={3}
>
<Link
className={classes.link}
to={`${process.env.PUBLIC_URL}/passwordreset`}
variant="body2"
>
<Button
className={classes.submit}
color="primary"
fullWidth
type="submit"
variant="text"
>
Forgot Password
</Button>
</Link>
</Grid>
<Grid item>
<Link
className={classes.link}
to={`${process.env.PUBLIC_URL}/signup`}
variant="body2"
>
<Button
className={classes.submit}
color="primary"
fullWidth
type="submit"
variant="text"
>
New User?
</Button>
</Link>
</Grid>
</Grid>
<Box mt={5}>
<SigninTrouble />
</Box>
</form>
</div>
</MuiThemeProvider>
</Grid>
</Grid>
);
}
Since you are using Form you need to handle submit method in form instead of your button. Because your button type is submit which triggers the onSubmit event in form.
<form onSubmit={handleSubmit}>
<button type="submit"></button>
</form>
If you want to make an async call you need to stop normal event cycle for your form.
const handleSubmit = (event) => {
// stop redirect
event.preventDefault();
console.log('testing button');
// here you can make your async call
}
In order to use a button with type submit it has to be nested within an html form tag and handle the submission with the onsubmit attribute.
Onother option is to attack an onClick event handler to your button and have your submission logic there.
Here is very simple example:
import React, {useEffect, useState} from 'react';
function Example(props) {
function clickHandler() {
alert('hi');
}
return (
<div>
<button onClick={clickHandler}>Click here</button>
</div>
);
}
export default Example;

Categories