Skip to content

Commit 4d0ac31

Browse files
committed
visible and enabled can be booleans or functions
1 parent 74ce5bf commit 4d0ac31

15 files changed

+275
-37
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
<a name="0.4.0"></a>
2+
# [0.4.0](https://github.com/isaacplmann/angular2-contextmenu/compare/v0.1.5...v0.4.0) (2016-10-11)
3+
- `[contextMenu]` and `[contextMenuSubject]` to automate wiring up the context menu
4+
- `[visible]` and `[enabled]` can be booleans or functions
5+
- Can have multiple context menus per component
6+
7+
18
<a name="0.2.1"></a>
29
## [0.2.1](https://github.com/isaacplmann/angular2-contextmenu/compare/v0.1.5...v0.2.1) (2016-09-12)
310
- Fix type definition for `ContextMenuService` to make `actions` optional

README.md

Lines changed: 71 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,21 @@ The older syntax is deprecated and will be removed in version 1.x. (I have no t
1818

1919
```html
2020
<ul>
21-
<li *ngFor="item in items" (contextmenu)="onContextMenu($event, item)">Right Click: {{item.name}}</li>
21+
<li *ngFor="let item of items" [contextMenu]="basicMenu" [contextMenuSubject]="item">Right Click: {{item?.name}}</li>
2222
</ul>
2323
<context-menu>
24-
<template contextMenuItem (execute)="alert('Hi, ' + $event.item.name)">
24+
<template contextMenuItem (execute)="showMessage('Hi, ' + $event.item.name)">
2525
Say hi!
2626
</template>
27-
<template contextMenuItem let-item (execute)="alert('Bye, ' + $event.item.name)">
28-
Bye, {{item.name}}
27+
<template contextMenuItem let-item (execute)="showMessage($event.item.name + ' said: ' + $event.item.otherProperty)">
28+
Bye, {{item?.name}}
2929
</template>
3030
</context-menu>
3131
```
3232

3333
### Component Code
3434

3535
```js
36-
import { ContextMenuService } from 'angular2-contextmenu';
37-
3836
@Component({
3937
...
4038
})
@@ -43,13 +41,7 @@ export class MyContextMenuClass {
4341
{ name: 'John', otherProperty: 'Foo' },
4442
{ name: 'Joe', otherProperty: 'Bar' }
4543
};
46-
47-
constructor(private contextMenuService: ContextMenuService) {}
48-
49-
public onContextMenu($event: MouseEvent, item: any): void {
50-
this.contextMenuService.show.next({ event: $event, item: item });
51-
$event.preventDefault();
52-
}
44+
@ViewChild(ContextMenuComponent) public basicMenu: ContextMenuComponent;
5345
}
5446
```
5547

@@ -61,19 +53,82 @@ export class MyContextMenuClass {
6153
- Every context menu item emits `execute` events. The `$event` object is of the form `{ event: MouseEvent, item: any }` where `event` is the mouse click event
6254
that triggered the execution and `item` is the current item.
6355
- The `enabled` input parameter is optional. Items are enabled by default.
56+
This can be a boolean value or a function definition that takes an item and returns a boolean.
6457
- The `visible` input parameter is optional. Items are visible by default. This property enables you to show certain context menu items based on what the data item is.
58+
This can be a boolean value or a function definition that takes an item and returns a boolean.
6559
- Within the template, you have access to any components and variables available in the outer context.
6660

6761
```html
6862
<context-menu>
69-
<template contextMenuItem let-item [visible]="item.type === 'type1'" [enabled]="isMenuItemEnabled(item)" (execute)="alert('Hi, ' + $event.item.name); $event.event.preventDefault();">
63+
<template contextMenuItem let-item [visible]="isMenuItemType1" [enabled]="false" (execute)="showMessage('Hi, ' + $event.item.name)">
7064
Say hi, {{item?.name}}! <my-component [attribute]="item"></my-component>
7165
With access to the outside context: {{ outsideValue }}
7266
</template>
7367
</context-menu>
7468
```
7569
```js
76-
this.outsideValue = "something";
70+
public outsideValue = "something";
71+
public isMenuItemType1(item: any): boolean {
72+
return item.type === 'type1';
73+
}
74+
```
75+
76+
## Multiple Context Menus
77+
You can use multiple context menus in the same component if you would like.
78+
79+
```html
80+
<ul>
81+
<li *ngFor="let item of items" [contextMenu]="basicMenu" [contextMenuSubject]="item">{{item?.name}}</li>
82+
</ul>
83+
<context-menu #basicMenu>
84+
...
85+
</context-menu>
86+
87+
<ul>
88+
<li *ngFor="let item of items" [contextMenu]="otherMenu" [contextMenuSubject]="item">{{item?.name}}</li>
89+
</ul>
90+
<context-menu #otherMenu>
91+
...
92+
</context-menu>
93+
```
94+
95+
```js
96+
@ViewChild('basicMenu') public basicMenu: ContextMenuComponent;
97+
@ViewChild('otherMenu') public otherMenu: ContextMenuComponent;
98+
```
99+
100+
## Context Menu In a Different Component
101+
If your `<context-menu>` component is in a different component from your list, you'll need to wire up the context menu event yourself.
102+
103+
```html
104+
<ul>
105+
<li *ngFor="item in items" (contextmenu)="onContextMenu($event, item)">Right Click: {{item.name}}</li>
106+
</ul>
107+
```
108+
109+
```js
110+
import { ContextMenuService } from 'angular2-contextmenu';
111+
112+
@Component({
113+
...
114+
})
115+
export class MyContextMenuClass {
116+
public items = [
117+
{ name: 'John', otherProperty: 'Foo' },
118+
{ name: 'Joe', otherProperty: 'Bar' }
119+
};
120+
121+
constructor(private contextMenuService: ContextMenuService) {}
122+
123+
public onContextMenu($event: MouseEvent, item: any): void {
124+
this.contextMenuService.show.next({
125+
event: $event,
126+
item: item,
127+
});
128+
$event.preventDefault();
129+
$event.stopPropagation();
130+
}
131+
}
77132
```
78133

79134
## Custom Styles
@@ -179,6 +234,7 @@ export class MyContextMenuClass {
179234
item: item,
180235
});
181236
$event.preventDefault();
237+
$event.stopPropagation();
182238
}
183239
}
184240
```

angular2-contextmenu-0.3.4.tgz

73.3 KB
Binary file not shown.

angular2-contextmenu.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
import { NgModule } from '@angular/core';
22
import { CommonModule } from '@angular/common';
33
import {ContextMenuComponent} from './src/contextMenu.component';
4-
import {ContextMenuItemDirective} from './src/contextMenu.item.component';
4+
import {ContextMenuItemDirective} from './src/contextMenu.item.directive';
55
import {ContextMenuService} from './src/contextMenu.service';
6+
import {ContextMenuAttachDirective} from './src/contextMenu.attach.directive';
67

78
export * from './src/contextMenu.component';
89
export * from './src/contextMenu.service';
910

1011
@NgModule({
1112
declarations: [
13+
ContextMenuAttachDirective,
1214
ContextMenuComponent,
1315
ContextMenuItemDirective,
1416
],
1517
exports: [
18+
ContextMenuAttachDirective,
1619
ContextMenuComponent,
1720
ContextMenuItemDirective,
1821
],

demo/app.component.html

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<h1>Angular2 Context Menu Demo</h1>
2+
<h3>Base Case</h3>
3+
<ul>
4+
<li *ngFor="let item of items" [contextMenu]="basicMenu" [contextMenuSubject]="item">Right Click: {{item?.name}}</li>
5+
</ul>
6+
<context-menu #basicMenu>
7+
<template contextMenuItem (execute)="showMessage('Hi, ' + $event.item.name)">
8+
Say hi!
9+
</template>
10+
<template contextMenuItem let-item (execute)="showMessage($event.item.name + ' said: ' + $event.item.otherProperty)">
11+
Bye, {{item?.name}}
12+
</template>
13+
</context-menu>
14+
15+
<h3>Enabled and Visible</h3>
16+
<ul>
17+
<li *ngFor="let item of items" [contextMenu]="enableAndVisible" [contextMenuSubject]="item">Right Click: {{item?.name}}</li>
18+
</ul>
19+
<context-menu #enableAndVisible>
20+
<template contextMenuItem let-item [visible]="true" [enabled]="false"
21+
(execute)="showMessage('Hi, ' + $event.item.name)">
22+
Say hi, {{item?.name}}!
23+
With access to the outside context: {{ outsideValue }}
24+
</template>
25+
<template contextMenuItem [visible]="false" (execute)="showMessage('Hi, ' + $event.item.name)">
26+
This will never show...
27+
</template>
28+
<template contextMenuItem let-item [visible]="true" [enabled]="true"
29+
(execute)="showMessage($event.item.name + ' said: ' + $event.item.otherProperty)">
30+
Bye, {{item?.name}}
31+
</template>
32+
</context-menu>
33+
34+
<h3>Enabled and Visible as Functions</h3>
35+
<ul>
36+
<li *ngFor="let item of items" [contextMenu]="withFunctions" [contextMenuSubject]="item">Right Click: {{item?.name}}</li>
37+
</ul>
38+
<context-menu #withFunctions>
39+
<template contextMenuItem [enabled]="onlyJohn" (execute)="showMessage('Hi, ' + $event.item.name)">
40+
Say hi! (enabled for John)
41+
</template>
42+
<template contextMenuItem [visible]="onlyJoe" (execute)="showMessage('Hi, ' + $event.item.name)">
43+
Say hi! (visible for Joe)
44+
</template>
45+
<template contextMenuItem let-item (execute)="showMessage($event.item.name + ' said: ' + $event.item.otherProperty)">
46+
Bye, {{item?.name}}
47+
</template>
48+
</context-menu>

demo/app.component.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { Component, ViewChild } from '@angular/core';
2+
import { ContextMenuService, ContextMenuComponent } from '../angular2-contextmenu';
3+
4+
@Component({
5+
selector: 'angular2-context-menu-demo',
6+
templateUrl: './app.component.html',
7+
})
8+
export class AppComponent {
9+
public items: any[] = [
10+
{ name: 'John', otherProperty: 'Foo' },
11+
{ name: 'Joe', otherProperty: 'Bar' },
12+
];
13+
public outsideValue: string = 'something';
14+
15+
@ViewChild('basicMenu') public basicMenu: ContextMenuComponent;
16+
@ViewChild('enableAndVisible') public enableAndVisible: ContextMenuComponent;
17+
@ViewChild('withFunctions') public withFunctions: ContextMenuComponent;
18+
19+
constructor(private contextMenuService: ContextMenuService) {}
20+
21+
public onContextMenu($event: MouseEvent, item: any): void {
22+
this.contextMenuService.show.next({ event: $event, item: item });
23+
$event.preventDefault();
24+
}
25+
26+
public showMessage(message: string): void {
27+
console.log(message);
28+
}
29+
30+
public onlyJohn(item: any): boolean {
31+
return item.name === 'John';
32+
}
33+
34+
public onlyJoe(item: any): boolean {
35+
return item.name === 'Joe';
36+
}
37+
}

demo/app.module.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { CommonModule } from '@angular/common';
2+
import { NgModule } from '@angular/core';
3+
import { BrowserModule } from '@angular/platform-browser';
4+
import { ContextMenuModule } from '../angular2-contextmenu';
5+
import { AppComponent } from './app.component';
6+
7+
@NgModule({
8+
bootstrap: [AppComponent],
9+
declarations: [AppComponent],
10+
imports: [
11+
BrowserModule,
12+
CommonModule,
13+
ContextMenuModule,
14+
],
15+
providers: [/* TODO: Providers go here */],
16+
})
17+
export class AppModule { }

demo/index.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<html>
2+
<head>
3+
<title>Angular2 Context Menu Demo</title>
4+
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
5+
</head>
6+
<body>
7+
<angular2-context-menu-demo>Loading...</angular2-context-menu-demo>
8+
</body>
9+
</html>

demo/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// require('./styles.css');
2+
3+
import { AppModule } from './app.module';
4+
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
5+
6+
function main(): any {
7+
return platformBrowserDynamic().bootstrapModule(AppModule);
8+
}
9+
10+
document.addEventListener('DOMContentLoaded', () => main());

package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "angular2-contextmenu",
3-
"version": "0.3.4",
3+
"version": "0.4.0",
44
"description": "An Angular 2 component to show a context menu on an arbitrary component",
55
"main": "angular2-contextmenu.js",
66
"scripts": {
@@ -18,8 +18,8 @@
1818
"flow.github-release": "./node_modules/.bin/conventional-github-releaser -p angular",
1919
"flow.build:prod": "NODE_ENV=production ./node_modules/.bin/webpack --progress --color",
2020
"flow.build:dev": "./node_modules/.bin/webpack --progress --color",
21-
"flow.serve:dev": "./node_modules/.bin/webpack-dev-server --hot --inline --colors --display-error-details --display-cached",
22-
"flow.serve:prod": "NODE_ENV=production ./node_modules/.bin/webpack-dev-server --hot --inline --colors --display-error-details --display-cached",
21+
"flow.serve:dev": "./node_modules/.bin/webpack-dev-server --inline --colors --display-error-details --display-cached",
22+
"flow.serve:prod": "NODE_ENV=production ./node_modules/.bin/webpack-dev-server --inline --colors --display-error-details --display-cached",
2323
"prepublish": "npm run flow.clean && npm run flow.compile",
2424
"disabled.postpublish": "npm run flow.deploy:gh-pages",
2525
"start": "npm run flow.serve:dev",
@@ -51,6 +51,7 @@
5151
"@angular/platform-browser": "^2.0.0",
5252
"@angular/platform-browser-dynamic": "^2.0.0",
5353
"@angular/platform-server": "^2.0.1",
54+
"angular2-template-loader": "^0.5.0",
5455
"async": "1.5.2",
5556
"bootstrap": "3.3.6",
5657
"codecov": "1.0.1",
@@ -103,6 +104,7 @@
103104
"typescript": "^2.0.3",
104105
"typings": "0.8.1",
105106
"webpack": "1.13.1",
107+
"webpack-combine-loaders": "^2.0.0",
106108
"webpack-dev-server": "1.14.1",
107109
"zone.js": "^0.6.21"
108110
},

0 commit comments

Comments
 (0)