Skip to content

Commit

Permalink
Merge pull request #315 from cibernox/allow_to_opt_out_to_search_in_m…
Browse files Browse the repository at this point in the history
…ultiple_select

[FEATURE] Disable search in multiple selects
  • Loading branch information
cibernox committed Feb 11, 2016
2 parents 14d342b + 4448213 commit 26b1905
Show file tree
Hide file tree
Showing 11 changed files with 113 additions and 35 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Master

- [FEATURE] Search can be disabled in multiple selects, instead of only in single selects.
- [BUGFIX] Pressing enter in a select without searchbox correctly selects the highlighted element

# 0.9.0-beta.1
Expand Down
23 changes: 22 additions & 1 deletion addon/components/power-select-multiple.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Ember from 'ember';
import layout from '../templates/components/power-select-multiple';
import fallbackIfUndefined from '../utils/computed-fallback-if-undefined';
import { emberPowerSelectBuildSelection as buildNewSelection } from '../helpers/ember-power-select-build-selection';

const { computed } = Ember;

Expand Down Expand Up @@ -32,11 +33,31 @@ export default Ember.Component.extend({
let action = this.get('onfocus');
if (action) { action(select, e); }
this.focusInput();
},

handleKeydown(select, e) {
let action = this.get('onkeydown');
if (action) { action(select, e); }
if (e.defaultPrevented) { return; }
let selected = Ember.A((this.get('selected') || []));
if (e.keyCode === 13 && select.isOpen) {
e.stopPropagation();
if (select.highlighted !== undefined) {
if (selected.indexOf(select.highlighted) === -1) {
select.actions.choose(buildNewSelection([select.highlighted, selected], { multiple: true }), e);
} else {
select.actions.close(e);
}
} else {
select.actions.close(e);
}
}
}
},

// Methods
focusInput() {
this.element.querySelector('.ember-power-select-trigger-multiple-input').focus();
let input = this.element.querySelector('.ember-power-select-trigger-multiple-input');
if (input) { input.focus(); }
}
});
13 changes: 2 additions & 11 deletions addon/components/power-select-multiple/trigger.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,12 @@ export default Ember.Component.extend({
},

handleKeydown(e) {
let { highlighted, onkeydown, select } = this.getProperties('highlighted', 'onkeydown', 'select');
let { onkeydown, select } = this.getProperties('onkeydown', 'select');
if (onkeydown) { onkeydown(select, e); }
if (e.defaultPrevented) { return; }

let selected = Ember.A((this.get('selected') || []));
if (e.keyCode === 13 && select.isOpen && highlighted !== undefined) {
e.stopPropagation();
if (selected.indexOf(highlighted) === -1) {
select.actions.choose(buildNewSelection([highlighted, selected], { multiple: true }), e);
} else {
select.actions.close(e);
}
} else if (e.keyCode === 8 && isBlank(e.target.value)) {
if (e.keyCode === 8 && isBlank(e.target.value)) {
let lastSelection = get(selected, 'lastObject');
if (lastSelection) {
select.actions.select(buildNewSelection([lastSelection, selected], { multiple: true }), e);
Expand All @@ -74,8 +67,6 @@ export default Ember.Component.extend({
select.actions.search(get(lastSelection, searchField));
}
}
} else {
select.actions.handleKeydown(e);
}
}
},
Expand Down
3 changes: 2 additions & 1 deletion addon/components/power-select.js
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,8 @@ export default Ember.Component.extend({
const ownActions = {
search: this._doSearch.bind(this, dropdown),
highlight: this._doHighlight.bind(this, dropdown),
select: this._doSelect.bind(this, dropdown)
select: this._doSelect.bind(this, dropdown),
choose: (selected, e) => this.send('choose', dropdown, selected, e)
};
return {
isOpen: dropdown.isOpen,
Expand Down
4 changes: 2 additions & 2 deletions addon/templates/components/power-select-multiple.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
options=options
selected=selected
onchange=onchange
onkeydown=onkeydown
onkeydown=(action "handleKeydown")
onfocus=(action "handleFocus")
onopen=(action "handleOpen")
onclose=onclose
Expand Down Expand Up @@ -44,7 +44,7 @@
options=options
selected=selected
onchange=onchange
onkeydown=onkeydown
onkeydown=(action "handleKeydown")
onfocus=(action "handleFocus")
onopen=(action "handleOpen")
onclose=onclose
Expand Down
18 changes: 10 additions & 8 deletions addon/templates/components/power-select-multiple/trigger.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@
</li>
{{/each}}
</ul>
<input type="search" class="ember-power-select-trigger-multiple-input {{elementId}}-input"
tabindex="0" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
aria-controls={{listboxId}}
style={{triggerMultipleInputStyle}}
placeholder={{maybePlaceholder}}
disabled={{disabled}}
oninput={{action "search" value="target.value"}}
onkeydown={{action "handleKeydown"}}>
{{#if searchEnabled}}
<input type="search" class="ember-power-select-trigger-multiple-input {{elementId}}-input"
tabindex="0" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
aria-controls={{listboxId}}
style={{triggerMultipleInputStyle}}
placeholder={{maybePlaceholder}}
disabled={{disabled}}
oninput={{action "search" value="target.value"}}
onkeydown={{action "handleKeydown"}}>
{{/if}}
<span class="ember-power-select-status-icon"></span>
8 changes: 6 additions & 2 deletions addon/templates/components/power-select.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,15 @@
{{yield option term}}
{{/component}}
{{/if}}
{{component afterOptionsComponent select=(readonly select) searchPlaceholder=(readonly searchPlaceholder) searchEnabled=(readonly searchEnabled)}}
{{component afterOptionsComponent
select=(readonly select)
searchPlaceholder=(readonly searchPlaceholder)
searchEnabled=(readonly searchEnabled)}}
{{/with}}
{{else}}
{{#with (hash
isOpen=registeredDropdown.isOpen
highlighted=(readonly highlighted)
actions=(hash
open=registeredDropdown.actions.open
close=registeredDropdown.actions.close
Expand All @@ -81,7 +85,6 @@
{{#component triggerComponent
options=(readonly results)
selected=(readonly selected)
highlighted=(readonly highlighted)
searchText=(readonly searchText)
lastSearchedText=(readonly lastSearchedText)
placeholder=(readonly placeholder)
Expand All @@ -92,6 +95,7 @@
onkeydown=(readonly onkeydown)
listboxId=(readonly optionsId)
selectedItemComponent=(readonly selectedItemComponent)
searchEnabled=(readonly searchEnabled)
searchField=(readonly searchField) as |opt term|}}
{{yield opt term}}
{{/component}}
Expand Down
14 changes: 7 additions & 7 deletions tests/dummy/app/templates/legacy-demo.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@
<input type="text" value="sample input">
<h2 id="title">Welcome to the demo of ember-power-select (provisional name)</h2>

{{#power-select-multiple options=complexOptions selected=choosenCountry onchange=(action (mut choosenCountry)) searchField='name' as |country|}}
{{country.name}}
{{/power-select-multiple}}

<p><strong>Trying to reproduce bug with store.findAll('user')</strong></p>

{{#power-select options=model selected=selectedUser onchange=(action (mut selectedUser)) as |user|}}
Expand Down Expand Up @@ -56,12 +52,12 @@
{{option.code}}: {{option.name}}
{{/power-select}}

<h4>Select multiple [WORK IN PROGRESS]</h4>
<h4>Select multiple with async search</h4>
{{#power-select-multiple options=(readonly simpleOptions) selected=emptyMultipleSelection onchange=(action (mut multipleSelection)) search=(action 'asyncSearch') as |option|}}
{{option}}
{{/power-select-multiple}}

<h4>Select multiple [WORK IN PROGRESS]</h4>
<h4>Select multiple</h4>
{{#power-select-multiple options=(readonly simpleOptions) selected=multipleSelection onchange=(action (mut multipleSelection)) as |option|}}
{{option}}
{{/power-select-multiple}}
Expand Down Expand Up @@ -154,6 +150,11 @@
{{option}}
{{/power-select}}

<h4>The search box can be disabled passing `searchEnabled=false` on multiple selects too</h4>
{{#power-select-multiple searchEnabled=false options=complexOptions selected=choosenCountry onchange=(action (mut choosenCountry)) searchField='name' as |country|}}
{{country.name}}
{{/power-select-multiple}}

<h4>Right to left styles</h4>
{{#power-select options=(readonly complexOptions) dir="rtl" selected=(readonly complexSelected) allowClear=true onchange=(action (mut complexSelected)) as |option|}}
{{option.code}}: {{option.name}}
Expand All @@ -177,7 +178,6 @@
{{opt}}
{{/power-select}}
</div>

<br>
<br>
<br>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,6 @@ test('If the user passes `closeOnSelect=false` the dropdown remains visible afte
assert.equal($('.ember-power-select-dropdown').length, 1, 'Dropdown is rendered');
});


test('If the content of the options is refreshed (starting with empty array proxy) the available options should also refresh', function(assert) {
let done = assert.async();
assert.expect(2);
Expand Down
61 changes: 60 additions & 1 deletion tests/integration/components/power-select/multiple-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,23 @@ test('Pressing ENTER when the select is closed opens and nothing is written on t
assert.equal($('.ember-power-select-dropdown').length, 1, 'Dropdown is rendered');
});

test('Pressing ENTER on a multiple select with `searchEnabled=false` when it is closed opens it', function(assert) {
assert.expect(2);

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

let trigger = this.$('.ember-power-select-trigger')[0];
trigger.focus();
assert.equal($('.ember-power-select-dropdown').length, 0, 'Dropdown is not rendered');
triggerKeydown(trigger, 13);
assert.equal($('.ember-power-select-dropdown').length, 1, 'Dropdown is rendered');
});

test('Pressing ENTER over a highlighted element selects it', function(assert) {
assert.expect(2);

Expand All @@ -290,6 +307,48 @@ test('Pressing ENTER over a highlighted element selects it', function(assert) {
assert.ok(/two/.test($('.ember-power-select-trigger').text().trim()), 'The element was selected');
});

test('Pressing ENTER over a highlighted element on a multiple select with `searchEnabled=false` selects it', function(assert) {
assert.expect(2);

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

clickTrigger();
assert.equal($('.ember-power-select-dropdown').length, 1, 'Dropdown is rendered');
let trigger = this.$('.ember-power-select-trigger')[0];
triggerKeydown(trigger, 40);
triggerKeydown(trigger, 13);
assert.ok(/two/.test($('.ember-power-select-trigger').text().trim()), 'The element was selected');
});


test('Pressing ENTER over a highlighted element on a select with `searchEnabled=false` selects it', function(assert) {
assert.expect(4);

this.numbers = numbers;
this.change = (selected) => {
assert.deepEqual(selected, ['two']);
this.set('foo', selected);
};
this.render(hbs`
{{#power-select-multiple searchEnabled=false options=numbers selected=foo onchange=change as |option|}}
{{option}}
{{/power-select-multiple}}
`);

clickTrigger();
assert.equal(this.$('.ember-power-select-multiple-option').length, 0, 'There is no elements selected');
let trigger = this.$('.ember-power-select-trigger')[0];
triggerKeydown(trigger, 40);
triggerKeydown(trigger, 13);
assert.equal(this.$('.ember-power-select-multiple-option').length, 1, 'There is one element selected');
assert.ok(/two/.test($('.ember-power-select-trigger').text().trim()), 'The element is "two"');
});

test('Pressing ENTER over a highlighted element what is already selected closes the select without doing anything and focuses the trigger', function(assert) {
assert.expect(3);

Expand Down Expand Up @@ -601,4 +660,4 @@ test('The trigger of multiple selects have a special class to distinguish them f

assert.ok(this.$('.ember-power-select-trigger').hasClass('ember-power-select-multiple-trigger'), 'The trigger has the default class');
assert.ok(this.$('.ember-power-select-trigger').hasClass('foobar-trigger'), 'The trigger has the given class');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ test('The onkeydown of multiple selects action receives the public API and the k
this.numbers = numbers;
this.onKeyDown = (select, e) => {
assert.equal(typeof select.isOpen, 'boolean', 'select.isOpen is a boolean');
assert.equal(typeof select.highlighted, 'undefined', 'select.highlighted is still undefined');
assert.equal(typeof select.highlighted, 'string', 'select.highlighted is a string');
assert.equal(typeof select.actions.open, 'function', 'select.actions.open is a function');
assert.equal(typeof select.actions.close, 'function', 'select.actions.close is a function');
assert.equal(typeof select.actions.search, 'function', 'select.actions.search is a function');
Expand Down

0 comments on commit 26b1905

Please sign in to comment.