How to make Material-UI Dialog work in React - javascript

I am using material-UI for my project and I want to use Dialog but Dialog not working without any error. I am using react with material design. I try many things but still not working. I am using react with material design.i want to open form in Dialog.
App.tsx
import React from "react";
import logo from "./logo.svg";
import "./style.scss";
import {
Button,
FormControl,
TextField,
Grid,
Container
} from "#material-ui/core";
import CreateDialog from "./Components/UserLoginSignUp/Signup";
function App() {
return (
<Container>
<div className="App">
<CreateDialog />
sdfsdf
</div>
</Container>
);
}
export default App;
Signup.tsx
import React, { Fragment } from "react";
import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle
} from "#material-ui/core";
import { FormControl, TextField, Grid, Container } from "#material-ui/core";
import { Component } from "react";
export default class extends Component {
state = {
open: false
};
handleToggle = () => {
this.setState({
open: !this.state.open
});
};
render() {
const { open } = this.state;
return (
<Fragment>
<Button>add</Button>
<Dialog aria-labelledby="form-dialog-title" open={open}>
<DialogTitle id="form-dialog-title">Set backup account</DialogTitle>
<DialogContent>
<DialogContentText>form</DialogContentText>
<Grid container spacing={3}>
<Grid item xs={12} sm={6} id="content_side_userLS">
<Grid>
{" "}
<h1>Signup</h1>
<p>
Invest with next-generation wealth building & investment
platform.
</p>
</Grid>
</Grid>
<Grid item xs={12} sm={6}>
<form noValidate autoComplete="off">
<FormControl className="input_field" fullWidth>
<TextField id="standard-basic" label="Full Name" />
</FormControl>
<FormControl className="input_field" fullWidth>
<TextField
id="standard-basic"
label="Enter Email/Mobile Number"
/>
</FormControl>
<FormControl className="input_field" fullWidth>
{" "}
<TextField id="standard-basic" label="Password" />
</FormControl>
<FormControl className="input_field" fullWidth>
{" "}
<Button variant="contained" color="primary">
{" "}
CONTINUE{" "}
</Button>
</FormControl>
</form>
</Grid>
</Grid>
</DialogContent>
<DialogActions>
<Button>Subscribe</Button>
</DialogActions>
</Dialog>
</Fragment>
);
}
}

You didn't bind the handler function handleToggle to the button.
<Button onClick={this.handleToggle}>add</Button>
You need an onClose callback handler to close the dialog, and it seems you can share the same handler with onClick.
handler = () => {
this.setState({
open: !this.state.open
});
};
<Dialog
aria-labelledby="form-dialog-title"
open={open}
onClose={this.handler}
>
Try it online:

Related

react-speech-recognition for text-field

Im trying to make react-speech-recognition write inside a text-field but for some reason it wont work. I think it has to do with the last line.
import React from 'react';
import Button from '#material-ui/core/Button';
import Checkbox from '#material-ui/core/Checkbox';
import CircularProgress from '#material-ui/core/CircularProgress';
import FormControlLabel from '#material-ui/core/FormControlLabel';
import Grid from '#material-ui/core/Grid';
import TextField from '#material-ui/core/TextField';
import Paper from '#material-ui/core/Paper';
import InputLabel from '#material-ui/core/InputLabel';
import SpeechRecognition, { useSpeechRecognition } from 'react-speech-recognition'
// import EventIcon from '#material-ui/icons/Event';
import SearchIcon from '#material-ui/icons/Search';
// import TodayIcon from '#material-ui/icons/Today';
import InputUnstyled from '#mui/base/InputUnstyled';
const Dictaphone = () => {
const {
transcript,
listening,
resetTranscript,
browserSupportsSpeechRecognition
} = useSpeechRecognition();
if (!browserSupportsSpeechRecognition) {
return <span>Browser doesn't support speech recognition.</span>;
}
return (
<div>
<p>Microphone: {listening ? 'on' : 'off'}</p>
<button onClick={SpeechRecognition.startListening}>Start</button>
<button onClick={SpeechRecognition.stopListening}>Stop</button>
<button onClick={resetTranscript}>Reset</button>
<p>{transcript}</p>
</div>
);
};
function updateInput(ish) {
document.setSearchField = "Rendering";
}
function SearchForm({ runSearch, setSearchField, setAuthorField, setVenue, setBeginDate, setEndDate, setShowGraph, show_loading }) {
const {
transcript,
listening,
resetTranscript,
browserSupportsSpeechRecognition
} = useSpeechRecognition();
return (
<Grid container spacing={2}>
<Grid item xs={1} />
<Grid item xs={10}>
<Paper elevation={2}>
<div className="search-body">
<form onSubmit={runSearch}>
<Grid container spacing={2}>
<Grid item xs={12}>
<div>
<p>Microphone: {listening ? 'on' : 'off'}</p>
<button onClick={SpeechRecognition.startListening}>Start</button>
<button onClick={SpeechRecognition.stopListening}>Stop</button>
<button onClick={resetTranscript}>Reset</button>
<p>{transcript}</p>
</div>
<TextField
id="busca" label="Palavras-chave *"
type='text'
placeholder={transcript}
name='q'
variant="outlined"
fullWidth
InputProps={{
endAdornment: <SearchIcon />
}}
InputLabelProps={{
shrink: true
}}
onChange={setSearchField} />
I tried using value={transcript} in the text-field but it only will work after i write something after it. Example: i say "hello", it will write it in the text-field but it wont actually send "hello" until i write something with the keyboard after like "1". then it will send "hello1".
<TextField
id="busca" label="Palavras-chave *"
type='text'
value={transcript}
placeholder={transcript}
name='q'
variant="outlined"
fullWidth
InputProps={{
endAdornment: <SearchIcon />
}}
InputLabelProps={{
shrink: true
}}
onChange={setSearchField} />
I think it might work if you replace TextField with textarea including value={transcript} for the same.

React / MUI : How to call other class with hook to button in main App.js

I'm new to React/MUI.. I'm creating different components for now for a website, so the UI for now doesn't matter.
I'm facing this problem while trying to do a button to link me to the Sign Up page (Doing the same for Sign In):
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: ...
The following is my code:
SignUp.js
import React from 'react';
import Avatar from '#material-ui/core/Avatar';
import Button from '#material-ui/core/Button';
import CssBaseline from '#material-ui/core/CssBaseline';
import TextField from '#material-ui/core/TextField';
import FormControlLabel from '#material-ui/core/FormControlLabel';
import Checkbox from '#material-ui/core/Checkbox';
import Link from '#material-ui/core/Link';
import Grid from '#material-ui/core/Grid';
import Box from '#material-ui/core/Box';
import LockOutlinedIcon from '#material-ui/icons/LockOutlined';
import Typography from '#material-ui/core/Typography';
import { makeStyles } from '#material-ui/core/styles';
import Container from '#material-ui/core/Container';
const useStyles = makeStyles((theme) => ({
paper: {
marginTop: theme.spacing(8),
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
},
avatar: {
margin: theme.spacing(1),
backgroundColor: theme.palette.secondary.main,
},
form: {
width: '100%', // Fix IE 11 issue.
marginTop: theme.spacing(3),
},
submit: {
margin: theme.spacing(3, 0, 2),
},
}));
export default function SignUp() {
const classes = useStyles();
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
/>
</Grid>
<Grid item xs={12} sm={6}>
<TextField
variant="outlined"
required
fullWidth
id="lastName"
label="Last Name"
name="lastName"
autoComplete="lname"
/>
</Grid>
<Grid item xs={12}>
<TextField
variant="outlined"
required
fullWidth
id="email"
label="Email Address"
name="email"
autoComplete="email"
/>
</Grid>
<Grid item xs={12}>
<TextField
variant="outlined"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="current-password"
/>
</Grid>
<Grid item xs={12}>
<FormControlLabel
control={<Checkbox value="allowExtraEmails" color="primary" />}
label="I want to receive inspiration, marketing promotions and updates via email."
/>
</Grid>
</Grid>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
>
Sign Up
</Button>
<Grid container justify="flex-end">
<Grid item>
<Link href="#" variant="body2">
Already have an account? Sign in
</Link>
</Grid>
</Grid>
</form>
</div>
<Box mt={5}>
<Copyright />
</Box>
</Container>
);
}
App.js
import React from 'react';
import Container from '#material-ui/core/Container';
import Typography from '#material-ui/core/Typography';
import SignUp from './sign-up/SignUp.js';
import SignIn from './sign-in/SignIn.js';
import Box from '#material-ui/core/Box';
import Link from '#material-ui/core/Link';
import { Button, Paper } from '#material-ui/core';
export default function App() {
return (
<div>
<Container maxWidth="sm">
<Box my={4}>
<Typography variant="h4" component="h1" gutterBottom>
Creating a website!
</Typography>
<ProTip />
<button onClick={SignUp}>
Click me!
</button>
<SignIn />
<Copyright />
</Box>
</Container>
</div>
);
}
How do I properly convert in this case?
You're trying to call a React component as an event handler:
<button onClick={SignUp}>
That will not work. Instead you can for example create a flag, set it to true in the onClick handler and then render SignUp based on this flag.
const [showSignUp, setShowSignUp]= React.useState(false)
...
<button onClick={()=>setShowSignUp(s=>!s)}>Click me!</button>
{showSignUp ? <SignUp /> : <SignIn />}

Material UI: Grid does not put select in row

I'm new in full stack developing and I'm trying to code something to understand better frontend with React JS and Material UI. I've write a page that shows posts in backend but I want to Select Items all in a row, on Material UI website I've read that I've to write like this in order to show elements in a row:
Marketplace.js
import { Grid } from '#material-ui/core'
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import regioni from '../utils/where'
import Adv from '../components/marketplace/Adv';
import NewAdv from '../components/marketplace/NewAdv';
import Profile from '../components/profile/Profile';
import PostSkeleton from '../utils/PostSkeleton';
import Select from '#material-ui/core/Select';
import Input from '#material-ui/core/Input';
import InputLabel from '#material-ui/core/InputLabel';
import MenuItem from '#material-ui/core/MenuItem';
import TextField from '#material-ui/core/TextField';
import Radio from '#material-ui/core/Radio';
import RadioGroup from '#material-ui/core/RadioGroup';
import FormControlLabel from '#material-ui/core/FormControlLabel';
import Button from '#material-ui/core/Button';
import FormLabel from '#material-ui/core/FormLabel';
import { connect } from 'react-redux';
class marketplace extends Component {
state = {
query:'',
errors:{},
type:'Vendo',
title:'',
product:'Singole',
body:'',
regione:'Abruzzo',
provincia:'',
};
componentDidMount(){
const {
user:{
authenticated, credentials:{
handle,
ygo,
mtg,
kf
}
}} = this.props;
render() {
return (
<Grid container>
<Grid item sm={4} xs={12}>
<Profile/>
</Grid>
<Grid item sm={8} xs={12}>
<TextField
name="search"
floatingLabelText="Cerca"
value={this.state.query}
onChange={this.searchChange}
/>
<Button type="submit" variant="contained" color="primary" onClick={this.handleSearch}>
Cerca
</Button>
<Grid item xs={6} sm={3} >
<FormLabel component="legend">Tipo</FormLabel>
<RadioGroup aria-label="Tipo" name="type" color="primary" value={this.state.type} onChange={this.radioTypeChange}>
<FormControlLabel value="Vendo" control={<Radio />} label="Vendo" />
<FormControlLabel value="Scambio" control={<Radio />} label="Scambio" />
<FormControlLabel value="Cerco" control={<Radio />} label="Cerco" />
</RadioGroup>
</Grid>
<Grid item xs={6} sm={3}>
<FormLabel component="legend">Prodotto</FormLabel>
<RadioGroup aria-label="Prodotto" name="product" color="primary" value={this.state.product} onChange={this.radioProductChange}>
<FormControlLabel value="Singole" control={<Radio />} label="Singole" />
<FormControlLabel value="Lista" control={<Radio />} label="Lista" />
<FormControlLabel value="Sigillato" control={<Radio />} label="Sigillato" />
<FormControlLabel value="Accessori" control={<Radio />} label="Accessori" />
</RadioGroup>
</Grid>
<Grid item xs={6} sm={3}>
<InputLabel id="regioni">Regione</InputLabel>
<Select
labelId="Regione"
id="regioni"
value={this.state.regione}
onChange={this.regionChange}
input={<Input />}
MenuProps={MenuProps}
>
{regioni.map((regione) => (
<MenuItem value={regione.regioneName}>
{regione.regioneName}
</MenuItem>
))}
</Select>
</Grid>
<Grid item xs={6} sm={3}>
<InputLabel id="demo-simple-select-label">Provincia</InputLabel>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={this.state.provincia}
onChange={this.whereChange}
disabled={!this.state.regione}
>
{this.state.regione
? regioni
.find(({ regioneName }) => regioneName === this.state.regione)
.province.map((prov) => (
<MenuItem value={prov.name}>
{prov.name}
</MenuItem>
))
: []}
</Select>
</Grid>
<Button type="submit" variant="contained" color="primary" onClick={this.handleFilter}>
filter
</Button>
<Button type="submit" variant="contained" color="primary" onClick={this.handleReset}>
Reset
</Button>
<NewAdv game={game}/>
{recentAdvsMarkup}
</Grid>
<Grid item sm={4} xs={12}>
</Grid>
</Grid>
)
}
}
marketplace.propTypes={
data: PropTypes.object.isRequired,
user: PropTypes.object.isRequired
}
const mapStateToProps = state =>({
data: state.data,
user: state.user,
game: state.UI
})
export default connect(mapStateToProps,)(marketplace)
But they were showed in a columb. How can I do?
You can wrap elements in a Box Material UI component.
<Box display="flex" flexDirection="row">
<Box>
// Element
</Box>
<Box>
// Element
</Box>
</Box>

How do I disable Accordion propagation after it has been clicked for the first time?

I have an Accordion with a TextField in the AccordionSummary (Material-UI) which when clicked opens the AccordionDetails with the rest of the form however, I can't work out how to stop multiple clicks on the field from triggering propagation to open and close the accordion contents after the first click. I don't want the newly visible form contents to disappear after the first click in AccountSummary. I know how to disable propagation when the field is entered for the first time but not how to allow propagation only once?
import React from "react";
import { Formik, Field, Form } from "formik";
import { TextField, Select } from "formik-material-ui";
import Grid from "#material-ui/core/Grid";
import Box from "#material-ui/core/Box";
import FormControl from "#material-ui/core/FormControl";
import MenuItem from "#material-ui/core/MenuItem";
import Button from "#material-ui/core/Button";
import Accordion from "#material-ui/core/Accordion";
import MuiAccordionDetails from "#material-ui/core/AccordionDetails";
import MuiAccordionSummary from "#material-ui/core/AccordionSummary";
import { withStyles } from "#material-ui/core/styles";
const AccordionSummary = withStyles({
root: {
"&.Mui-focused": {
backgroundColor: "inherit"
}
}
})(MuiAccordionSummary);
const AccordionDetails = withStyles({
root: {
paddingTop: 0
}
})(MuiAccordionDetails);
export default function App() {
return (
<div className="App">
<Formik>
<Form>
<Accordion>
<AccordionSummary>
<FormControl fullWidth>
<Field
component={TextField}
name="itemName"
placeholder="What do you want to buy?"
variant="outlined"
/>
</FormControl>
</AccordionSummary>
<AccordionDetails>
<Grid container>
<Grid item xs={2}>
<Box>
<FormControl fullWidth>
<Field
component={TextField}
name="quantity"
label="Qty"
type="number"
variant="outlined"
size="small"
/>
</FormControl>
</Box>
</Grid>
<Grid item xs={2}>
<Box pl={1}>
<FormControl fullWidth>
<Field
component={TextField}
name="volume"
label="Vol"
type="number"
variant="outlined"
size="small"
/>
</FormControl>
</Box>
</Grid>
<Grid item xs={2}>
<Box pl={1}>
<FormControl label="Type" size="small" fullWidth>
<Field
component={Select}
name="volumeType"
as="select"
variant="outlined"
>
<MenuItem value="g">grams</MenuItem>
<MenuItem value="kg">kg</MenuItem>
<MenuItem value="ml">ml</MenuItem>
<MenuItem value="cl">cl</MenuItem>
<MenuItem value="litre">litre</MenuItem>
<MenuItem value="pint">pint</MenuItem>
<MenuItem value="pack">pack</MenuItem>
</Field>
</FormControl>
</Box>
</Grid>
<Grid item xs={4}>
<Box pl={1}>
<FormControl fullWidth>
<Field
component={TextField}
name="brandName"
label="Brand"
variant="outlined"
size="small"
/>
</FormControl>
</Box>
</Grid>
<Grid item xs={2}>
<Box pl={1}>
<Button
type="submit"
variant="contained"
color="primary"
disableElevation
fullWidth
>
Add
</Button>
</Box>
</Grid>
</Grid>
</AccordionDetails>
</Accordion>
</Form>
</Formik>
</div>
);
}
The only way I could get this to work without creating a massive performance hit was the following:
import Accordion from "#material-ui/core/Accordion";
import AccordionDetails from "#material-ui/core/AccordionDetails";
import AccordionSummary from "#material-ui/core/AccordionSummary";
import Typography from "#material-ui/core/Typography";
import ExpandMoreIcon from "#material-ui/icons/ExpandMore";
import React, { useState } from "react";
export default function ControlledAccordions() {
const [expanded, setExpanded] = useState("");
const handleChange = (panel) => () => {
setExpanded(panel);
};
return (
<div>
<Accordion
expanded={expanded === "panel1"}
onChange={handleChange("panel1")}
>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<Typography>General settings</Typography>
<Typography>I am an accordion</Typography>
</AccordionSummary>
<AccordionDetails>
<Typography>
Nulla facilisi. Phasellus sollicitudin nulla et quam mattis feugiat.
Aliquam eget maximus est, id dignissim quam.
</Typography>
</AccordionDetails>
</Accordion>
</div>
);
}

How do I get the likes length to update in real time after clicking clicking like

If I click to remove the first like on the first goal, I can see the Redux action firing (using Redux DevTools) for the like being updated. But the number beside is not updating. When I check the console it doesn't appear that anything is refreshing. When I refresh the page, it shows the updated number that was previously liked (the 0 becomes a 1), but I have to refresh the page to see this update. How can I get the number to update in real time without having to refresh the page?
import React, { useEffect } from "react";
import Moment from "react-moment";
import PropTypes from "prop-types";
import { Link } from "react-router-dom";
import { connect } from "react-redux";
import { addLike, removeLike } from "../../actions/goal";
import { getGoals } from "../../actions/goal";
import Spinner from "../layout/Spinner";
import Navbar from "../dashboard/Navbar";
import ThumbUpAltIcon from "#material-ui/icons/ThumbUpAlt";
import ThumbDownAltIcon from "#material-ui/icons/ThumbDownAlt";
import ChatIcon from "#material-ui/icons/Chat";
import DeleteIcon from "#material-ui/icons/Delete";
import DoneIcon from "#material-ui/icons/Done";
import {
Typography,
Container,
CssBaseline,
makeStyles,
Grid,
Avatar,
Paper,
Button
} from "#material-ui/core";
const useStyles = makeStyles(theme => ({
paper: {
height: "auto",
marginBottom: theme.spacing(3)
},
actionButtons: {
marginTop: "3vh"
},
profileHeader: {
textAlign: "center",
marginBottom: 20
},
avatar: {
width: theme.spacing(7),
height: theme.spacing(7)
}
}));
const Goals = ({
getGoals,
auth,
addLike,
removeLike,
goal: { goals, user, loading }
}) => {
useEffect(() => {
getGoals();
}, [getGoals]);
const classes = useStyles();
return loading ? (
<>
<Navbar />
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Spinner />
</div>
</Container>
</>
) : (
<>
<CssBaseline />
<Navbar />
<main>
<Container>
<Typography variant="h2" className={classes.profileHeader}>
Goals
</Typography>
{/* parent grid */}
<Grid container spacing={4}>
{goals.map(singleGoal => (
<Grid
className={classes.paper}
key={singleGoal._id}
spacing={1}
container
item
direction="row"
alignItems="center"
component={Paper}
>
<Grid
item
container
direction="column"
justify="center"
alignItems="center"
xs={3}
>
<Avatar className={classes.avatar} src={singleGoal.avatar} />
<Typography variant="caption">
{singleGoal.first_name} {singleGoal.last_name}
</Typography>
<Typography variant="caption" className={classes.postedOn}>
Posted on{" "}
<Moment format="MM/DD/YYYY">{singleGoal.date}</Moment>
</Typography>
</Grid>
<Grid container item direction="column" xs={9}>
<Typography variant="body1">{singleGoal.text}</Typography>
<Grid item className={classes.actionButtons}>
<Button size="small" onClick={e => addLike(singleGoal._id)}>
<ThumbUpAltIcon />
</Button>
<Typography variant="caption">
{singleGoal.likes.length}
</Typography>
<Button
size="small"
onClick={e => removeLike(singleGoal._id)}
>
<ThumbDownAltIcon />
</Button>
<Button href={`/goal/${singleGoal._id}`} size="small">
<ChatIcon />
</Button>
{!auth.loading && singleGoal.user === auth.user._id && (
<Button size="small">
<DoneIcon />
</Button>
)}
{!auth.loading && singleGoal.user === auth.user._id && (
<Button size="small">
<DeleteIcon />
</Button>
)}
</Grid>
</Grid>
</Grid>
))}
</Grid>
</Container>
</main>
</>
);
};
Goals.propTypes = {
getGoals: PropTypes.func.isRequired,
goal: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
goal: state.goal,
auth: state.auth
});
export default connect(mapStateToProps, { getGoals, addLike, removeLike })(
Goals
);
I will need to see the rest of your code to be sure, but it seems you are dispatching your action but you are not updating your store, it could be a mistake in your reducer.

Categories

Resources