i am trying to create a sidebar with drop down
like this example in react js
https://www.w3schools.com/howto/howto_js_dropdown_sidenav.asp
i was able to design it using react the issue is that when i click on a inner li
the dropdown closes i dont want it to close
this.state = { isOpen: false, }
Clickhandler() {
this.setState({ isOpen: !this.state.isOpen });
}
<li style={styles.listItem}
onClick={this.Clickhandler}
className={this.state.isOpen ? "admintabs" : ""}
>
<div>
<FontAwesomeIcon
icon={faHistory}
style={{ marginRight: "1rem" }}
/>
</div>
<div> Internal users</div>
<div>
{" "}
<FontAwesomeIcon icon={faCaretDown} />
</div>
</li>
{this.state.isOpen ? (
<>
<NavLink
to="/admin/saler"
activeClassName="active3"
onClick={this.Clickhandler}
>
<li style={styles.listItem}>
<div>
<FontAwesomeIcon
icon={faCube}
style={{ marginRight: "1rem" }}
/>
</div>
<div> saler</div>
</li>
</NavLink>
<NavLink
to="/admin/con"
activeClassName="active3"
onClick={this.Clickhandler}
>
<li style={styles.listItem}>
<div>
<FontAwesomeIcon
icon={faBriefcaseMedical}
style={{ marginRight: "1rem" }}
/>
</div>
<div> Con</div>
</li>
</NavLink>
</>
) : null}
my code is too big so i added in codesand box
https://codesandbox.io/s/stupefied-hooks-9qm66s?file=/src/App.js
Related
How can I center the Navbar.Brand on top of the Navbar.Items.
Any help would be much appreciated as I am new to StackOverflow and new to React.js.
I've tried to edit the orientation with this through the Navbar styling in my css file but that has not been much help to me either.
This is what it currently looks like
This is the orientation that Im looking for
'''
function NavBar() {
const [expand, updateExpanded] = useState(false);
const [navColour, updateNavbar] = useState(false);
function scrollHandler() {
if (window.scrollY >= 20) {
updateNavbar(true);
} else {
updateNavbar(false);
}
}
window.addEventListener("scroll", scrollHandler);
return (
<Navbar
expanded={expand}
fixed="top"
expand="md"
className={navColour ? "sticky" : "navbar"}
>
<Container>
<Navbar.Brand href="/" className="d-flex">
<img src={logo} className="img-fluid logo" alt="brand" />
</Navbar.Brand>
<Navbar.Toggle
aria-controls="responsive-navbar-nav"
onClick={() => {
updateExpanded(expand ? false : "expanded");
}}
>
<span></span>
<span></span>
<span></span>
</Navbar.Toggle>
<Navbar.Collapse id="responsive-navbar-nav">
<Nav className="mx-auto" defaultActiveKey="#home">
<Nav.Item>
<Nav.Link as={Link} to="/" onClick={() => updateExpanded(false)}>
<AiOutlineHome style={{ marginBottom: "2px" }} /> Home
</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link
as={Link}
to="/about"
onClick={() => updateExpanded(false)}
>
<AiTwotoneEye style={{ marginBottom: "2px" }} /> The Story
</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link
as={Link}
to="/project"
onClick={() => updateExpanded(false)}
>
<FaFlask
style={{ marginBottom: "2px" }}
/>{" "}
The Lab
</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link
href="placeholder.com"
target="_blank"
rel="noreferrer"
>
<AiOutlineTrophy style={{ marginBottom: "2px" }} /> How To Join
</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link
href="placeholder.com"
target="_blank"
rel="noreferrer"
>
<FaDiceFive style={{ marginBottom: "2px" }} /> More
</Nav.Link>
</Nav.Item>
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
);
}
'''
I need some help pls. I created a menu with section and courses; but the section-labels are repeating.
I would like all courses with the same section to be displayed on a single section lable.
Please see code and screenshot.
<Menu
defaultSelectedKeys={[clicked]}
inlineCollapsed={collapsed}
style={{ height: "100vh", overflow: "scroll" }}
mode="inline"
>
{course.lessons.map((lesson, index) => (
<SubMenu
title={lesson.section}>
<ItemGroup
key={index}>
<Item
onClick={() => setClicked(index)}
key={index}
icon={<Avatar>{index + 1}</Avatar>}
>
{lesson.title.substring(0, 30)}
{" "}
{completedLessons.includes(lesson._id) ? (
<CheckCircleFilled
className="float-end text-primary ml-2"
style={{ marginTop: "13px" }}
/>
) : (
<MinusCircleFilled
className="float-end text-danger ml-2"
style={{ marginTop: "13px" }}
/>
)}
</Item>
</ItemGroup>
</SubMenu>
))}
</Menu>
Screenshot of the Menu
You need to group the lessons by section, then you must iterate over each lessons in the section.
Here is a possible solution :
// group lessons by section into an object {sectionName: [lesson1, lesson2]}
const lessonsBySection = course.lessons.reduce(function(obj, lesson) {
(obj[lesson.section] = obj[lesson.section] || []).push(lesson);
return obj;
}, {});
// get all the sections (sorted alphabetically)
const sections = Object.keys(lessonsBySection).sort();
return (
<Menu ...>
{sections.map((section, sectionIndex) => (
<SubMenu key={section} title={section}>
<ItemGroup>
{lessonsBySection[section].map((lesson, lessonIndex) => (
<Item
key={lesson._id}
onClick={() => setClicked(
courses.lessons.findIndex(l => l._id === lesson._id)
)}
icon={<Avatar>{lessonIndex + 1}</Avatar>}
>
...
</Item>
))}
</ItemGroup>
</SubMenu>
))}
</Menu>
)
Ant modal appears few times, but if i remove map function inside the modal then its works fine its appears only one time.
what may be the issue? please help me to solve this issue (Modal triggering/appears few times)
Ant modal code follows:
const [visibleVoucherModal, setVisibleVoucherModal] = useState(false);
const showVoucherModal = () => {
setVisibleVoucherModal(true)
}
const closeVoucherModal = () => {
setVisibleVoucherModal(false);
};
const SavedVoucherModal = () => {
return (
<Modal title="Select Any Voucher" visible={visibleVoucherModal} onCancel={closeVoucherModal} footer={null} >
{savedVoucherList.length >= 1 ?
<div>
<Checkbox.Group className="w-100" onChange={checkBox} value={voucherVal} >
{savedVoucherList.map((item, i) => {
return (
<div key={i}>
<Checkbox value={item.Id} className="w-100" onChange={e => { handleCheckBox(e, i) }}
checked={checked[i] || true} disabled={!checked[i] && disabled} >
<div className="pl-4">
<List.Item style={{ marginTop: "-35px" }} className="py-0">
<List.Item.Meta
// avatar={<img src={item.Photo == '' ? 'd' : item.Photo} alt="" width="72" />}
title={<span style={{ fontSize: "12px" }}>{item.Name}</span>}
description={<div className="small">Expiry Date: <br />{item.ExpireDate.slice(0, 10)}</div>}
/>
<div className="pt-1">
<p className="font-weight-bold text-primary mb-0">{numberFormat(item.Price)}</p>
<small><del>{numberFormat(item.OldPrice)}</del></small>
</div>
</List.Item>
</div>
</Checkbox>
<Divider className="m-0 p-0 mb-4" />
</div>)
})}
</Checkbox.Group>
</div> :
<p className="mb-4">Oops, there is no voucher applicable to this order</p>
}
<Button type="primary" className="font-weight-bold btn-round" onClick={closeVoucherModal}>Close</Button>
</Modal>
)
}
Button:
<Button type="default" className="text-primary border-right-0 border-left-0" size="large" onClick={showVoucherModal}>Redeem Voucher</Button>
I am trying to make a card grid where the user can expand the card to view its details. The issue I am facing with the react hooks is that the function is getting called for all cards instead of the particular card I am clicking the button. As a result, all the cards are getting expanded.
Here's my code for reference.
Any help is highly appreciated. Thank you!
function Album(props) {
return (
<div>
<Card className={classes.card}>
<Card.Text >
<p className={classes.heading}>
{props.blogTitle}
</p>
</Card.Text>
<Card.Body>
<Card.Img
src={props.imgsrc}
alt="Card image"
className={classes.cardMedia}
/>
{props.cardOpen &&
<AnimatePresence>
<motion.div
initial={{opacity:0}}
animate={{opacity:1, transition:0.3}}
>
<p className={classes.desc} gutterbottom>
{props.blogDescription}
</p>
<div href={props.blogLink}
style={{color:"gray", fontSize:17, fontFamily:"calibri", fontSmooth: "auto", cursor:"pointer", display:"flex", justifyContent:"center"}}>
<LocalLibraryIcon style={{marginRight:7}}/>Read blog
</div>
</motion.div>
</AnimatePresence>
}
{(props.cardOpen) ?
<div onClick={props.isOpen} style={{float:"right", cursor:"pointer"}}>
<ExpandLessIcon style={{fontSize:40, marginTop:10, color:" #909090"}}/>
</div> : (
<div onClick={props.isOpen} style={{float:"right", cursor:"pointer"}}>
<ExpandMoreIcon style={{fontSize:40, marginTop:10, color:" #909090"}}/>
</div>
)}
</Card.Body>
</Card>
</div>
);
}
export default function ProjectItems() {
const [cardOpen, setCardOpen]= useState(false);
return (
<React.Fragment>
<CssBaseline />
<main>
<div className={classes.heroContent}>
<Container maxWidth="md">
<Typography
variant="h2"
align="center"
color="textPrimary"
className={classes.root}
gutterBottom
>
Blogs
</Typography>
</Container>
</div>
<Container maxWidth="md">
<Grid container spacing={4}>
{blogData.map(post => (
<Grid item xs={12} sm={6} md={4} key={post.id}>
<div>
<Album
blogId={post.id}
blogTitle={post.title}
blogDescription={post.summary}
imgsrc={post.image_link}
blogLink={post.article_link}
isOpen={()=>{
setCardOpen(!cardOpen);
}}
cardOpen={cardOpen}
/>
</div>
</Grid>
))}
</Grid>
</Container>
</main>
</React.Fragment>
);
}
I am stuck in this problem. I want to add/remove the class on a header element on scroll, but somehow I can not manage it.
I tried to mount and unmount (found few solutions here on Stack) but does not work in my case. Simply because in most of those cases the code relates to component but I have a little bit different set-up.
Here the full code:
https://codesandbox.io/s/angry-villani-lduor?fontsize=14
I want to add the new class on store_details_header
const handleChangeIndex = index => {
setValue(index);
};
if (!selectedStore) {
return null;
}
return (
<div className="store-details">
<div className="store-details__header" style={{ backgroundImage: `url(${selectedStore.headerBackgroundImgUrl})` }}>
<img className="store-details__header__exit" src={exit} alt="exit" onClick={backToNearYou} />
<img className="store-details__header__logo" src={selectedStore.headerLogoUrl} alt="logo" />
</div>
<div className="store-details__content" style={{ backgroundImage: `url(${selectedStore.contentBackgroundImgUrl})` }}>
<div>
<AppBar className={props.classes.root} position="static" color="default">
<Tabs value={value} classes={{ indicator: props.classes.indicator }} onChange={setSelectedNavigationItem} variant="fullWidth">
<StyledTab label="Products" />
<StyledTab label="Items" />
</Tabs>
</AppBar>
<SwipeableViews axis={'x'} index={value} onChangeIndex={handleChangeIndex}>
<TabContainer>
{' '}
<div className="store-details__content__items">{renderSliderItems()}</div>
</TabContainer>
<TabContainer>
{' '}
<div className="store-details__content__items">{renderSliderItems()}</div>
</TabContainer>
</SwipeableViews>
</div>
</div>
{guestMode && renderGuestModeBox()}
{selectedStore.loyaltyCard && renderLoyaltyCard()}
</div>
);
};
const handleChangeIndex = index => {
setValue(index);
};
if (!selectedStore) {
return null;
}
return (
<div className="store-details">
<div className="store-details__header" style={{ backgroundImage: `url(${selectedStore.headerBackgroundImgUrl})` }}>
<img className="store-details__header__exit" src={exit} alt="exit" onClick={backToNearYou} />
<img className="store-details__header__logo" src={selectedStore.headerLogoUrl} alt="logo" />
</div>
<div className="store-details__content" style={{ backgroundImage: `url(${selectedStore.contentBackgroundImgUrl})` }}>
<div>
<AppBar className={props.classes.root} position="static" color="default">
<Tabs value={value} classes={{ indicator: props.classes.indicator }} onChange={setSelectedNavigationItem} variant="fullWidth">
<StyledTab label="Products" />
<StyledTab label="Items" />
</Tabs>
</AppBar>
<SwipeableViews axis={'x'} index={value} onChangeIndex={handleChangeIndex}>
<TabContainer>
{' '}
<div className="store-details__content__items">{renderSliderItems()}</div>
</TabContainer>
<TabContainer>
{' '}
<div className="store-details__content__items">{renderSliderItems()}</div>
</TabContainer>
</SwipeableViews>
</div>
</div>
{guestMode && renderGuestModeBox()}
{selectedStore.loyaltyCard && renderLoyaltyCard()}
</div>
);
};