Styling a card causes TextField to lose focus in Material UI + React - javascript

I'm trying to style my card so that it's not so big but the problem is every time I do that, my TextField loses its' functionality and I have to keep on clicking on the TextField because it keeps on losing focus. I need to make my Card component smaller without losing the functionality of my TextField.
https://codesandbox.io/s/mutable-monad-dsvf8?file=/src/index.js
import React, { useState } from "react";
import ReactDOM from "react-dom";
import Grid from "#material-ui/core/Grid";
import Button from "#material-ui/core/Button";
import Card from "#material-ui/core/Card";
import TextField from "#material-ui/core/TextField";
import CreateIcon from "#material-ui/icons/Create";
import Box from "#material-ui/core/Box";
import CardMedia from "#material-ui/core/CardMedia";
import MuiAlert from "#material-ui/lab/Alert";
import Snackbar from "#material-ui/core/Snackbar";
import { withStyles } from "#material-ui/core/styles";
const PetitionCard = () => {
const StyledCard = withStyles({
root: { height: 450, width: 350 }
})(Card);
const [title, setTitle] = useState("");
const [description, setDescription] = useState("");
const [open, setOpen] = useState(false);
const [petition, newPetition] = useState(false);
const handleTitleChange = event => {
setTitle(event.target.value);
};
const handleDescriptionChange = event => setDescription(event.target.value);
const handleClose = (event, reason) => {
if (reason === "clickaway") {
return;
}
};
const Alert = props => <MuiAlert elevation={6} variant="filled" {...props} />;
const Message = (message, severity) => {
return (
<Snackbar open={!open} autoHideDuration={3000} onClose={handleClose}>
<Alert severity={severity}>{message}</Alert>
</Snackbar>
);
};
const clearField = event => {
setOpen(true);
if (title.length > 0 && description.length > 0) {
setTitle("");
setDescription("");
return (
<Message
open={open}
message={"You have successfully created a petition!"}
severity={"success"}
/>
);
} else {
return (
<Message
message={"You have one more more fields missing"}
severity={"error"}
/>
);
}
};
return (
<StyledCard>
<Box mt={1}>
<Grid container justify="center">
<TextField
id="outlined-multiline-static"
multiline
rows={1}
variant="outlined"
placeholder="Title"
value={title}
onChange={handleTitleChange}
/>
</Grid>
</Box>
<CardMedia title="Petition" style={{ height: 0, paddingTop: "40.25%" }} />
<Box mt={1} justify="center">
<Grid container justify="center">
<TextField
size="small"
inputProps={{
style: { fontSize: 15 }
}}
id="outlined-multiline-static"
multiline
rows={5}
placeholder="Description"
variant="outlined"
value={description}
onChange={handleDescriptionChange}
/>
</Grid>
</Box>
<Box mt={1}>
<Grid container justify="center">
<Button onClick={clearField}>
<CreateIcon />
Create Petition!
</Button>
</Grid>
</Box>
</StyledCard>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(
<React.StrictMode>
<PetitionCard />
</React.StrictMode>,
rootElement
);

The problem is that you are re-creating StyledCard whenever PetitionCard is rendered:
const PetitionCard = () => {
const StyledCard = withStyles({
root: { height: 450, width: 350 }
})(Card);
[...]
}
Therefore, a new TextField is created on every render since its container changes. TextField is by default not focused and doesn't know whether the TextField from the previous render was focused.
The solution is to create StyledCard outside PetitionCard:
const StyledCard = withStyles({
root: { height: 450, width: 350 }
})(Card);
const PetitionCard = () => {
[...]
}

Related

How to launch a popUp without a button in react?

I have a modal window / Cookies dialog that I want to be launched when I open my application, without having to press any buttons, before showing my Dashboard.
this is my dashboard:
import { getDocument } from '../actions/documentAction';
//
import Grid from '#mui/material/Grid';
import { ThemeProvider } from '#mui/material'
//
import theme from '../styles/theme'
import '../styles/styles.css'
//
import HeaderBar from './header-bar/HeaderBar'
import BodyGrid from './body-grid/BodyGrid';
import BottomBar from './botton-bar/BottonBar';
// -----------------------------------------------------------
export const Dashboard = () => {
const dispatch = useDispatch();
dispatch( getDocument( 'EIT5850', {} ) );
//dispatch( getPrintCenter( 'EIT5850' ) );
return (
<>
<ThemeProvider theme={theme}>
<div>
<HeaderBar/>
<Grid container xs={12}>
<BodyGrid/>
</Grid>
<Grid container xs={12} pt={4}>
<BottomBar/>
</Grid>
</div>
</ThemeProvider>
</>
)
}
This is my Cookies modal:
import * as React from 'react';
import Backdrop from '#mui/material/Backdrop';
import Box from '#mui/material/Box';
import Modal from '#mui/material/Modal';
import Fade from '#mui/material/Fade';
import Button from '#mui/material/Button';
import Typography from '#mui/material/Typography';
import {Stack, ThemeProvider } from '#mui/material'
import Tab from '#mui/material/Tab';
import TabContext from '#mui/lab/TabContext';
import TabList from '#mui/lab/TabList';
import TabPanel from '#mui/lab/TabPanel';
import { FormControlLabel, IconButton } from '#mui/material';
import CloseIcon from '#mui/icons-material/Close';
import PropTypes from 'prop-types';
import { styled } from '#mui/material/styles';
import Dialog from '#mui/material/Dialog';
import DialogTitle from '#mui/material/DialogTitle';
import DialogContent from '#mui/material/DialogContent';
import DialogActions from '#mui/material/DialogActions';
import theme from '../../styles/theme'
import '../../styles/styles.css'
const style = {
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: 1800,
bgcolor: 'background.paper',
border: '2px solid #000',
boxShadow: 24,
p: 4,
};
const BootstrapDialog = styled(Dialog)(({ theme }) => ({
'& .MuiDialogContent-root': {
padding: theme.spacing(2),
},
'& .MuiDialogActions-root': {
padding: theme.spacing(1),
},
}));
const BootstrapDialogTitle = (props) => {
const { children, onClose, ...other } = props;
return (
<DialogTitle sx={{ m: 0, p: 2 }} {...other}>
{children}
{onClose ? (
<IconButton
aria-label="close"
onClick={onClose}
sx={{
position: 'absolute',
right: 8,
top: 8,
color: (theme) => theme.palette.grey[500],
}}
>
<CloseIcon />
</IconButton>
) : null}
</DialogTitle>
);
};
BootstrapDialogTitle.propTypes = {
children: PropTypes.node,
onClose: PropTypes.func.isRequired,
};
export default function ModalNonDocs() {
const handleOpen = () => setOpen(true);
const [open, setOpen] = React.useState(false);
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
const handleNotClose = (event, reason) => {
if (reason && reason == "backdropClick")
return;
}
const [value, setValue] = React.useState('1');
const handleChange = (event, newValue) => {
setValue(newValue);
};
return (
<ThemeProvider theme={theme}>
<div>
<Fade in={open}>
<Box>
<BootstrapDialog
onClose={handleNotClose}
aria-labelledby="customized-dialog-title"
open={open}
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500,
}}
>
<BootstrapDialogTitle id="customized-dialog-title" onClose={handleClose}>
</BootstrapDialogTitle>
<TabContext value={value}>
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
<TabList onChange={handleChange} aria-label="lab API tabs example">
<Tab
label="Consentimiento"
value="1" />
<Tab
label="PolĂ­tica de Cookies"
value="2" />
<Tab
label="Acerca de las Cookies"
value="3" />
</TabList>
</Box>
<TabPanel value="1">
<p>Opcion 1</p>
</TabPanel>
<TabPanel value="2">
<p>Opcion 2</p>
</TabPanel>
<TabPanel value="3">
<p>Opcion 3</p>
</TabPanel>
</TabContext>
<Button
onClick={handleClose}
variant="contained"
color="secondary"
style={
{ borderRadius: 0 ,
fontFamily: 'Source Sans Pro'}
}
>
Aceptar
</Button>
</BootstrapDialog>
</Box>
</Fade>
</div>
</ThemeProvider>
);
}
and this is where I call my dashboard to launch it
import { Routes, Route, BrowserRouter } from 'react-router-dom';
import { Dashboard } from '../components/Dashboard';
import { PrivateRoute } from './PrivateRoute';
export const AppRouter = () => {
return (
<BrowserRouter>
<Routes>
<Route path="/*" element={
<PrivateRoute>
<Dashboard />
</PrivateRoute>
} />
</Routes>
</BrowserRouter>
)
}
Until now I launched my cookie modal through an informative button, but now I need it to be shown automatically when the application starts.
I can't find a way to do it without a button

how to perform parent action from child in react

I have parent & its 2 child component
Parent code:
import React from 'react';
import { Grid, CircularProgress } from '#mui/material';
import { useSelector } from 'react-redux';
import Angle from './Angle/Angle';
import CustomSnackbar from '../Snackbar/CustomSnackbar';
import useStyles from './styles';
const Angles = ({ setCurrentId }) => {
const angles = useSelector((state) => state.angles);
const [snackbarOpenProp, setSnackbarOpenProp] = React.useState(false);
const classes = useStyles();
const handleSnackBarCloseAction = () => {
setSnackbarOpenProp(false)
}
const handleAddToCartAction = () => {
console.log('click');
setSnackbarOpenProp(true)
}
return (
!angles.length ? <CircularProgress /> : (
<Grid className={classes.container} container alignItems="stretch" spacing={3}>
{angles.map((angle) => (
<Grid key={angle._id} item xs={12} sm={6} md={6}>
<Angle angle={angle} setCurrentId={setCurrentId} handleAddToCart={handleAddToCartAction}/>
</Grid>
))}
<CustomSnackbar openState={snackbarOpenProp} handleSnackBarCloseProp={handleSnackBarCloseAction}/>
</Grid>
)
);
};
export default Angles;
Child 1 code:
import React from 'react';
import { Card, CardActions, CardContent, CardMedia, Button, Typography } from '#mui/material';
import Add from '#mui/icons-material/Add';
import { useDispatch } from 'react-redux';
import useStyles from './styles';
const Angle = ({ angle, setCurrentId,handleAddToCart }) => {
const dispatch = useDispatch();
const classes = useStyles();
return (
<Card className={classes.card}>
<CardMedia className={classes.media} image={angle.image} />
<div className={classes.overlay}>
<Typography variant="h6">{angle.qualityName}</Typography>
<Typography variant="body2">{angle.colors}</Typography>
</div>
<div className={classes.overlay2}>
<Button onClick={handleAddToCart} style={{ color: 'white' }} size="small" onClick={() => setCurrentId(angle._id)}><Add fontSize="large" /></Button>
</div>
</Card>
);
};
export default Angle;
Child 2 code:
import * as React from 'react';
import Button from '#mui/material/Button';
import Snackbar from '#mui/material/Snackbar';
import IconButton from '#mui/material/IconButton';
import CloseIcon from '#mui/icons-material/Close';
export default function CustomSnackbar(props) {
const action = (
<React.Fragment>
<Button color="secondary" size="small" onClick={props.handleSnackBarCloseProp}>
UNDO
</Button>
<IconButton
size="small"
aria-label="close"
color="inherit"
onClick={props.handleSnackBarCloseProp}
>
<CloseIcon fontSize="small" />
</IconButton>
</React.Fragment>
);
return (
<div>
<Snackbar
open={props.openState}
autoHideDuration={6000}
onClose={props.handleSnackBarCloseProp}
message="Note archived"
action={action}
/>
</div>
);
}
As you can see, I am trying to attach the onClick event which is in Child1 Angle code & based on its click I am trying to change a state value of another child2 CustomSnackbar and sending it as a prop, but on clicking I am not getting a response, How can I do it, also is there any more simple way to achieve this ?
There are two onClick methods on the button component. Please change according below example and try it.
Before:
<Button onClick={handleAddToCart} style={{ color: 'white' }} size="small" onClick={() => setCurrentId(angle._id)}><Add fontSize="large" /></Button>
After:
<Button
style={{ color: 'white' }}
size="small"
onClick={() => {
handleAddToCart();
setCurrentId(angle._id)
}
}>
<Add fontSize="large" />
</Button>

Dynamic input fields in React using functional component

I am trying to create dynamic input fields in my react application(using Material UI) on the click of a button. Whenever the add button is clicked, it creates a new input field inside a dialog box but I can't seem to enter any values in the text-field. Following is my app.js file -
import React from "react";
import "./styles.css";
import Button from "#material-ui/core/Button";
import TextField from "#material-ui/core/TextField";
import Dialog from "#material-ui/core/Dialog";
import DialogActions from "#material-ui/core/DialogActions";
import DialogContent from "#material-ui/core/DialogContent";
import DialogContentText from "#material-ui/core/DialogContentText";
import DialogTitle from "#material-ui/core/DialogTitle";
import IconButton from "#material-ui/core/IconButton";
import DeleteIcon from "#material-ui/icons/Delete";
import { Box, Grid } from "#material-ui/core";
export default function App() {
const [open, setOpen] = React.useState(false);
const [values, setValues] = React.useState([]);
const [text, setText] = React.useState("");
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
setValues([]);
};
const handleChangeText = (e) => {
setText(e.target.value);
};
const addValue = () => {
setValues([...values, ""]);
};
const handleValueChange = (index, e) => {
values[index] = e.target.value;
console.log(values);
setValues(values);
};
const deleteValue = (jump) => {
setValues(values.filter((j) => j !== jump));
};
return (
<div>
<Button variant="outlined" color="primary" onClick={handleClickOpen}>
Create
</Button>
<Dialog
open={open}
onClose={handleClose}
aria-labelledby="form-dialog-title"
>
<DialogTitle id="form-dialog-title">New Dialog</DialogTitle>
<DialogContent>
<DialogContentText>Sample Text.</DialogContentText>
<TextField
autoFocus
margin="dense"
value={text}
onChange={handleChangeText}
label="Text"
fullWidth
/>
{values.map((jump, index) => (
<Box key={"jump" + index}>
<Grid container spacing={1} alignItems="flex-end">
<Grid item xs={10}>
<TextField
autoFocus
margin="dense"
label="Value"
value={jump || ""}
onChange={(e) => handleValueChange(index, e)}
fullWidth
/>
</Grid>
<Grid item xs={2}>
<div
className="font-icon-wrapper"
onClick={() => deleteValue(jump)}
>
<IconButton aria-label="delete">
<DeleteIcon />
</IconButton>
</div>
</Grid>
</Grid>
</Box>
))}
</DialogContent>
<Button onClick={addValue} color="primary">
Add
</Button>
<DialogActions>
<Button onClick={handleClose} variant="contained" color="secondary">
Cancel
</Button>
<Button onClick={handleClose} variant="contained" color="primary">
Create
</Button>
</DialogActions>
</Dialog>
</div>
);
}
Here is the code sandbox link.
I have a simple text field inside the dialog box also that works perfectly. The problem is with the dynamic fields. I don't know what mistake I am making in this code. Someone please help me out. Thanks in advance
You a have problem in the function handleValueChanges, don't use mutation use immutable data.
the correct code:
const handleValueChange = (index, e) => {
const updatedValues = values.map((value, i) => {
if(i === index) {
return e.target.value
}else {
return value
}
})
setValues(updatedValues);
};
You can test from here: https://codesandbox.io/s/dynamic-textfield-forked-gck25?file=/src/App.js

Map not re-rendering

I am trying to use the map function but it wont rerender my select box with the updated selected value.
The filter is on a material ui dialog that pops up when you view a file. The values will update when i close the modal and reopen it but wont update if i dont close the window. Any help would be greatly appriciated.
import React, { useEffect, useState } from 'react';
import Grid from '#material-ui/core/Grid';
import Paper from '#material-ui/core/Paper';
import InputLabel from '#material-ui/core/InputLabel';
import FormControl from '#material-ui/core/FormControl';
import Select from '#material-ui/core/Select';
import { makeStyles } from '#material-ui/core/styles';
import MenuItem from '#material-ui/core/MenuItem';
import filter from '../../../constants/filter-options';
export default function KeywordFilter(props) {
const [selectedFilter, setFilter] = useState(props.selectedFilter);
const [filterOptions, setFilterOptions] = useState(filter);
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1
},
paper: {
padding: theme.spacing(2),
textAlign: 'center',
color: theme.palette.text.primary,
},
modal: {
height: '80vh',
width: '40vw',
maxWidth: '40vw'
}
}));
const classes = useStyles();
const handleChange = (event, keyword) => {
var temp = selectedFilter;
temp[keyword] = event.target.value;
console.log("TEMP: ", temp)
console.log("keywordList: ", keywordList)
props.onFilterChange(temp);
setFilter(temp)
setFilterOptions(filter)
};
const keywordList = Object.keys(filterOptions)
return (
<div key={keywordList}>
<h4 style={{textAlign:'center'}}>Filters: </h4>
<Grid container spacing={3}>
{keywordList.map((keyword) => {
return (
<Grid item xs={6}>
{console.log("selectedFilter: ", selectedFilter)}
<Paper className={classes.paper}>
{keyword}: <FormControl className={classes.formControl}>
<Select
key={keyword}
labelId="demo-simple-select-label"
id="demo-simple-select"
value={selectedFilter[keyword] ? selectedFilter[keyword] : "None"}
onChange={(e) => handleChange(e, keyword)}
>
{filterOptions[keyword].map(element => <MenuItem value={element}>{element}</MenuItem>)}
</Select>
</FormControl>
</Paper>
</Grid>
)}
)}
</Grid>
</div>
);
}
The filter file looks like the following:
const filter =
{
Schedule : ["None", "Monthly", "Quarterly", "Semi-Annually", "Annually"],
Chemical : ["None", "Copper", "Phosphorus"],
Color : ["None", "Black", "Blue"]
}
export default filter;
It turns out I was modifying the state directly and that was creating a bunch of issues. The following changes to the handleChange function and removing unnecessary code fixed the issue:
import React, { useEffect, useState } from 'react';
import Grid from '#material-ui/core/Grid';
import Paper from '#material-ui/core/Paper';
import FormControl from '#material-ui/core/FormControl';
import Select from '#material-ui/core/Select';
import { makeStyles } from '#material-ui/core/styles';
import MenuItem from '#material-ui/core/MenuItem';
import filter from '../../../constants/filter-options';
export default function KeywordFilter(props) {
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1
},
paper: {
padding: theme.spacing(2),
textAlign: 'center',
color: theme.palette.text.primary,
},
modal: {
height: '80vh',
width: '40vw',
maxWidth: '40vw'
}
}));
const classes = useStyles();
const handleChange = (event, keyword) => {
//deep copy selected filters to avoid directly changing state
const target = JSON.parse(JSON.stringify(props.selectedFilter))
//set new value to add
const source = { [keyword]: event.target.value};
//merge the 2 objects (this will update target aswell)
const results = Object.assign(target, source)
//update state
props.onFilterChange(results)
};
return (
<>
<h4 style={{textAlign:'center'}}>Filters: </h4>
<Grid container spacing={3}>
{Object.keys(filter).map((keyword) => {
return (
<Grid item xs={6}>
<Paper className={classes.paper}>
{keyword}: <FormControl className={classes.formControl}>
<Select
key={keyword}
labelId="demo-simple-select-label"
id="demo-simple-select"
value={props.selectedFilter[keyword] ? props.selectedFilter[keyword] : "None"}
onChange={(e) => handleChange(e, keyword)}
>
{filter[keyword].map(element => <MenuItem value={element}>{element}</MenuItem>)}
</Select>
</FormControl>
</Paper>
</Grid>
)}
)}
</Grid>
</>
);
}

Using axios to make use of a service not working

I'm trying to use S3 service to upload an image and it's telling me that certain variables aren't defined when I have defined them. I have imported axios and all the other stuff that are required
import React, { useState } from "react";
import ReactDOM from "react-dom";
import axios from "axios";
import Grid from "#material-ui/core/Grid";
import Button from "#material-ui/core/Button";
import Card from "#material-ui/core/Card";
import TextField from "#material-ui/core/TextField";
import CreateIcon from "#material-ui/icons/Create";
import Box from "#material-ui/core/Box";
import CardMedia from "#material-ui/core/CardMedia";
import MuiAlert from "#material-ui/lab/Alert";
import Snackbar from "#material-ui/core/Snackbar";
import { withStyles } from "#material-ui/core/styles";
import { makeStyles } from "#material-ui/core/styles";
import Chip from "#material-ui/core/Chip";
import Avatar from "#material-ui/core/Avatar";
import Slider from "#material-ui/core/Slider";
import Typography from "#material-ui/core/Typography";
import InputAdornment from "#material-ui/core/InputAdornment";
import { connect } from "react-redux";
function mapStateToProps(state) {
return {};
}
const useStyles = makeStyles((theme) => ({
root: {
"& > *": {
margin: theme.spacing(1),
marginLeft: theme.spacing(15),
},
},
input: {
display: "none",
},
}));
const useSliderStyles = makeStyles({
root: {
width: 250,
},
input: {
width: 100,
},
});
const UploadButton = () => {
const classes = useStyles();
return (
<div className={classes.root}>
<input
accept='image/*'
className={classes.input}
id='contained-button-file'
multiple
type='file'
/>
<label htmlFor='contained-button-file'>
<Button variant='contained' color='primary' component='span'>
Upload
</Button>
</label>
</div>
);
};
const StyledCard = withStyles({
root: { height: 600, width: 350 },
})(Card);
const PetitionForm = () => {
const [title, setTitle] = useState("");
const [description, setDescription] = useState("");
const [open, setOpen] = useState(false);
const [petition, validPetition] = useState(false);
const [noTitle, titleError] = useState(false);
const [noDescription, descriptionError] = useState(false);
const [hashtag, setHashtag] = useState("");
const [arrayOfHashtags, addHashtag] = useState([]);
const [money, setMoney] = React.useState(500);
const slider = useSliderStyles();
const handleTitleChange = (event) => setTitle(event.target.value);
const handleDescriptionChange = (event) => setDescription(event.target.value);
const handleClose = (event, reason) => {
if (reason === "clickaway") {
return;
}
};
const Alert = (props) => (
<MuiAlert elevation={6} variant='filled' {...props} />
);
const clearField = (event) => {
setOpen(true);
if (title.length > 0 && description.length > 0) {
validPetition(true);
setTitle("");
setDescription("");
addHashtag([]);
setHashtag("");
axios({
url: `call/s3/backend`,
method: "post",
data: {
images: imageArray.toByteArray(),
},
})
.then((res) => {
imageUrlArr = res.data;
axios({
url: `api/petition_posts`,
method: "post",
data: {
petition_post: {
title: title,
description: description,
hashtags: arrayOfHashtags.join(" "),
amount_donated: 0,
media: imageUrlArr,
goal: money,
card_type: "petition",
org_profile_id: 1,
},
},
})
.then((res) => {
console.log(res.data);
})
.catch((error) => console.log(error));
})
.catch((error) => console.log(error));
}
titleError(true ? title.length === 0 : false);
descriptionError(true ? description.length === 0 : false);
};
const handleDelete = (h) => () => {
addHashtag((arrayOfHashtags) =>
arrayOfHashtags.filter((hashtag) => hashtag !== h)
);
};
const handleHashtagChange = (event) => setHashtag(event.target.value);
const handleSliderChange = (event, newValue) => {
setMoney(newValue);
};
const handleInputChange = (event) => {
setMoney(event.target.value === "" ? "" : Number(event.target.value));
};
const newHashtag = () => {
if (arrayOfHashtags.length < 3) {
addHashtag((arrayOfHashtags) => arrayOfHashtags.concat(hashtag));
} else {
console.log("Too many hashtags");
}
};
const Hashtags = arrayOfHashtags.map((h) => (
<Chip
key={h.length}
size='small'
avatar={<Avatar>#</Avatar>}
label={h}
onDelete={handleDelete(h)}
/>
));
return (
<StyledCard>
<Box mt={1}>
<Grid container justify='center'>
<TextField
id='outlined-multiline-static'
multiline
rows={1}
variant='outlined'
placeholder='Title'
value={title}
onChange={handleTitleChange}
helperText={
open // only displays helper text if button has been clicked and fields haven't been filled
? !noTitle || petition
? ""
: "Can't be an empty field"
: ""
}
/>
</Grid>
</Box>
<Box mt={1}>
<Grid container justify='center'>
<CardMedia title='Petition'>
<UploadButton />
</CardMedia>
</Grid>
</Box>
<div className={slider.root}>
<Typography>Amount to raise</Typography>
<Box>
<Grid container justify='center'>
<Slider
min={500}
max={10000}
value={typeof money === "number" ? money : 0}
onChange={handleSliderChange}
aria-labelledby='input-slider'
/>
<TextField
className={slider.input}
value={money}
onChange={handleInputChange}
InputProps={{
startAdornment: (
<InputAdornment position='start'>$</InputAdornment>
),
}}
helperText={
money < 500 || money > 10000
? "Please enter a value between 500 and 10000"
: ""
}
/>
</Grid>
</Box>
</div>
<Box mt={1} mb={1}>
<Grid container justify='center'>
<TextField
size='small'
inputProps={{
style: { fontSize: 15 },
}}
id='outlined-multiline-static'
multiline
rows={1}
placeholder='Hashtags'
variant='outlined'
value={hashtag}
onChange={handleHashtagChange}
helperText={
arrayOfHashtags.length === 3
? "You reached the maximum amount of hashtags"
: ""
}
/>
<Button color='primary' onClick={newHashtag}>
Create!
</Button>
{arrayOfHashtags.length > 0 ? Hashtags : ""}
</Grid>
</Box>
<Box mt={1} justify='center'>
<Grid container justify='center'>
<TextField
size='small'
inputProps={{
style: { fontSize: 15 },
}}
id='outlined-multiline-static'
multiline
rows={5}
placeholder='Description'
variant='outlined'
value={description}
onChange={handleDescriptionChange}
helperText={
// only displays helper text if button has been clicked and fields haven't been filled
open
? !noDescription || petition
? ""
: "Can't be an empty field"
: ""
}
/>
</Grid>
</Box>
<Box mt={1}>
<Grid container justify='center'>
<Button onClick={clearField}>
<CreateIcon />
Create Petition!
</Button>
{open && petition && (
<Snackbar open={open} autoHideDuration={2000} onClose={handleClose}>
<Alert severity='success'>
You have successfully create a petition!
</Alert>
</Snackbar>
)}
{open && !petition && (
<Snackbar open={open} autoHideDuration={2000} onClose={handleClose}>
<Alert severity='error'>You're missing one or more fields</Alert>
</Snackbar>
)}
</Grid>
</Box>
</StyledCard>
);
};
export default connect(mapStateToProps)(PetitionForm);
This is the error I'm getting, someone mentioned something about the scope and I think that shouldn't matter when I'm trying to assign a value to a variable as far I as know
Line 109:19: 'imageArray' is not defined no-undef
Line 113:11: 'imageUrlArr' is not defined no-undef
Line 123:24: 'imageUrlArr' is not defined no-undef
Search for the keywords to learn more about each error.

Categories