diff --git a/public/docs/_examples/cb-key-bindings/.gitignore b/public/docs/_examples/cb-key-bindings/.gitignore new file mode 100644 index 0000000000..e69de29bb2 diff --git a/public/docs/_examples/cb-key-bindings/e2e-spec.ts b/public/docs/_examples/cb-key-bindings/e2e-spec.ts new file mode 100644 index 0000000000..b4ffc64f3c --- /dev/null +++ b/public/docs/_examples/cb-key-bindings/e2e-spec.ts @@ -0,0 +1,37 @@ +/// +'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'); + + }); + +}); diff --git a/public/docs/_examples/cb-key-bindings/ts/app/app.component.ts b/public/docs/_examples/cb-key-bindings/ts/app/app.component.ts new file mode 100644 index 0000000000..4b5dbd2a55 --- /dev/null +++ b/public/docs/_examples/cb-key-bindings/ts/app/app.component.ts @@ -0,0 +1,66 @@ +// #docregion +import { Component } from '@angular/core'; + +// #docregion component +@Component({ + selector: 'cb-app', + template: ` + + + + ` +}) +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 diff --git a/public/docs/_examples/cb-key-bindings/ts/app/app.module.ts b/public/docs/_examples/cb-key-bindings/ts/app/app.module.ts new file mode 100644 index 0000000000..2217795180 --- /dev/null +++ b/public/docs/_examples/cb-key-bindings/ts/app/app.module.ts @@ -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 {} diff --git a/public/docs/_examples/cb-key-bindings/ts/app/main.ts b/public/docs/_examples/cb-key-bindings/ts/app/main.ts new file mode 100644 index 0000000000..961a226688 --- /dev/null +++ b/public/docs/_examples/cb-key-bindings/ts/app/main.ts @@ -0,0 +1,6 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/cb-key-bindings/ts/example-config.json b/public/docs/_examples/cb-key-bindings/ts/example-config.json new file mode 100644 index 0000000000..e69de29bb2 diff --git a/public/docs/_examples/cb-key-bindings/ts/index.html b/public/docs/_examples/cb-key-bindings/ts/index.html new file mode 100644 index 0000000000..153a1da1cb --- /dev/null +++ b/public/docs/_examples/cb-key-bindings/ts/index.html @@ -0,0 +1,38 @@ + + + + + + + + + Binding To Key Combination Events + + + + + + + + + + + + + + + + + +

+ Binding To Key Combination Events +

+ + Loading app... + + + diff --git a/public/docs/_examples/cb-key-bindings/ts/plnkr.json b/public/docs/_examples/cb-key-bindings/ts/plnkr.json new file mode 100644 index 0000000000..0131610c20 --- /dev/null +++ b/public/docs/_examples/cb-key-bindings/ts/plnkr.json @@ -0,0 +1,9 @@ +{ + "description": "Set The Document Title In Angular 2", + "files": [ + "!**/*.d.ts", + "!**/*.js", + "!**/*.[1].*" + ], + "tags": [ "cookbook" ] +} diff --git a/public/docs/_examples/cb-key-bindings/ts/sample.css b/public/docs/_examples/cb-key-bindings/ts/sample.css new file mode 100644 index 0000000000..926571d1f6 --- /dev/null +++ b/public/docs/_examples/cb-key-bindings/ts/sample.css @@ -0,0 +1,4 @@ +input { + font-size: 20px ; + width: 400px ; +} \ No newline at end of file diff --git a/public/docs/ts/latest/cookbook/_data.json b/public/docs/ts/latest/cookbook/_data.json index f82d816cef..755cff8206 100644 --- a/public/docs/ts/latest/cookbook/_data.json +++ b/public/docs/ts/latest/cookbook/_data.json @@ -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." diff --git a/public/docs/ts/latest/cookbook/key-bindings.jade b/public/docs/ts/latest/cookbook/key-bindings.jade new file mode 100644 index 0000000000..9157f492fc --- /dev/null +++ b/public/docs/ts/latest/cookbook/key-bindings.jade @@ -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 + — 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) diff --git a/public/resources/images/cookbooks/key-bindings/key-bindings.gif b/public/resources/images/cookbooks/key-bindings/key-bindings.gif new file mode 100644 index 0000000000..adcaec23d1 Binary files /dev/null and b/public/resources/images/cookbooks/key-bindings/key-bindings.gif differ