Skip to content

Commit 2b66cf0

Browse files
committed
Add a contextual menu to the ListView
1 parent b38d90a commit 2b66cf0

File tree

3 files changed

+80
-85
lines changed

3 files changed

+80
-85
lines changed
Lines changed: 77 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,11 @@
1-
# Add a contextual menu
2-
## The ListView column
3-
To add a contextual menu to our ListView we will insert another Viewfield in the webpart code at the position of our choice, for instance after the “Lastname”:
4-
```TypeScript
5-
{
6-
name: "",
7-
sorting: false,
8-
maxWidth: 40,
9-
render: (rowitem: IListitem) => {
10-
const element:React.ReactElement<IECBProps> =React.createElement(
11-
ECB, {
12-
item:rowitem
13-
}
14-
);
15-
return element;
16-
}
17-
}
18-
```
19-
We use the render method of IViewField. Inside we create our ECB component and as a property we handover the rowitem which is clicked.
20-
We could also handover functions that shall be executed inside the context menu component but be able to be bound to the parent component, that is the webpart/component which contains the ListView.
1+
# ListView: Add a contextual menu
2+
213
## The ContextualMenu component
22-
We now need to create the ECB component which represents our context menu. Therefore we will use a combination of an [IconButton](https://developer.microsoft.com/en-us/fabric#/components/button#Variants) and a [ContextualMenu](https://developer.microsoft.com/en-us/fabric#/components/contextualmenu) from the Office UI Fabric components.
23-
The code for this additional component looks like this:
4+
5+
In order to create a contextual menu for your list view, you first need to create a new component which will use a combination of an [IconButton](https://developer.microsoft.com/en-us/fabric#/components/button#Variants) and [ContextualMenu](https://developer.microsoft.com/en-us/fabric#/components/contextualmenu) controls from the Office UI Fabric React.
6+
7+
Here is some sample code:
8+
249
```TypeScript
2510
import * as React from 'react';
2611
import { Layer, IconButton, IButtonProps } from 'office-ui-fabric-react';
@@ -33,81 +18,91 @@ import { IListitem } from '../../model/IListitem';
3318
export class ECB extends React.Component<IECBProps, {}> {
3419

3520
public constructor(props: IECBProps) {
36-
super(props);
21+
super(props);
3722

38-
this.state = {
39-
panelOpen: false
40-
};
23+
this.state = {
24+
panelOpen: false
25+
};
4126
}
4227

4328
public render() {
44-
return <div className={styles.ecb}>
45-
<IconButton
46-
47-
id='ContextualMenuButton1'
48-
className={styles.ecbbutton}
49-
text=''
50-
width='30'
51-
split={false}
52-
iconProps={ { iconName: 'MoreVertical' } }
53-
menuIconProps={ { iconName: '' } }
54-
menuProps={ {
55-
shouldFocusOnMount: true,
56-
items: [
57-
{
58-
key: 'action1',
59-
name: 'Action 1',
60-
onClick: this.handleClick.bind(this, this.props.item.Firstname + ' Action 1')
61-
},
62-
[ {
63-
key: 'divider_1',
64-
itemType: ContextualMenuItemType.Divider
65-
},
66-
{
67-
key: 'action2',
68-
name: 'Action 2',
69-
onClick: this.handleClick.bind(this, this.props.item.Firstname + ' Action 2')
70-
},
71-
{
72-
key: 'action3',
73-
name: 'Action 3',
74-
onClick: this.handleClick.bind(this, this.props.item.Lastname + ' Action 3')
75-
},
76-
{
77-
key: 'disabled',
78-
name: 'Disabled action',
79-
disabled: true,
80-
onClick: () => console.error('Disabled action should not be clickable.')
81-
}
82-
]
83-
} }
84-
/>
85-
</div>
86-
;
29+
return (
30+
<div className={styles.ecb}>
31+
<IconButton id='ContextualMenuButton1'
32+
className={styles.ecbbutton}
33+
text=''
34+
width='30'
35+
split={false}
36+
iconProps={ { iconName: 'MoreVertical' } }
37+
menuIconProps={ { iconName: '' } }
38+
menuProps={{
39+
shouldFocusOnMount: true,
40+
items: [
41+
{
42+
key: 'action1',
43+
name: 'Action 1',
44+
onClick: this.handleClick.bind(this, this.props.item.Firstname + ' Action 1')
45+
},
46+
{
47+
key: 'divider_1',
48+
itemType: ContextualMenuItemType.Divider
49+
},
50+
{
51+
key: 'action2',
52+
name: 'Action 2',
53+
onClick: this.handleClick.bind(this, this.props.item.Firstname + ' Action 2')
54+
},
55+
{
56+
key: 'action3',
57+
name: 'Action 3',
58+
onClick: this.handleClick.bind(this, this.props.item.Lastname + ' Action 3')
59+
},
60+
{
61+
key: 'disabled',
62+
name: 'Disabled action',
63+
disabled: true,
64+
onClick: () => console.error('Disabled action should not be clickable.')
65+
}
66+
]
67+
}} />
68+
</div>
69+
);
8770
}
8871

8972
private handleClick(source:string, event) {
90-
alert(source + ' clicked');
73+
alert(`${source} clicked`);
9174
}
9275
}
9376
```
94-
One of the things to mention is that in the (totally simplified for demo reasons here) onClick function we hand over one attribute of the clicked item that we have in the components' properties so we can process it in the function.
95-
Another trick is to give an empty iconName for the menuIconProps. This is because once you attach a menuProps Attribute to any Kind of Office UI fabric button a ChevronDown selector on the right side of the button will occur by default.
96-
With the menuIconProps Attribute you can adjust this, that is when specifying an empty Name you can remove it. This is what we want because we only want to have our “MoreVertical” icon which are the three dots in a vertical order.
97-
To place this a bit more centric, we have small CSS manipulation as well:
98-
```SCSS
99-
.ecb {
100-
position: absolute;
101-
top: -3px;
102-
.ecbbutton div {
103-
padding-left: 12px;
104-
}
77+
78+
## The ListView column
79+
80+
Once the ECB component is created, you can add the contextual menu to the `ListView` control. In order to do this, you have to insert another `Viewfield` in code at the position of our choice. For instance after the `Lastname`:
81+
82+
```TypeScript
83+
{
84+
name: "",
85+
sorting: false,
86+
maxWidth: 40,
87+
render: (rowitem: IListitem) => {
88+
const element:React.ReactElement<IECBProps> = React.createElement(
89+
ECB,
90+
{
91+
item: rowitem
92+
}
93+
);
94+
return element;
95+
}
10596
}
10697
```
98+
99+
Inside the render method of the `IViewField`, the ECB component gets created and the current item will be used as a reference for the clicked row.
100+
107101
## The result
108102
The result will look like the following:
109103

110104
![ContextualMenu_shown](../assets/ListView.ContextualMenu.png)
111-
And in action it shows which function and item was clicked:
105+
106+
Once you click on an action, you will see the alert:
112107

113108
![ContextualMenu_clicked](../assets/ListView.ContextualMenu_clicked.png)

docs/documentation/docs/controls/ListView.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,8 @@ const groupByFields: IGrouping[] = [
5454
];
5555
```
5656

57-
## Extend with a ContextualMenu
58-
59-
To extend the ListView control with a [ContextualMenu](https://developer.microsoft.com/en-us/fabric#/components/contextualmenu) refer to [ListView.ContextualMenu](./ListView.ContextualMenu.md)
57+
!!! note "Extend ListView with a ContextualMenu"
58+
To extend the `ListView` control with a [ContextualMenu](https://developer.microsoft.com/en-us/fabric#/components/contextualmenu) refer to [ListView.ContextualMenu](./ListView.ContextualMenu).
6059

6160
## Implementation
6261

docs/documentation/mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ pages:
44
- Controls:
55
- FileTypeIcon: 'controls/FileTypeIcon.md'
66
- ListView: 'controls/ListView.md'
7+
- "ListView: add a contextual menu": 'controls/ListView.ContextualMenu.md'
78
- Placeholder: 'controls/Placeholder.md'
89
- SiteBreadcrumb: 'controls/SiteBreadcrumb.md'
910
- WebPartTitle: 'controls/WebPartTitle.md'

0 commit comments

Comments
 (0)