Show Checkbox in Div - reactjs

Code:-
export default function TabHeader({ item, index, activeIndex, ontoggle }) {
const [activeLOCK, setActiveLock] = useState(0);
const setLock = (e, ChannelName, ID) => {
setActiveLock(index);
}
<div id="Lock">
<p onClick={(e) => { setLock(e, Delete.val, index) }}>
{activeLOCK === index ? <FaRegCheckCircle style={{ height: "20px", width: "20px", color: "green" }} /> : <FaRegCircle style={{ color: "red" }} />}
</p>
</div>
}
when User click the menu btn then there 1 tab is open with default checkbox when I user click the 2 menu btn 2 tab open(evening) with circle in div but how can I show the checkbox when i click the 2 box div and 1 box div(business)make them red circle remove the checkbox and show the circle
How can I do that? in react
right now getting this(in image):-
but want when user click the div its show checkbox and other show red circle
please help......

I think your problem is you don't modify activeIndex from the parent component
To fix it, you should pass setActiveIndex into your TabHeader like below
export default function TabHeader({ item, index, activeIndex, setActiveIndex, ontoggle }) {
const [activeLOCK, setActiveLock] = useState(activeIndex); //set `activeIndex` as default
const setLock = (e, ChannelName, ID) => {
setActiveLock(index);
setActiveIndex(index); //call your `setActiveIndex` here to update `activeIndex` on the parent component
}
<div id="Lock">
<p onClick={(e) => { setLock(e, Delete.val, index) }}>
{activeLOCK === index ? <FaRegCheckCircle style={{ height: "20px", width: "20px", color: "green" }} /> : <FaRegCircle style={{ color: "red" }} />}
</p>
</div>
}
If you don't have setActiveIndex in the parent component, I'd suggest you add that as state update
const [activeIndex, setActiveIndex] = useState(0)

Related

Change background color of div by clicking in react

I have three div in the component(which can be more than three as well). I want to change their color when they will be clicked. If again I will click, they will get back their old color. In my code if I am clicking any one div, all div s are changing, Can you help me to do it for particular div?
The code is:
import React,{useState} from 'react'
export default function ChangeColor() {
let [colorState,changeState]=useState(['red','green','blue']);
let [isActive,setIsActive]=useState(true);
return (
<>
{colorState.map((color,index)=>{
return(
<React.Fragment key={index}>
<div style={{width:'100px',height:'100px',backgroundColor:isActive?`${color}`:'yellow' }}
onClick={()=>{isActive?setIsActive(false) :setIsActive(true)}}>
<p>{color}</p>
</div>
</React.Fragment>
)})
}
</>
)
}
All 3 div are changing together because only a single value is used to control the state.
To solve this, you could make isActive an object that contain a Boolean value for each color, so its structure could be something like this:
{red: true, green: false, blue: false}
This way, each of the div can set the styles based on condition like:
backgroundColor: isActive[color] ? 'yellow' : color
Full example: (live demo on stackblitz)
import React, { useState } from 'react';
export default function ChangeColor() {
const [colorState, changeState] = useState(['red', 'green', 'blue']);
const [isActive, setIsActive] = useState({});
const toggleActive = (color) =>
setIsActive((prev) => {
if (prev[color]) return { ...prev, [color]: false };
return { ...prev, [color]: true };
});
return (
<>
{colorState.map((color, index) => {
return (
<React.Fragment key={index}>
<div
style={{
width: '100px',
height: '100px',
backgroundColor: isActive[color] ? 'yellow' : color,
cursor: 'pointer',
}}
onClick={() => toggleActive(color)}
>
<p>{isActive[color] ? 'yellow' : color}</p>
</div>
</React.Fragment>
);
})}
</>
);
}

How can I show the div when its display none?

when i click the Cross (X) btn in div its should we close and when I click the Rundown List its show me div example:-
when I click the Business news Cross btn its close the div but when i click the rundown List business news its show me business new
i have try but i when i click the cross btn is again not open the div
Code:-.
Parent component
const LeftNav = () => {
return (
<div className="allDivs">
{item.map((items, index) => {
// console.log(item)
return (
<div key={index} >
<TabHeader item={items} index={index}/>
</div>
)
})}
</div>
</div >
)
}
export default LeftNav;
Child componentL;-
export default function TabHeader({ item, index }) {
const [Close, setClose] = useState(false);
useEffect(() => {
console.log("activeFOCUS", activeFOCUS);
setShow(ontoggle);
}, [])
return (
<Fragment>
<div id="CLOSEDIV" style={Close === true ? { display: "none" } : { display: "block" }}>
<div className="TableText" onClick={(e) => { handleOnClick(e, Delete.val) }}>
<div id="SHOW">{Delete.val}</div>
</div>
//cross btn
<div className="CloseIcon" id="CloseBtn"><FaRegTimesCircle
style={{ color: "#FC0000", width: "20px", height: "20px", alignItems: "right" }}
onClick={(e) => { handleToggle(e, index, Delete.val) }} /></div>
</div>
</div>
</Fragment >
)
}
please help....
Try using visibility: hidden and visibility: visible instead of display: none

Add a tooltip to MUI Badge content?

I want to add a tooltip to my MUI Badge component.
I tried wrapping the badge with a ToolTip component from MUI but tooltip text also displays when the children are hovered, I'd like it to only appear when the Badge itself is hovered.
I have also tried using the primitive title prop on the badge component but this has the same issue.
Does anyone know of a better way to add a tooltip to a Badge component?
my usage:
<Badge
title={'Click to view more info'} // not ideal as the tooltip shows when the children are hovered too
badgeContent={getTotalVulnerabilitiesCount()}
showZero={false}
>
{children}
</Badge>
You're very close, badgeContent prop also accepts a ReactNode so you can put the Badge content inside a Tooltip without affecting the other component:
<Badge
color="primary"
badgeContent={
<Tooltip title="Delete">
<span>1</span>
</Tooltip>
}
>
<MailIcon color="action" />
</Badge>
I ended up building my own badge component, its not too long either so good solution imo. If anyone has feedback for the code please let me know :)
import React from 'react';
import { makeStyles, Tooltip } from '#material-ui/core';
const useStyles = makeStyles({
badgeStyles: {
minHeight: '24px',
minWidth: '24px',
position: 'absolute',
top: '-12px',
left: 'calc(100% - 12px)',
color: 'white',
borderRadius: '50%',
backgroundColor: 'tomato',
padding: '3px',
fontSize: '.75rem'
}
});
const Badge = props => {
const {
children,
showZero,
...badgeContentProps
} = props;
return (
<span>
{children}
{
(showZero || props.badgeContent !== 0) && (
<BadgeComponent {...badgeContentProps}/>
)
}
</span>
);
};
const BadgeComponent = props => {
const classes = useStyles();
const {
badgeContent,
badgeClasses,
onClick,
tooltipText,
tooltipPlacement
} = props;
// If no tooltiptext provided render without Tooltip
if(tooltipText == null) return (
<span
className = {`${badgeClasses ?? ''} ${classes.badgeStyles}`}
onClick={onClick ? onClick : undefined}
>
{badgeContent}
</span>
);
// Render with Tooltip
return (
<Tooltip title={tooltipText} placement={tooltipPlacement}>
<span
className = {`${badgeClasses} ${classes.notifyCount}`}
onClick={onClick ? onClick : undefined}
>
{badgeContent}
</span>
</Tooltip>
);
};
export default Badge;

Change color of active button among multiple buttons in React using material ui

I am trying to change the color only of a button, which is clicked. And by default the first button to be active. The problem that I have is that in Material UI when I use Button there is a span so I cannot use e.target.name ... because there is no name in the span. This span is created when I type some text between the button tags => Some title. As well I intend to have some other actions when the button is clicked, except that it should change its color to show, which one is active.
If there is some way around I will appreciate it. Down below is some code, that I tried, but I do not know what to do in clickedButtonHandler and if it's possible to pass any argument on it when the button is clicked... for example the name.
import React, { useState } from "react";
import { Container, Box, Button } from "#material-ui/core";
import { makeStyles, withStyles } from "#material-ui/styles";
const StyledButton = withStyles(() => ({
root: {
marginRight: "1rem",
width: "25%",
padding: "1rem",
fontSize: "1.2rem",
borderRadius: "1rem",
color: "#000",
fontWeight: "400",
textTransform: "capitalize"
}
}))(Button);
const useStyles = makeStyles(() => ({
buttonContainerWrapper: {
display: "flex",
justifyContent: "center"
},
buttonContainer: {
backgroundColor: "#ccc",
border: "1px solid #000",
padding: "1rem",
display: "flex",
justifyContent: "space-between"
},
lastButtonFilter: {
marginRight: "0rem"
},
activeButton: {
background: "#fc7303",
color: "#fff"
}
}));
export default function Filter() {
const classes = useStyles();
const [activeButton, setActiveButton] = useState({
first: true,
second: false,
third: false,
fourth: false
});
const clickedButtonHandler = (e) => {
console.log(e.target);
const { name } = e.target;
setActiveButton(name);
console.log(activeButton);
};
return (
<Container className={classes.buttonContainerWrapper}>
<Box className={classes.buttonContainer}>
<StyledButton
name="button-one"
className={activeButton?.first ? `${classes.activeButton}` : ""}
onClick={clickedButtonHandler}
>
Button One
</StyledButton>
<StyledButton
name="button-two"
className={
activeButton?.second ? `${classes.activeButton}` : ""
}
onClick={clickedButtonHandler}
>
Button Two
</StyledButton>
<StyledButton
name="button-three"
className={activeButton?.third ? `${classes.activeButton}` : ""}
onClick={clickedButtonHandler}
>
Button Three
</StyledButton>
<StyledButton
name="button-four"
className={
activeButton?.fourth ? `${classes.activeButton}` : ""
}
onClick={clickedButtonHandler}
>
Button Four
</StyledButton>
</Box>
</Container>
);
}
here is the link to codepan: https://codesandbox.io/s/awesome-sinoussi-u3o3s
It looks like you can also loop through an array for the buttons
export default function Filter() {
const classes = useStyles();
const [activeButton, setActiveButton] = useState("button-one");
const clickedButtonHandler = (name) => {
setActiveButton(name);
};
const buttons = ["button-one", "button-two", "button-three", "button-four"];
return (
<Container className={classes.buttonContainerWrapper}>
<Box className={classes.buttonContainer}>
{buttons.map((name) => (
<StyledButton
name={name}
className={activeButton === name ? `${classes.activeButton}` : ""}
onClick={() => clickedButtonHandler(name)}
>
{name}
</StyledButton>
))}
</Box>
</Container>
);
}
for targetting the root element use the ButtonBase component.
And also to keep track of active buttons in useState, spread the old state first and then update the new value of the new variable (might differ in different use case or requirement). I've updated that issue.
export default function Filter() {
const classes = useStyles();
const [activeButton, setActiveButton] = useState('first');
const clickedButtonHandler = (e) => {
console.log(e.target);
const { name } = e.target;
setActiveButton(name);
console.log(activeButton);
};
return (
<Container className={classes.buttonContainerWrapper}>
<Box className={classes.buttonContainer}>
<StyledButton
name="first"
className={activeButton === "first" ? `${classes.activeButton}` : ""}
onClick={clickedButtonHandler}
>
Button One
</StyledButton>
<StyledButton
name="second"
className={activeButton === "second" ? `${classes.activeButton}` : ""}
onClick={clickedButtonHandler}
>
Button Two
</StyledButton>
<StyledButton
name="third"
className={activeButton === "third" ? `${classes.activeButton}` : ""}
onClick={clickedButtonHandler}
>
Button Three
</StyledButton>
<StyledButton
name="fourth"
className={activeButton === "fourth" ? `${classes.activeButton}` : ""}
onClick={clickedButtonHandler}
>
Button Four
</StyledButton>
</Box>
</Container>
);
}
Workign demo:-

React Hooks useRef initialization issue, useRef only works on subsequent calls

I am implementing useRef into my project. I have a form that has clickable sections. Once clicked it opens the form. I'm using Reactstrap Collapse to show/hide the form. I need to be able to open the form and show the section that needs to be filled out, however the scrollIntoView once I click the section doesn't work until I open and close the form again. I'm stumped. I console.log(formRef), the ref returns as expected of the component that I want to be scrolled to the top of viewport on subsequent calls. My guess would be that the formRef is being initialized as null to begin with so initial calls to the ref do not work. However, once it knows the ref the subsequent calls work. I'm not sure how to go about this..
If I need to provide an example that is stripped please let me know. I am expecting this to be just an initialization issue.
Form
import React, { useRef, useContext, useEffect } from "react";
import {
FormQuestionsContext,
FormAnswersContext,
ExpandedSectionContext,
} from "../../Store";
import SectionHeader from "../SectionHeader";
import ImageUploader from "../CommentsSection";
import Ratings from "../Ratings";
import { Collapse, Button, CardBody, Card } from "reactstrap";
import FontAwesome from "react-fontawesome";
import styles from "./bedthreeform.module.css";
function BedThreeForm({ Name }) {
const formRef = useRef(null); //useRef Initialization
const [expandedSection, setExpandedSection] = useContext(
ExpandedSectionContext
);
const [formQuestions, setFormQuestions] = useContext(FormQuestionsContext);
const [formAnswers, setFormAnswers] = useContext(FormAnswersContext);
const array = formQuestions.bedthree;
const onChange = (e, name) => {
const { value } = e.target;
setFormAnswers((state) => ({
...state,
[Name]: { ...state[Name], [name]: value },
}));
};
//! The function I use when I want to tell useRef to scrollIntoView
const handleOpen = () => {
expandedSection === Name
? setExpandedSection("")
: setExpandedSection(Name);
formRef.current.scrollIntoView();
};
const answeredQuestions = formAnswers.bedthree
? Object.keys(formAnswers.bedthree)
: null;
console.log(formRef);
return (
<div>
<Button
className={styles["CollapseBtn"]}
onClick={handleOpen} //Calling the function here
style={
answeredQuestions &&
answeredQuestions.length === formQuestions.bedthree.length
? {
color: "white",
":focus": {
backgroundColor: "#02BD43",
},
backgroundColor: "#02BD43",
marginBottom: "1rem",
width: "100%",
}
: answeredQuestions &&
answeredQuestions.length !== formQuestions.bedthree.length
? {
color: "white",
":focus": {
backgroundColor: "#bd0202",
},
backgroundColor: "#bd0202",
marginBottom: "1rem",
width: "100%",
}
: {
":focus": {
backgroundColor: "#fafafa",
},
marginBottom: "1rem",
width: "100%",
}
}
>
<p>BEDROOM #3 INSPECTION</p>
<FontAwesome
className="super-crazy-colors"
name="angle-up"
rotate={expandedSection === Name ? null : 180}
size="lg"
style={{
marginTop: "5px",
textShadow: "0 1px 0 rgba(0, 0, 0, 0.1)",
}}
/>
</Button>
<Collapse
className={styles["Collapse"]}
isOpen={expandedSection === Name}
>
<Card>
<CardBody>
{array ? (
<div>
<SectionHeader title="Bedroom #3 Inspection" name={Name} />
<div
ref={formRef}
className={styles["BedroomThreeFormWrapper"]}
id="bedroom-three-form"
>
{array.map((question, index) => {
const selected =
formAnswers[Name] && formAnswers[Name][question]
? formAnswers[Name][question]
: "";
return (
<div className={styles["CheckboxWrapper"]} key={index}>
<h5>{question}</h5>
<Ratings
section={Name}
question={question}
onChange={onChange}
selected={selected}
/>
</div>
);
})}
</div>
{!answeredQuestions ? (
""
) : (
<Button
onClick={(e) => e.preventDefault()}
style={
!answeredQuestions ||
(answeredQuestions &&
answeredQuestions.length !==
formQuestions.bedthree.length)
? {
backgroundColor: "#bd0202",
color: "white",
pointerEvents: "none",
}
: {
backgroundColor: "#02BD43",
color: "white",
pointerEvents: "none",
}
}
>
{!answeredQuestions ||
(answeredQuestions &&
answeredQuestions.length !==
formQuestions.bedthree.length)
? "Incomplete"
: "Complete"}
</Button>
)}
<br />
<ImageUploader name="bedthree" title={"Bedroom #3"} />
</div>
) : (
<div></div>
)}
</CardBody>
</Card>
</Collapse>
</div>
);
}
export default BedThreeForm;
CodeSandbox Stripped Form Doesn't work as expected, however that is the stripped code.
Update I'm open to suggestions to bypass this, or an alternative way to do this. I'm not sure why it only does it on subsequent calls.
Look at these lines:
<CardBody>
{array ? (
...
<div
ref={formRef}
...
This (virtual) dom will be evaluated only if array is defined. In case you would like to have your formRef always to point to the dom, then You'll have to strip it out from your condition.
I've figured out the issue, the issue is calling it when the content in the collapse hasn't been loaded yet, Reactstrap has an attribute onEntered which basically when set, will run the function as soon as the collapse has fully opened. The example that I found is here. Also, by setting the attribute innerRef on a Reactstrap component I can manipulate it just like I could a regular component using ref.

Resources