Use multiple checkbox to show/hide multiple input fields with React - javascript

For each checkbox i need to show/hide values in a dialog.
The code for adding and removing selecteditems is working.
How can I show each input after the checkbox with React hide/show for multiple fields?
The React is correct and if the second function is removed from the JS code this will work with the first checkbox and input... but, I don't know how to write the React code for multiple fields for this React structure.
Image
Here is the code
const [selectedItems, setSelectedItems] = React.useState<any>([]);
const handleToggle = (record: any) => () => {
const currentIndex = selectedItems.indexOf(record);
const newChecked = [...selectedItems];
if (currentIndex === -1) {
newChecked.push(record);
} else {
newChecked.splice(currentIndex, 1);
}
setSelectedItems(newChecked);
};
This is view
<Dialog
open={open}
onClose={handleClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
PaperProps={{
style: {
width: 500,
backgroundColor: "#222",
color: "white"
}
}}
maxWidth="lg"
>
<DialogContent>
<List sx={{ width: '100%', maxWidth: 500 }}>
{expensesType.map((record: any) => {
const labelId = `checkbox-list-label-${record.id}`;
return (
<ListItem
key={record}
secondaryAction={showInput(record)}
>
<ListItemButton role={undefined} onClick={handleToggle(record)} dense>
<ListItemIcon>
<Checkbox
edge="start"
checked={selectedItems.indexOf(record) !== -1}
tabIndex={-1}
value={record.value}
disableRipple
inputProps={{ 'aria-labelledby': labelId }}
/>
</ListItemIcon>
<ListItemText id={labelId} primary={record.name} />
</ListItemButton>
</ListItem>
);
})}
</List>
</DialogContent>
<DialogActions>
<Button onClick={handleClose}>Cancel</Button>
<Button onClick={handleClose} autoFocus>
Done
</Button>
</DialogActions>
</Dialog>

Related

unable to set state in react for provided situation

i am building a ecommerce web app with react and i am unable to set state profileOptionsLayer when i click on the highlighted listitem both the logs are displayed on the console but component dosent rerender and state "profileOptionsLayer" is not updated either ,i am unable to locate the reason need help!
ALL imports .....
const TemporaryDrawer = ({
profileDrawerlayer,
setprofileDrawerlayer,
setuserDetails,
userDetails,
}) => {
const [profileOptionsLayer, setprofileOptionsLayer] = useState();
console.log(profileOptionsLayer);
return (
<>
<Drawer
anchor={"right"}
open={profileDrawerlayer}
onClose={() => {
setprofileDrawerlayer(false);
}}
>
<Box
sx={{ width: 250, background: "lightblue", height: "100%" }}
role="presentation"
onClick={() => {
setprofileDrawerlayer(false);
}}
onKeyDown={() => {
setprofileDrawerlayer(false);
}}
>
<List>
////////////////////////////////////// Below ///////////////////////////////////////////////
<ListItem disablePadding>
<ListItemButton
onClick={() => {
console.log("dsadsa");
setprofileOptionsLayer("View"); <= unable to set this state
console.log(profileOptionsLayer);
console.log("dsadsa");
}}
>
<ListItemIcon>
<VisibilityIcon />
</ListItemIcon>
<ListItemText primary={"View Profile"} />
</ListItemButton>
</ListItem>
/////////////////////////////////////// UP /////////////////////////////////////////
<ListItem
disablePadding
onClick={() => {
localStorage.removeItem("userId");
setuserDetails("");
}}
>
<ListItemButton>
<ListItemIcon>
<LogoutIcon />
</ListItemIcon>
<ListItemText primary={"Logout"} />
</ListItemButton>
</ListItem>
</List>
<Divider />
</Box>
</Drawer>
{profileOptionsLayer &&<ProfileOptions {...{ userDetails }} />}
</>
);
};
export default TemporaryDrawer;

Implementing a Modal inside a Drawer in Material UI

I'm using Material UI and im trying to make a Modal pop up from a Responsive Drawer component. The problem is that when i click on the button, the Modal is rendered and instantly closed. I think that is because of the closing animation of the modal.
I tried a lot of workarounds, played with the z-index a little bit but nothing is working. Any ideas? This is the Modal code:
<div>
<Button
onClick={handleOpen}
sx={{
backgroundColor: "black",
color: "white",
borderBottom: "1px solid #f14d59",
borderRadius: "0px",
}}
>
Log In
</Button>
<Modal
open={open}
onClose={handleClose}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
>
<Box sx={style} className="modal-box">
<button className="close-popup" onClick={handleClose}>
x
</button>
<Validations />
</Box>
</Modal>
</div>
and this is the Drawer:
const toggleDrawer = (anchor, open) => (event) => {
if (
event.type === "keydown" &&
(event.key === "Tab" || event.key === "Shift")
) {
return;
}
setState({ ...state, [anchor]: open });
};
const list = (anchor) => (
<Box
sx={{
width: 250,
}}
role="presentation"
onClick={toggleDrawer(anchor, false)}
onKeyDown={toggleDrawer(anchor, false)}
>
<List>
{icons.map((icon) => (
<a to={icon.route} key={icon.title} href={icon.href}>
<ListItem disablePadding>
<ListItemButton>
<ListItemIcon sx={{ color: "#f14d59" }}>
<icon.icon />
</ListItemIcon>
<ListItemText
primary={icon.title}
sx={{ color: "#f14d59", fontWeight: "700" }}
/>
</ListItemButton>
</ListItem>
</a>
))}
</List>
<Divider sx={{ backgroundColor: "lightgrey" }} />
<List>
<ListItem disablePadding>
<ListItemButton>
<Modal />
</ListItemButton>
</ListItem>
</List>
</Box>
);
<nav>
<React.Fragment key={"left"}>
<Button onClick={toggleDrawer("left", true)}>
<MenuIcon sx={{ color: "white" }} />
</Button>
<Drawer
anchor={"left"}
open={state["left"]}
onClose={toggleDrawer("left", false)}
>
{list("left")}
</Drawer>
</React.Fragment>
</nav>

Material-table with MUI full screen dialog

Problem: Clicking a button in my material-table it opens the full screen dialog then closing the dialog, Then I am not able to click anywhere in the screen anymore. The dialog's wrapper container blocking the whole screen.
My material ui table component:
export default function MyMaterialTable() {
const columns = [
// columns here
];
const [myState, setModalState] = React.useState(false);
function modalHandleClick() {
setModalState(!myState);
}
return (
<div>
<MaterialTable
title="My Material Table"
columns={columns} data={tableData} // Retreived via api
options={{
selection: true,
filtering: true,
paging: true
}}
actions={[
{
tooltip: 'Action button that triggers the Fullscreen Dialog',
icon: () => {return(<AddBoxIcon /> )},
onClick: (evt, data) => modalHandleClick()
}
]}
/>
<MyFullScreenDialog modalState={myState} modalHandleClick={modalHandleClick} />
</div>
);
}
My Full Screen dialog component:
export default function MyFullScreenDialog (props) {
const Transition = React.forwardRef(function Transition(p, ref) {
return <Slide direction="up" ref={ref} {...p} />;
});
const handleClose = () => {
props.modalHandleClick();
};
return(
<div>
<Dialog
fullScreen
open={props.modalState}
onClose={handleClose}
TransitionComponent={Transition}
>
<AppBar sx={{ position: 'relative' }}>
<Toolbar>
<IconButton
edge="start"
color="inherit"
onClick={handleClose}
aria-label="close"
>
<CloseIcon />
</IconButton>
<Typography sx={{ ml: 2, flex: 1 }} variant="h6" component="div">
Sound
</Typography>
<Button autoFocus color="inherit" onClick={handleClose}>
save
</Button>
</Toolbar>
</AppBar>
<List>
<ListItem button>
<ListItemText primary="Phone ringtone" secondary="Titania" />
</ListItem>
<Divider />
<ListItem button>
<ListItemText
primary="Default notification ringtone"
secondary="Tethys"
/>
</ListItem>
</List>
</Dialog>
</div>
);
}
I am following these guides:
FullScreen Dialog MUI
Material Table
I think the problem is in your Transition.
Try declaring the const Transition in a global context, outside the class declaration.
In your Fullscreen component:
const Transition = React.forwardRef(function Transition(p, ref) {
return <Slide direction="up" ref={ref} {...p} />;
});
export default function MyFullScreenDialog (props) {
const handleClose = () => {
props.modalHandleClick();
};
return(
<div>
...

Button onclick move next tab in react js

I have a vertical tab and Next and Back buttons like in my react application. i want to move forward and backward tab using button click like stepper. if i click "next button" move to next tab. and the same if i click "back button" move to back tab.
and additionally, how to get data from this all tabs?
here is my tried code..
import React from "react";
import { useState } from "react";
export default function Products() {
const [value, setValue] = React.useState(0);
//Next tab button
function getSteps() {
return ["Shirt", "Hoodies", "Jeans", "Inner wear"];
}
const handleNext = () => {
setActiveStep((prevActiveStep) => prevActiveStep + 1);
};
const handleBack = () => {
setActiveStep((prevActiveStep) => prevActiveStep - 1);
};
const handleReset = () => {
setActiveStep(0);
};
const handleChange = (event, newValue) => {
setValue(newValue);
};
<Tabs
orientation="vertical"
variant="scrollable"
value={value}
onChange={handleChange}
aria-label="Vertical tabs"
activeStep={activeStep}
>
<Tab label="Shirt" {...a11yProps(0)} />
<Tab label="Hoodies" {...a11yProps(1)} />
<Tab label="Jeans" {...a11yProps(2)} />
<Tab label="Inner wear" {...a11yProps(3)} />
</Tabs>
<Form>
<TabPanel value={value} index={0}>Tab 1</TabPanel>
<TabPanel value={value} index={1}>Tab 2</TabPanel>
<TabPanel value={value} index={2}>Tab 3</TabPanel>
<TabPanel value={value} index={3}>Tab 4</TabPanel>
</Form>
{/* NEXT & SAVE BUTTONS */}
<Grid>
{activeStep === steps.length ? (
<div>
<Typography className={classes.instructions}>
Saved Successfully!
</Typography>
<Button
onClick={handleReset}
>
Reset
</Button>
</div>
) : (
<div>
<Button
variant="contained"
color="secondary"
disabled={activeStep === 0}
onClick={handleBack}
>
Back
</Button>
<Button
variant="contained"
color="primary"
// onClick={handleNext}
value={value}
onClick={handleChange}
>
{/* Continue */}
{activeStep === steps.length - 1 ? "Save & Update" : "Next"}
</Button>
</div>
)}
</Grid>
}

React and Material UI: how can I expand only one single card

I'm using React and Material UI in order to show some mapped cards mapped. When I try to expand a card, all the cards are expanded at the same time. I figured out that I have to pass an index inside my "handleExpandClick" function, but still not working. Maybe I did it some kind of typo.
I found this question Expand one card on click that regards the same problem, but seems not to be applied to my situation.
Here my piece of code:
const useStyles = makeStyles(theme => ({
card: {
maxWidth: 345,
marginBottom: 15
},
media: {
height: 0,
paddingTop: "56.25%" // 16:9
},
expand: {
transform: "rotate(0deg)",
marginLeft: "auto",
transition: theme.transitions.create("transform", {
duration: theme.transitions.duration.shortest
})
},
expandOpen: {
transform: "rotate(180deg)"
},
avatar: {
width: 90
},
root: {
display: "flex",
justifyContent: "center",
flexWrap: "wrap",
"& > *": {
margin: theme.spacing(0.5)
}
},
list: {
width: 200
}
}));
const ItininerariesList = ({ itineraries, activities }) => {
const classes = useStyles();
const [expanded, setExpanded] = React.useState(false);
let path = window.location.pathname;
let currentId = path.substring(path.lastIndexOf("/") + 1);
const itinerariesPerCity = itineraries.filter(
itiner => itiner.city_id === currentId
);
const handleExpandClick = () => {
setExpanded(!expanded);
};
return (
<Fragment>
{itinerariesPerCity.map((itinerary, i) => (
<Card className={classes.card} key={itinerary._id}>
<CardHeader
avatar={
<Grid
container
direction="column"
justify="flex-start"
alignItems="center"
className={classes.avatar}
>
<Avatar
aria-label="user"
alt={itinerary.profile_name}
src={itinerary.profile_img}
>
<PersonIcon />
</Avatar>
<Typography variant="caption" component="p">
{itinerary.profile_name}
</Typography>
</Grid>
}
action={
<IconButton aria-label="settings">
<MoreVertIcon />
</IconButton>
}
title={itinerary.title}
subheader={itinerary.sub_title}
/>
<CardContent>
</CardContent>
<CardActions disableSpacing>
<IconButton aria-label="add to favorites">
<FavoriteIcon />
</IconButton>
<IconButton aria-label="share">
<ShareIcon />
</IconButton>
<IconButton
className={clsx(classes.expand, {
[classes.expandOpen]: expanded
})}
onClick={() => handleExpandClick()}
aria-expanded={expanded}
aria-label="show more"
>
<ExpandMoreIcon />
</IconButton>
</CardActions>
<Collapse in={expanded} timeout="auto" unmountOnExit>
<CardContent>
<ActivitiesList
activities={activities}
itineraryId={itinerary._id}
/>
</CardContent>
</Collapse>
</Card>
))}
</Fragment>
);
};
export default ItininerariesList;
Any suggestions or guidance would be greatly appreciated. Thank you in advance.
In the expand handler you indeed have to pass the index. And also use it in the state.
Something like it:
const [expandedId, setExpandedId] = React.useState(-1);
...
const handleExpandClick = (i) => {
setExpandedId(expandedId === i ? -1 : i);
};
...
<CardContent />
<CardActions disableSpacing>
<IconButton aria-label="add to favorites">
<FavoriteIcon />
</IconButton>
<IconButton aria-label="share">
<ShareIcon />
</IconButton>
<IconButton
onClick={() => handleExpandClick(i)}
aria-expanded={expandedId === i}
aria-label="show more"
>
<ExpandMoreIcon />
</IconButton>
</CardActions>
<Collapse in={expandedId === i} timeout="auto" unmountOnExit>
<CardContent>
<div>ActivitiesList</div>
</CardContent>
</Collapse>
Here is a working example: https://codesandbox.io/s/eloquent-sara-wswrn

Categories

Resources