Skip to content

Commit

Permalink
Add also support for the onkeypress action in single selects
Browse files Browse the repository at this point in the history
Note that in single selects this action is fired both when the user presses
a key being the search input the focused element and when the focused
element is the surrounding component (a <div>) so anyone implementing some
functionality using this event will need to check if the target of the event
is an input or not before doing `e.target.value` by example
  • Loading branch information
cibernox committed Nov 27, 2015
1 parent 55e1eb0 commit 1bd4d18
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 46 deletions.
2 changes: 2 additions & 0 deletions addon/components/power-select/single.js
Expand Up @@ -33,6 +33,8 @@ export default PowerSelectBaseComponent.extend({
},

handleKeydown(dropdown, e) {
const onkeydown = this.get('onkeydown');
if (onkeydown) { onkeydown(dropdown, e); }
if (e.defaultPrevented) { return; }
if (e.keyCode === 13 && dropdown.isOpen) { // Enter
this.send('select', dropdown, this.get('_highlighted'), e);
Expand Down
139 changes: 93 additions & 46 deletions tests/integration/components/power-select-test.js
Expand Up @@ -1514,6 +1514,99 @@ test('Pressing ESC while the component is opened closes it and focuses the trigg
assert.ok($('.ember-power-select-trigger').get(0) === document.activeElement, 'The select is focused');
});

test('In single-mode, when the user presses a key being the search input focused the passes `onkeydown` action is invoked with the public API and the event', function(assert) {
assert.expect(7);

this.numbers = numbers;
this.selected = null;
this.handleKeydown = (select, e) => {
assert.ok(select.isOpen, 'The yieded object has the `isOpen` key');
assert.ok(select.actions.open, 'The yieded object has an `actions.open` key');
assert.ok(select.actions.close, 'The yieded object has an `actions.close` key');
assert.ok(select.actions.toggle, 'The yieded object has an `actions.toggle` key');
assert.equal(e.keyCode, 13, 'The event is received as second argument');
};

this.render(hbs`
{{#power-select options=numbers selected=selected onchange=(action (mut foo)) onkeydown=(action handleKeydown) as |option|}}
{{option}}
{{/power-select}}
`);

Ember.run(() => this.$('.ember-power-select-trigger').click());
assert.equal($('.ember-power-select-dropdown').length, 1, 'The select is opened');
Ember.run(() => triggerKeydown($('.ember-power-select-search input')[0], 13));
assert.equal($('.ember-power-select-dropdown').length, 0, 'The select is closed');
});

test('in single-mode if the users calls preventDefault on the event received in the `onkeydown` action it prevents the component to do the usual thing', function(assert) {
assert.expect(2);

this.numbers = numbers;
this.selected = null;
this.handleKeydown = (select, e) => {
e.preventDefault();
};

this.render(hbs`
{{#power-select options=numbers selected=selected onchange=(action (mut foo)) onkeydown=(action handleKeydown) as |option|}}
{{option}}
{{/power-select}}
`);

Ember.run(() => this.$('.ember-power-select-trigger').click());
assert.equal($('.ember-power-select-dropdown').length, 1, 'The select is opened');
Ember.run(() => triggerKeydown($('.ember-power-select-search input')[0], 13));
assert.equal($('.ember-power-select-dropdown').length, 1, 'The select is still opened');
});

test('In multiple-mode, when the user presses a key being the search input focused the passes `onkeydown` action is invoked with the public API and the event', function(assert) {
assert.expect(7);

this.numbers = numbers;
this.selectedNumbers = [];
this.handleKeydown = (select, e) => {
assert.ok(select.isOpen, 'The yieded object has the `isOpen` key');
assert.ok(select.actions.open, 'The yieded object has an `actions.open` key');
assert.ok(select.actions.close, 'The yieded object has an `actions.close` key');
assert.ok(select.actions.toggle, 'The yieded object has an `actions.toggle` key');
assert.equal(e.keyCode, 13, 'The event is received as second argument');
};

this.render(hbs`
{{#power-select multiple=true options=numbers selected=selectedNumbers onchange=(action (mut foo)) onkeydown=(action handleKeydown) as |option|}}
{{option}}
{{/power-select}}
`);

Ember.run(() => this.$('.ember-power-select-trigger').click());
assert.equal($('.ember-power-select-dropdown').length, 1, 'The select is opened');
Ember.run(() => triggerKeydown($('.ember-power-select-trigger-multiple-input')[0], 13));
assert.equal($('.ember-power-select-dropdown').length, 0, 'The select is closed');
});

test('in multiple-mode if the users calls preventDefault on the event received in the `onkeydown` action it prevents the component to do the usual thing', function(assert) {
assert.expect(2);

this.numbers = numbers;
this.selectedNumbers = [];
this.handleKeydown = (select, e) => {
e.preventDefault();
};

this.render(hbs`
{{#power-select multiple=true options=numbers selected=selectedNumbers onchange=(action (mut foo)) onkeydown=(action handleKeydown) as |option|}}
{{option}}
{{/power-select}}
`);

Ember.run(() => this.$('.ember-power-select-trigger').click());
assert.equal($('.ember-power-select-dropdown').length, 1, 'The select is opened');
Ember.run(() => triggerKeydown($('.ember-power-select-trigger-multiple-input')[0], 13));
assert.equal($('.ember-power-select-dropdown').length, 1, 'The select is still opened');
});


/**
9 - Disabled select/options
a) [DONE] A disabled dropdown doesn't responds to mouse/keyboard events
Expand Down Expand Up @@ -2157,52 +2250,6 @@ test('When passed `disabled=true`, the input inside the trigger is also disabled
assert.equal(this.$('.ember-power-select-multiple-remove-btn').length, 0, 'There is no button to remove selected elements');
});

test('When the user presses a key being the search input focused the passes `onkeydown` action is invoked with the public API and the event', function(assert) {
assert.expect(7);

this.numbers = numbers;
this.selectedNumbers = [];
this.handleKeydown = (select, e) => {
assert.ok(select.isOpen, 'The yieded object has the `isOpen` key');
assert.ok(select.actions.open, 'The yieded object has an `actions.open` key');
assert.ok(select.actions.close, 'The yieded object has an `actions.close` key');
assert.ok(select.actions.toggle, 'The yieded object has an `actions.toggle` key');
assert.equal(e.keyCode, 13, 'The event is received as second argument');
};

this.render(hbs`
{{#power-select multiple=true options=numbers selected=selectedNumbers onchange=(action (mut foo)) onkeydown=(action handleKeydown) as |option|}}
{{option}}
{{/power-select}}
`);

Ember.run(() => this.$('.ember-power-select-trigger').click());
assert.equal($('.ember-power-select-dropdown').length, 1, 'The select is opened');
Ember.run(() => triggerKeydown($('.ember-power-select-trigger-multiple-input')[0], 13));
assert.equal($('.ember-power-select-dropdown').length, 0, 'The select is closed');
});

test('if the users calls preventDefault on the event received in the `onkeydown` action it prevents the component to do the usual thing', function(assert) {
assert.expect(2);

this.numbers = numbers;
this.selectedNumbers = [];
this.handleKeydown = (select, e) => {
e.preventDefault();
};

this.render(hbs`
{{#power-select multiple=true options=numbers selected=selectedNumbers onchange=(action (mut foo)) onkeydown=(action handleKeydown) as |option|}}
{{option}}
{{/power-select}}
`);

Ember.run(() => this.$('.ember-power-select-trigger').click());
assert.equal($('.ember-power-select-dropdown').length, 1, 'The select is opened');
Ember.run(() => triggerKeydown($('.ember-power-select-trigger-multiple-input')[0], 13));
assert.equal($('.ember-power-select-dropdown').length, 1, 'The select is still opened');
});

/**
10 - Dropdown positioning
a) [UNTESTABLE??] By default the dropdown is placed automatically depending on the available space around the select.
Expand Down

0 comments on commit 1bd4d18

Please sign in to comment.