Reputation: 87
I have a context menu on click of a button. There are 3 items which are initially checked. On click of each item, I am toggling the check. The check/uncheck is not reflecting while the context menu is open. This used to work earlier but with the latest react versions it looks to be broken.
The snippet is here
import { initializeIcons } from '@uifabric/icons';
import { DefaultButton, IContextualMenuItem, IContextualMenuProps, IContextualMenuStyles } from 'office-ui-fabric-react';
import React from 'react';
initializeIcons();
//Without this style defined, check/uncheck will not reflect in UI.
const cmStyles:Partial<IContextualMenuStyles> = {
title:{},
header:{},
list:{
},
root:{
},
subComponentStyles:{
callout:{
root:{
}
},
menuItem:{}
},
container:{
}
}
const keys: string[] = [
'Item1',
'Item2',
'Item3'
];
interface IState {
updateUI: boolean;
}
export default class ContextMenuCheck extends React.Component<{}, IState>{
state:IState = {
updateUI: false
}
constructor(props:any){
super(props);
}
onTogglePlanType = (ev?: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>, item?: IContextualMenuItem):void => {
ev && ev.preventDefault();//This will not close the menu
item.checked = !item.checked;
this.setState({updateUI:true});
};
menuItems: IContextualMenuItem[] = [
{
key: keys[0],
text: keys[0],
canCheck: true,
checked: true,
onClick: this.onTogglePlanType
},
{
key: keys[1],
text: keys[1],
canCheck: true,
checked: true,
onClick: this.onTogglePlanType
},
{
key: keys[2],
text: keys[2],
canCheck: true,
checked: true,
onClick: this.onTogglePlanType
}
];
menuProps: IContextualMenuProps = {
items:this.menuItems,
styles: cmStyles
};
componentDidMount() {
}
render() {
return (
<DefaultButton text="Click Me" menuProps={this.menuProps}/>
);
}
}
ReactDOM.render(
<ContextMenuCheck />,
document.getElementById("content")
);
Upvotes: 0
Views: 2163
Reputation: 348
I put together a working example here.
Your sample is close, just had a few missing pieces:
menuItems
is defined with checked
hard-coded to true, the Context Menu will never render those without a checkmark.onTogglePlanType
has the ability to set checked (or not checked) for each individual menu item.menuItems
must be rebuilt on each render so that it is able to take checked
into account in building the menu.I changed IState
to just hold checked values:
type itemChecked = { [key: string]: boolean };
interface IState {
checkedMenuItems: itemChecked;
}
Then I changed the callback to explicitly set values for each menu item:
onTogglePlanType = (ev?: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>, item?: IContextualMenuItem):void => {
ev && ev.preventDefault();
// Use ... syntax to make a copy of the object
const itemChecked = { ...this.state.itemChecked };
itemChecked[item.key] = !itemChecked[item.key];
this.setState({ itemChecked: itemChecked });
};
Then, by moving the definition of menuItems
into the render()
function, it works as expected.
Upvotes: 1