How to open active menu when user visit manually url - javascript

I think it might be silly question to ask but trust me I am new to React . Actually I am working on app where I have different collapsible menu. For example when I click on menu then dropdown show what I want to achieve when user copy manually link and put in the browser then I want to show specific menu . could someone please help me how to achieve this goal .
code
menus.map((item, index) => (
<UnlockAccess
currentUser={userType || null}
roles={item.roles}
key={index}
>
<div key={index}>
<p
onClick={() => {
this.RouteTo(`/${item.url}`);
this.toggle(item.id);
}}
className={`element ${this.state[item.activeTab]}`}
>
<span
className={
collapse === item.id ? "fa fa-minus" : "fa fa-plus"
}
key={index}
></span>
<p className={this.state[item.activeTab]}>
{item.name}
</p>
</p>
{collapse === item.id ? (
<div className="prop-child">
<ul>
{item.children.map((item, index) => (
<li
key={index}
className={this.state[item.activeTab]}
onClick={() =>
this.setState({ collapse: item.itemId }, () =>
this.toggle(item.itemId)
)
}
>
<Link
onClick={() => this.RouteTo(`/${item.url}`)}
to={item.url}
className={this.state[item.activeTab]}
>
{item.name}
</Link>
</li>
))}
</ul>
</div>
) : null}
toggle = (id) => {
if (!this.state.collapse || id !== this.state.collapse) {
this.setState({
collapse: id,
});
}
};

Just check the url params in the componentDidMount of your class. Then open the menu you want to be opened.

Related

How to optimize toggling className between different menu items by React?

I have header component, where I want to toggle className between all the elements of menu (if one of the elements of menu is active and user is clicking to another element - this element become active and all others no). I have a code like this
import React, { useState } from 'react';
import './header.scss';
export const Header = ({ favoriteCount }) => {
const [activeIndex, setActiveIndex] = useState(0);
function toggleClass(index) {
setActiveIndex(index);
}
return (
<header className="header">
<div className="container header-container">
<ul className="header-menu">
<li>
<a
className={
activeIndex === 0
? 'header-menu__link active'
: 'header-menu__link'
}
onClick={() => {
toggleClass(0);
}}
href="##"
>
Characters
</a>
</li>
<li>
<a
className={
activeIndex === 1
? 'header-menu__link active'
: 'header-menu__link'
}
onClick={() => {
toggleClass(0);
}}
href="##"
>
Favorites
</a>
</li>
</ul>
<div className="header-favorite-count">
<i className="far fa-heart"></i>
{favoriteCount}
</div>
</div>
</header>
);
};
and styles to visualise toggling classes
&-menu__link {
color: lightgray;
}
.active {
color: #fff;
}
This approach is working but looks creepy. Maybe somebody knows how to optimize it?
I wouldn't use the index, I'd use the text of the item. I'd also include that text in the href so that there's an indication of what the anchor leads to. To avoid repeated code, you might put the menu items in a reusable array, something like this:
const menuItems = [
"Characters",
"Favorites",
];
export const Header = ({ favoriteCount }) => {
const [activeItem, setActiveItem] = useState("");
const setActiveItem = useCallback((event) => {
setActiveItem(event.currentTarget.href.substring(2));
}, []);
const list = menuItems.map(item =>
<li key={item}>
<a
className={`header-menu__link ${item === activeItem ? "active" : ""}`}
onClick={setActiveItem}
href={"##" + item}>
{item}
</a>
</li>
);
return (
<header className="header">
<div className="container header-container">
<ul className="header-menu">
{list}}
</ul>
<div className="header-favorite-count">
<i className="far fa-heart"></i>
{favoriteCount}
</div>
</div>
</header>
);
};

Hide dropdowns in loop on click outside

I have an array of values which would render a list with a dropdown menu.
I would show/hide the dropdown on click of an element.
projectData.map(project => (
<div>
<div>{project.name}</div>
<div
onClick={() => setDropdownId((prevState) => (
prevState === project.id ? null : project.id)
)}
>
Show
</div>
{dropdownId === project.id && (
<ul className="dropdown">
<li>option</li>
</ul>
)}
</div>
))
How can I hide the opened dropdown on outside click?
I tried with ref but is not working as expected as the elements are in a loop.
Use onBlur to trigger changes when loosing focuse
handleBlur = (e) => {
// add you code here
}
projectData.map(project => (
<div>
<div>{project.name}</div>
<div
onBlur={handleBlur}
onClick={() => setDropdownId((prevState) => (
prevState === project.id ? null : project.id)
)}
>
Show
</div>
{dropdownId === project.id && (
<ul className="dropdown">
<li>option</li>
</ul>
)}
</div>
))

Reactjs trigger onClick function without click in functional component

I'm using functional component in react js , my onClick function triggers with component rendering without click on my li element ;
this is my parent component that passed the handleCallDetails function as props to child component:
export default function Cartable(){
const [items , setItems] = useState(null);
const [details , setDetails] = useState(null);
function handleCallDetails(id){
if(items !== null && details === null){
let d = items.find(x => {
return x.id === id;
});
}
}
useEffect(() => {
axios.get(`/workflows/${mode}` ,{
params : {
OrganizationId : "FE905B40-DA6E-4A81-8A4F-B447AA6B0EA3" ,
Type : 2 ,
sortorder : "desc" ,
pageIndedx : 1 ,
pageSize : 10
}
}).then(response => {
// console.log('response : ***************** ' , response);
setItems(response.data.data);
}).catch(error => {
console.log('error : ****************** ' , error);
});
} , [mode]);
return (
<Grid container spacing={2}>
<Grid item xs={12} sm={4} md={3}>
<div className="drt_RightSide drt_segment">
<h4 className="drt_RightSideTitle">
<i className="far fa-inbox"></i>
کارتابل
</h4>
<ul>
{/* <li>
<i class="far fa-inbox"></i>
<span>درخواست ها</span>
</li> */}
<li onClick={() => {setMode('pending');}}>
<i className="fas fa-exclamation"></i>
<span><FormattedMessage id="CARTABLE_PENDING" /></span>
<span className="drt_badge_warning drt_NotifNum">5</span>
</li>
<li onClick={() => {setMode('approved');}}>
<i className="far fa-check"></i>
<span>تایید شده</span>
</li>
<li onClick={() => {setMode('rejected');}}>
<i className="far fa-times"></i>
<span>رد شده</span>
<span className="drt_badge_error drt_NotifNum">7</span>
</li>
<li>
<i className="far fa-bell"></i>
<span>خارج از فرآیند</span>
</li>
</ul>
</div>
</Grid>
<Grid item xs={12} sm={8} md={9}>
<div className="drt_LeftSide drt_segment"> */}
{/* cartbale list */}
<CartableList
items={items}
callDetails={handleCallDetails}/>
</div>
</Grid>
</Grid>
);
}
and it is my child compnent that use onClick function that named callDetails:
export default function CartableList(props){
const [showbox , setShowbox] = useState(false);
const [age, setAge] = useState('');
const handleChange = (event) => {
setAge(event.target.value);
};
function handleFilterBox(){
setShowbox(!showbox);
}
return (
<Fragment>
{/* cartable list */}
<div style={{direction : "ltr"}}>
<Scrollbars style={{ height: 400 }}>
{
props.items && props.items !== undefined ?
props.items.map(function(item , index){
return (
<div className="drt_clearfix drt_CartableItem" key={index} onClick={(props.callDetails)(item.id)}>
{/* <div className={clsx(drt_ItemStar , item.star ? drt_IsStared : '')}>
<span><i className={clsx(item.star ? "fas fa-star" : "fal fa-star")}></i></span>
</div> */}
<div className="drt_ItemImg">
<span>
<img alt={userImg} src={item.pictureUrl !== undefined && item.pictureUrl !== null ? item.image : userImg} />
</span>
</div>
<div className={clsx("drt_ItemName" , !item.isSeen ? "drt_IsNotSeen" : '')}>
{item.issuerFirstName}
<br />
{item.issuerLastname}
</div>
<div className="drt_ItemIcon">
<Tooltip title={(props.moduleType)(item.type).name}>
<span className={item.isSeen ? "drt_badge_default" : "drt_badge_primary"}>
<i className={(props.moduleType)(item.type).icon} />
</span>
</Tooltip>
</div>
<div className={clsx("drt_ItemDesc" , !item.isSeen ? "drt_IsNotSeen" : '')}>
{item.objectTitle}
</div>
<div className="drt_ItemStatus">
<span className={(props.stateClass)(item.status)}>
{(props.stateTitle)(item.status)}
</span>
</div>
<div className={clsx("drt_ItemDate" , !item.isSeen ? "drt_IsNotSeen" : '')}>
<p>
<span>
{item.issuerTime}
</span>
<span>
{item.issuerDate}
</span>
</p>
<i className="fal fa-clock" />
</div>
</div>
);
}) : ''
}
</Scrollbars>
</div>
</Fragment>
);
}
please help me to solve this problem without convert my functional component to class component and binding my function
The correct way is this. You need to use arrow function or else react will understand that you want to execute the function at load
wrong
<div className="drt_clearfix drt_CartableItem" key={index} onClick={(props.callDetails)(item.id)}>
correct
<div className="drt_clearfix drt_CartableItem" key={index} onClick={() => props.callDetails(item.id)}>
Change from
onClick={() => {setMode('rejected');}}
to
onClick={() => setMode('rejected')}
Also
<div className="drt_clearfix drt_CartableItem" key={index} onClick={() => props.callDetails(item.id)}>
But where did you define the const [mode, setMode] state
It seems you exec your callback function immediately as it renders based on your code:
onClick={(props.callDetails)(item.id)}
It's supposed to be:
onClick={() => props.callDetails(item.id)}
Is that the issue?
It's mainly because of piece of code onClick={(props.callDetails)(item.id)} in your child component. This code is actually executing callDetails function and passing the item.id value immediately. One way to handle this is to wrap your function.
onClick={() => {props.callDetails(item.id)}}
A simple reason as to why onClick is not called when it is wrapped is because it is not directly passing in any value when initialised.

Hide other previous div/dropdown React

I am wanting to hide other sibling divs (dropdowns in my case) when I click the statusPillDropdown
so far I click I am setting the status to true and opening the div,
{DropDown ${toggleStatusDropdown ? "open": ""}}
Do I just need to set the state to false for previously opened ones? Not sure how to do this.
thank you
import React, { useState } from "react";
import "./StatusPillDropdown.scss";
function StatusPillDropdown({
cellData,
rowItemId,
onStatusPillDropdownChange
}) {
const [toggleStatusDropdown, setToggleStatusDropdown] = useState();
const toggleDropdown = (action, rowItemId, e) => {
if (action === "pillClick") {
setToggleStatusDropdown(true);
} else {
onStatusPillDropdownChange(rowItemId, e.target.getAttribute("value"));
setToggleStatusDropdown(false);
}
};
const renderstatusPillDropdown = (cellData, rowItemId) => (
<React.Fragment>
<span
className="statusPillDropdown"
onClick={() => toggleDropdown("pillClick", rowItemId)}
>
<span className={`status-pill ${cellData.type}`}>{cellData.text}</span>
</span>
<div className="status">
<div className="dropdown-container">
<div className={`DropDown ${toggleStatusDropdown ? "open" : ""}`}>
<ul>
<li
value="Information only"
onClick={e => toggleDropdown("liClick", rowItemId, e)}
>
<span></span>Information only
</li>
<li
value="Unresolved"
onClick={e => toggleDropdown("liClick", rowItemId, e)}
>
<span className="unresolved"></span>Unresolved
</li>
<li
value="Partially Resolved"
onClick={e => toggleDropdown("liClick", rowItemId, e)}
>
<span className="partyResolved"></span>Partially Resolved
</li>
<li
value="Fully Resolved"
onClick={e => toggleDropdown("liClick", rowItemId, e)}
>
<span className="resolved"></span>Fully Resolved
</li>
</ul>
</div>
</div>
</div>
</React.Fragment>
);
return (
<React.Fragment>
{renderstatusPillDropdown(cellData, rowItemId)}
</React.Fragment>
);
}
export default StatusPillDropdown;

Unable to keep the selection highlighted when i focus out of calendar in react full calendar

I'm using React Full Calendar.
I want to keep the selected date highlighted even when i click out of calendar i.e. maps here. I also want to highlight my custom event when clicked i.e. cropname. I'm attatching my jsx also.
Can someone help me with this?
JSX=>
render() {
return (
<FullCalendar
dafaultView="dayGridMonth"
// defaultDate= '2017-12-12'
eventLimit="true"
eventLimitText="More"
views={{
month: {
eventLimit: 3
}
}}
dateClick={(e) => { this.onDateSelection(e) }}
plugins={[dayGridPlugin, interactionPlugin]}
weekends={true}
selectable="true"
unselect={(e)=>e.jsEvent.preventDefault()}
contentHeight="auto"
showNonCurrentDates="false"
events={this.state.calendarEvents && this.state.calendarEvents.list}
// viewRender={(view, element) => { alert("render"); console.log(view, element) }}
viewSkeletonRender={info => { this.addPaginationEvent(); }}
eventRender={({ event, el }) => {
const content = <div className="eventDetailContainer eventColor row justify-content-around">
<div id="eventDetailImg"className="col-md-1" onClick={(e) => e.preventDefault()}>
<img onClick={(e) => this.onCropSelect(event._def.extendedProps,e)} src={CropImageFinder(event._def.extendedProps.cropName)} />
</div>
<div className="col-md-5 harvestEventCropName harvestEventCropNameHideMobile">
<span onClick={(e) => this.onCropSelect(event._def.extendedProps,e)} > {event._def.extendedProps.cropName} </span>
</div>
<div id="eventDetailQuantity"className="col-md-2 harvestEventCropName">
<span onClick={(e) => this.onCropSelect(event._def.extendedProps,e)} > {event._def.extendedProps.cropQuantity + event._def.extendedProps.cropQuantityUnit } </span>
</div>
</div>;
ReactDOM.render(content, el);
return el;
}
}
/>
</section>)
}

Categories

Resources