Skip to content
This repository was archived by the owner on Dec 4, 2017. It is now read-only.

docs(cookbook - key bindings) Adding key-binding cookbook. #1558

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
37 changes: 37 additions & 0 deletions public/docs/_examples/cb-key-bindings/e2e-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('Key combination bindings', function () {

beforeAll(function () {
browser.get('');
});

it('should pick up key combinations', function () {
const input = element(by.css('input'));

input.click();

input.sendKeys(protractor.Key.ENTER);
expect(element.all(by.css('li')).last().getText()).toContain('Enter');

input.sendKeys(protractor.Key.SHIFT, protractor.Key.ENTER);
expect(element.all(by.css('li')).last().getText()).toContain('Shift+Enter');

input.sendKeys(protractor.Key.META, protractor.Key.ENTER);
expect(element.all(by.css('li')).last().getText()).toContain('Meta+Enter');

input.sendKeys(' ');
expect(element.all(by.css('li')).last().getText()).toContain('Space');

input.sendKeys('a');
expect(element.all(by.css('li')).last().getText()).toContain('a');

input.sendKeys(protractor.Key.SHIFT, 'a');
expect(element.all(by.css('li')).last().getText()).toContain('A');

input.sendKeys(protractor.Key.ESCAPE);
expect(element.all(by.css('li')).last().getText()).toContain('Escape');

});

});
66 changes: 66 additions & 0 deletions public/docs/_examples/cb-key-bindings/ts/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// #docregion
import { Component } from '@angular/core';

// #docregion component
@Component({
selector: 'cb-app',
template: `
<input
(keydown.Enter)="handleKey('Enter')"
(keydown.Meta.Enter)="handleKey('Meta+Enter')"
(keydown.Shift.Enter)="handleKey('Shift+Enter')"
(keydown.Control.Enter)="handleKey('Control+Enter')"
(keydown.Alt.Enter)="handleKey('Alt+Enter')"
(keydown.Alt.Meta.Enter)="handleKey('Alt+Meta+Enter')"
(keydown.Shift.Meta.Enter)="handleKey('Shift+Meta+Alt+Enter')"
(keydown.Alt.Shift.Meta.Enter)="handleKey('Alt+Shift+Meta+Alt+Enter')"
(keydown.Control.Alt.Shift.Meta.Enter)="handleKey('Control+Alt+Shift+Meta+Alt+Enter')"
(keydown.Shift)="handleKey('Shift')"

(keydown.a)="handleKey('a')"
(keydown.Shift.a)="handleKey('A')"
(keydown.Shift.?)="handleKey('?')"
(keydown.Tab)="handleKey('Tab :: CANCELED', $event)"
(keydown.Space)="handleKey('Space')"
(keydown.Dot)="handleKey('Dot')"

(keydown.ArrowLeft)="handleKey('ArrowLeft')"
(keydown.ArrowUp)="handleKey('ArrowUp')"
(keydown.ArrowRight)="handleKey('ArrowRight')"
(keydown.ArrowDown)="handleKey('ArrowDown')"
(keydown.ArrowDown)="handleKey('ArrowDown')"
(keydown.End)="handleKey('End')"
(keydown.Home)="handleKey('Home')"
(keydown.PageDown)="handleKey('PageDown')"
(keydown.PageUp)="handleKey('PageUp')"

(keydown.Meta.s)="handleKey('Meta+S (Save) :: CANCELED', $event)"
(keydown.Meta.o)="handleKey('Meta+O (Open) :: CANCELED', $event)"
(keydown.Meta.p)="handleKey('Meta+P (Print) :: CANCELED', $event)"
(keydown.Meta.f)="handleKey('Meta+F (Find) :: CANCELED', $event)"

(keydown.Escape)="handleKey('Escape')"
autofocus>

<ul>
<li *ngFor="let item of logItems">
Key event: {{ item }}
</li>
</ul>
`
})
export class AppComponent {
logItems: string[] = [];

handleKey(description: string, event?: KeyboardEvent): void {
if (description === 'Escape') {
this.logItems = [];
}

this.logItems.push(description);

event && event.preventDefault();
}

}
// #enddocregion component
11 changes: 11 additions & 0 deletions public/docs/_examples/cb-key-bindings/ts/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent } from './app.component';

@NgModule({
imports: [ BrowserModule ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule {}
6 changes: 6 additions & 0 deletions public/docs/_examples/cb-key-bindings/ts/app/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// #docregion
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule);
38 changes: 38 additions & 0 deletions public/docs/_examples/cb-key-bindings/ts/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<base href="/">

<title>
Binding To Key Combination Events
</title>

<link rel="stylesheet" type="text/css" href="./styles.css" />
<link rel="stylesheet" type="text/css" href="./sample.css" />

<!-- Polyfill(s) for older browsers -->
<script src="node_modules/core-js/client/shim.min.js"></script>

<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>

<script src="systemjs.config.js"></script>
<script>
System.import('app')
.then(function() { console.info( "System.js loaded your application module." )})
.catch(function(err){ console.error(err); });
</script>
</head>
<body>

<h1>
Binding To Key Combination Events
</h1>

<cb-app>Loading app...</cb-app>

</body>
</html>
9 changes: 9 additions & 0 deletions public/docs/_examples/cb-key-bindings/ts/plnkr.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"description": "Set The Document Title In Angular 2",
"files": [
"!**/*.d.ts",
"!**/*.js",
"!**/*.[1].*"
],
"tags": [ "cookbook" ]
}
4 changes: 4 additions & 0 deletions public/docs/_examples/cb-key-bindings/ts/sample.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
input {
font-size: 20px ;
width: 400px ;
}
5 changes: 5 additions & 0 deletions public/docs/ts/latest/cookbook/_data.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@
"intro": "Render dynamic forms with FormGroup"
},

"key-bindings": {
"title": "Key Bindings",
"intro": "Binding to Key Combinations"
},

"rc4-to-rc5": {
"title": "RC4 to RC5 Migration",
"intro": "Migrate your RC4 app to RC5 in minutes."
Expand Down
95 changes: 95 additions & 0 deletions public/docs/ts/latest/cookbook/key-bindings.jade
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
include ../_util-fns

a( id='top' )

:marked
With Angular's powerful event-binding syntax, we can bind to any native DOM
(Document Object Model) event by wrapping the **event type** in parentheses.
For example, if we wanted to bind to the `focus` or `click` event, we would
add an element binding for `(focus)` or `(click)`, respectively. The same can
be done for `(keydown)`, `(keyup)`, and `(keypress)` events. However, with
key events, we generally want to do more than _just_ bind to the event
&mdash; we want to respond to specific key combinations. Luckily, Angular's
event-binding system can help us accomplish this as well.

:marked
When defining a `keydown` or `keyup` event-binding, we can provide additional
settings that determine which keyboard events will cause our event handler to
be invoked. In the event-binding syntax, these settings are provided as a
dot-delimited suffix to the core event type.

:marked
So, for example, if we wanted to respond specifically to the `Enter` key in a
`keydown` event, we would add the following element binding:
`(keydown.Enter)`. And, if we wanted to respond to the increasingly-popular
`Command+Enter` key combination, we would add the following element binding:
`(keydown.Meta.Enter)`.

:marked
Any alpha-numeric character can be used in the event-binding as long as it
doesn't break the HTML parser (Caution: `>` will break the parser). Special
characters like the period and the space are made available via `Dot` and
`Space`, respectively. In addition, [many control characters](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key#Key_values)
like `ArrowLeft` and `ArrowRight` can be used as well.

.l-sub-section
:marked
Commonly-used control characters include:

* `Enter`
* `Escape`
* `ArrowLeft`, `ArrowUp`, `ArrowRight`, `ArrowDown`
* `Tab`

:marked
The following modifier modifiers can be used (either on their own or in
combination with other modifiers and characters):

:marked
* `Alt`
* `Control`
* `Meta` (`Command` key on the Mac, `Start` key on Windows)
* `Shift`

:marked
None of the event-binding settings are case-sensitive. `Tab` is the same as
`tab` and `A` is the same as `a`. However, the event settings have to match
on all event conditions. This means that our event-bindings have to account
for modifier keys if modifier keys are required in order to render the target
character. For example:

:marked
* `keydown.a` codes for `a`.
* `keydown.Shift.a` codes for `A` _(if the Shift key was depressed)_.
* `keydown.Shift.?` codes for the question mark.

:marked
In the following code, we're attaching multiple key combination events to a
single `input` and then logging the key values to a list:

:marked
**See the [live example](/resources/live-examples/cb-key-bindings/ts/plnkr.html)**.

+makeExample( 'cb-key-bindings/ts/app/app.component.ts', 'component', 'app/app.component.ts' )(format='.')

:marked
When we run this demo and try some of the key combination bindings, we get
the following output:

figure.image-display
img(src='/resources/images/cookbooks/key-bindings/key-bindings.gif' alt='Key Bindings')

:marked
When we use these key bindings, Angular doesn't alter the behavior of the
keys in any way. As such, if we want to override the default behavior
(such as preventing the `Tab` key from removing focus from an input), we
have to call the `.preventDefault()` method on the associated event object.

:marked
At the time of this writing, these special key combination settings are only
supported at the element level and only for the `keydown` and `keyup` events.
Meaning, these cannot be used with the global `window:` or `document:`
targets; and, they cannot be used with the `keypress` event.

:marked
[Back to top](#top)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.