I have MatrialUiTable if I select any of the table row by Clicking the checkboxes. On the top right hand side of the table delete icon will appear. But I wanted different icon which will do the same deletion operation .Is there any solution to change the Icon in MuiTable. Thank you.
Multi row delete icon can be changed by using Custom Components. The code is mentioned in code sample.`
const options = {
rowsSelected: rowsSelected,
customToolbarSelect: (selectedRows, displayData, setSelectedRows) => (
<div>
<Tooltip title={"Delete"} cursor='pointer' className="mr-6">
<Icon onClick={()=>DeleteRow(selectedRows)} color="error">delete</Icon>
</Tooltip>
</div>
),
}`
If you want to remove the delete icon from top during multiple rows select. use it.
customToolbarSelect: () => {},
Also for other task replacing delete icon. Try it
const [selectedFabrics, setSelectedFabrics] = useState([])
customToolbarSelect: selectedRows => (
<IconButton
onClick={() => {
const indexesToPrint = selectedRows.data.map((row, k) => row.dataIndex);
let temp = [];
for (let i = 0; i < fabricList.length; i++) {
if (indexesToPrint.includes(i)) {
temp.push(fabricList[i]['id']);
}
}
setSelectedFabrics(temp);
}}
style={{
marginRight: "24px",
height: "48px",
top: "50%",
display: "block",
position: "relative",
transform: "translateY(-50%)",
}}
>
{/* <EditIcon /> */}
<span style={{marginTop: "23px"}}>Print QR Code</span>
</IconButton>
),
Related
I am trying to get a button to say active when pressed, the problem is how would I do with buttons that are dynamically created?
Currently I have it is set up like this:
<Grid container sx={{ padding: "10px" }}>
{Object.values(CATEGORIES).map((c) => {
return (
<Button className="category-btn" onClick={() => handleChange(c)}>
{c.title}
</Button>
);
})}
</Grid>
Since the buttons are being dynamically generated I am not sure how to add the functionality. I have currently tried this answer to an avail.
Change color of active button among multiple buttons in React using material ui
If the CATEGORIES object doesn't have an id, the map function give you also the index in the array that you can track to discover which button should be active.
If you can have only one button active:
const [activeButtonIndex, setActiveButtonIndex] = useState(null)
const handleChange = (c,index) => {
setActiveButtonIndex(index)
}
...
<Grid container sx={{ padding: "10px" }}>
{Object.values(CATEGORIES).map((c,index) => {
return (
<Button className={index === activeButtonIndex ? "category-btn-active" : "category-btn"} onClick={() => handleChange(c,index)}>
{c.title}
</Button>
);
})}
</Grid>
if you can have multiple button active you can:
const [activeButtonIndexList, setActiveButtonIndexList] = useState([])
const handleChange = (c,index) => {
setActiveButtonIndexList([...activeButtonIndexList, index])
}
...
<Grid container sx={{ padding: "10px" }}>
{Object.values(CATEGORIES).map((c,index) => {
return (
<Button className={activeButtonIndexList.includes(index) ? "category-btn-active" : "category-btn"} onClick={() => handleChange(c,index)}>
{c.title}
</Button>
);
})}
</Grid>
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)
I have following code for creating a grid of cards , but the LINK button at the bottom is not aligned in all the cards. What do I need to change to get all the link buttons aligned in all the card at the bottom right. Please see the image at the bottom, I would like all the select button to be horizontally aligned with other cards in the row.
<Row xs={1} md={4} className="g-4">
{MilitaryFormsType.map((e, idx) => (
<Col>
<Card border="#f7f7f7" style={{ width: '18rem', height: '18rem', whiteSpace: 'pre-wrap' }}>
<Card.Body>
<Card.Title>{e.name}</Card.Title>
<Card.Text >{e.Description}</Card.Text>
<Link to={e.link} >
<Button variant="primary" style={{ backgroundColor: "#aa92df", borderStyle: "none", float: "right" }}>Select</Button>
</Link>
</Card.Body>
</Card>
</Col>
))}
</Row>
What I understand from a problem is you want to move the button on the right bottom of all cards.
You can use position "relative" on the body and for link position "absolute".
<Card.Body style={{ position: "relative" }}>
<Card.Title>{e.name}</Card.Title>
<Card.Text>{e.Description}</Card.Text>
<Link to={e.link} style={{ position: "absolute", bottom: 0, right: 0 }}>
<Button
variant="primary"
style={{
backgroundColor: "#aa92df",
borderStyle: "none",
float: "right",
}}
>
Select
</Button>
</Link>
</Card.Body>
**1. Try this one if using wrap it's possible **
<Card.Body>
<Card.Title>{e.name}</Card.Title>
<Card.Text >{e.Description}</Card.Text>
<Link to={e.link} >
<div style={{ text-align:center }}>
<Button variant="primary" style={{ backgroundColor: "#aa92df", borderStyle: "none"}}>Select</Button>
</div>
</Link>
</Card.Body>
Actually you can dynamically control the height of Card.Title, Card.Text and others using javascript. Below is the code of how you can make all the heights the same so the cards are aligned while containing all the data without overflowing. The principle is basically to set all the cards' heights equal to the height of the longest card. Below is the code:
const [cardHeight, setCardHeight] = useState(null);
const getMaxHeightTitle = (elements) => {
let titleHeights = Array.prototype.map.call(elements, (element, i) => {
return element.offsetHeight;
});
return Math.max(...titleHeights);
}
const setMaxContent = (elements) => {
Array.prototype.map.call(elements, (element, i) => {
element.style.height = 'max-content';
});
}
const setMaxHeightTitle = useCallback((elements, h) => {
Array.prototype.map.call(elements, (element, i) => {
if (element.offsetHeight !== cardHeight) {
element.style.height = cardHeight + 'px'
}
});
}, [cardHeight]);
const resizeCardTitle = useCallback(() => {
setMaxContent(document.getElementsByClassName('card-title h5'));
titleHeight = getMaxHeightTitle(document.getElementsByClassName('card-title h5'));
setCardHeight(titleHeight)
setMaxHeightTitle(document.getElementsByClassName('card-title h5'), titleHeight);
}, [setMaxHeightTitle]);
useEffect(() => {
window.addEventListener('load', resizeCardTitle);
window.addEventListener('resize', resizeCardTitle);
return () => {
window.removeEventListener('load', resizeCardTitle);
window.removeEventListener('resize', resizeCardTitle);
}
}, [cardHeight, resizeCardTitle]);
useEffect(() => {
resizeCardTitle();
}, [resizeCardTitle])
By default, in React JS Material UI's Select component, when we provide a custom IconComponent, it gets turned upside down when user has selected the dropdown / Select component.
Sample code:
<Select
multiple
variant="outlined"
MenuProps={CustomMenuProps}
IconComponent={Search}
renderValue={(selected) => (selected as string[]).join(', ')}
{...props}
>
...
I did a sneaky thing to remove "MuiSelect-iconOpen" from the className when calling IconComponent.
Sample Code after my fix:
<Select
multiple
variant="outlined"
MenuProps={CustomMenuProps}
IconComponent={({ className }) => {
className = className.replace("MuiSelect-iconOpen", "")
return <Search className={className} />
}}
renderValue={(selected) => (selected as string[]).join(', ')}
{...props}
>
....
Now is there a better way to do this without replacing the className?
My current solution is to overwrite the original iconOpen class provided by the Material-UI Select.
....
import { makeStyles } from "#material-ui/core";
const useStyles = makeStyles((theme) => ({
iconOpen: {
transform: 'rotate(0deg)',
},
}));
....
export const MyCompo: FC<> = () => {
const classes = useStyles();
return (
<Select
multiple
variant="outlined"
MenuProps={CustomMenuProps}
IconComponent={Search}
classes={{
iconOpen: classes.iconOpen,
}}
renderValue={(selected) => (selected as string[]).join(', ')}
{...props}
>
....
<Select
value={values.phoneCode}
onChange={handleChange("phoneCode")}
inputProps={{ "aria-label": "Without label" }}
IconComponent={(_props) => {
const rotate = _props.className.toString().includes("iconOpen");
return (
<div
style={{
position: "absolute",
cursor: "pointer",
pointerEvents: "none",
right: 10,
height: "15px",
width: "15px",
transform: rotate ? "rotate(180deg)" : "none",
}}
>
<ArrowDown />
</div>
);
}}
>
....
It does not rotate if you use arrow function: IconComponent={()=> <YourIcon/>}
I'm trying to utilize this example in order to create a calendar that lists out the events in the current month, I have this part working, but what I have yet to figure out is how to make it so that the user can click the event name and it would take them to that event page.
So per that example, if they click on one of the birthdays, it would take them to an events page where they could see more about that birthday.
Currently, my events page is being rendered using this function:
renderEvents() {
const {events} = this.state
this.state.events = {};
let eventItems = this.state.eventGet.map(event => {
console.log(event.id)
if(typeof(events[moment(event.date).date()]) !== "undefined") {
events[moment(event.date).date()].push(event.name)
} else {
events[moment(event.date).date()] = [event.name]
}
});
function renderDay(day) {
const date = day.getDate();
const dateStyle = {
position: 'absolute',
color: 'lightgray',
bottom: 0,
right: 0,
fontSize: 20,
};
const containerStyle = {
margin:'2px',
border: '1px solid #3a87ad',
borderRadius: '3px',
position: 'relative',
display: 'block',
cursor: 'pointer'
};
const textStyle = {
fontSize: '0.8em',
textAlign: 'left',
margin: '1.5px',
}
const cellStyle = {
height: 150,
width: 160,
position: 'relative',
};
return (
<div style={cellStyle}>
<div style={dateStyle}>{date}</div>
{events[date] &&
events[date].map((name, i) => (
<div onClick={() => this.props.history.push('/organizations/' + this.props.match.params.orgID + '/events' + i)} key={i} style={containerStyle}>
<div style={textStyle}> {name} </div>
</div>
))}
</div>
);
}
return (
<div>
<Grid component="section" className="section--center" shadow={0} noSpacing>
<Cell col={12}>
<FABButton style={{margin: '10px', float: "right"}} colored ripple onClick={() => this.props.history.push('/organizations/' + this.props.match.params.orgID + '/events')}>
<Icon name="add" />
</FABButton>
</Cell>
<DayPicker
canChangeMonth={true}
className="Birthdays"
renderDay={renderDay}
/>
</Grid>
</div>
);
}
The current problem is within the sub-function, renderDay which is called by the DayPicker component that gets the events associated with the day. When I try to push to the history property, it errors out and says that I cannot read property 'history' from undefined, which makes sense because we did not pass the history property to that function.
Can someone help me in figuring out how to modify that sub-function so that the onClick event on the div will take a user to that events page?
and says that I cannot read property 'history' from undefined
Make sure your renderDay function is bound to the correct this:
<DayPicker
canChangeMonth
className="Birthdays"
renderDay={renderDay.bind(this)}
/>