Skip to content

Commit

Permalink
[RFC][UN-14114] Add groups to uni select (#260)
Browse files Browse the repository at this point in the history
* add groups to uni select

* improvements
  • Loading branch information
carantunes authored and AndreJoaquim committed Aug 29, 2018
1 parent e5cc5f9 commit 69e1876
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 20 deletions.
21 changes: 15 additions & 6 deletions addon/components/uni-select.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Component from '@ember/component';
import { A } from '@ember/array';
import { isNone, isPresent } from '@ember/utils';
import layout from '../templates/components/uni-select';
import { computed } from '@ember/object';

export default Component.extend({
layout,
Expand All @@ -10,9 +11,13 @@ export default Component.extend({

options: [],
selected: null,
selectedGroup: null,
placeholder: null,
useAlias: false,
aliasValue: null,
groups: [],

hasGroups: computed.gt('groups.length', 0),

onChange() {},

Expand All @@ -24,36 +29,40 @@ export default Component.extend({
}

if (this.get('selected')) {
this._changeAliasValue(this.get('selected'));
this._changeAliasValue(this.get('selected'), this.get('selectedGroup'));

return;
}

if (isNone(this.get('placeholder'))) {
this._changeAliasValue(this._getFirstAvailableValue());
let group = this.get('hasGroups') ? this.get('groups')[0].key : null;
this._changeAliasValue(this._getFirstAvailableValue(), group);
}
},

actions: {
changeSelected({ target }) {
if (this.get('useAlias')) {
this._changeAliasValue(target.value);
let group = this.get('hasGroups') ? target.options[target.selectedIndex].parentNode.getAttribute('key') : null;
this._changeAliasValue(target.value, group);
}

this.get('onChange')(target.value);
}
},

_changeAliasValue(key) {
let option = A(this.get('options')).findBy('key', key);
_changeAliasValue(key, group = null) {
let options = group ? A(this.get('groups')).findBy('key', group).options : this.get('options');
let option = A(options).findBy('key', key);

if (isPresent(option)) {
this.set('aliasValue', option.alias);
}
},

_getFirstAvailableValue() {
let option = A(this.get('options')).find(({ disabled }) => isNone(disabled));
let options = this.get('hasGroups') ? this.get('groups')[0].options : this.get('options');
let option = A(options).find(({ disabled }) => isNone(disabled));

return isPresent(option) ? option.key : null;
}
Expand Down
34 changes: 25 additions & 9 deletions addon/templates/components/uni-select.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,31 @@
{{placeholder}}
</option>
{{/if}}
{{#each options as |option|}}
<option disabled={{option.disabled}} selected={{if (eq option.key selected) "selected"}} value={{option.key}} class="uni-select__option">
{{#if hasBlock}}
{{yield option}}
{{else}}
{{option.value}}
{{/if}}
</option>
{{/each}}
{{#if groups}}
{{#each groups as |group|}}
<optgroup label={{group.label}} key={{group.key}}>
{{#each group.options as |option|}}
<option disabled={{option.disabled}} selected={{if (eq option.key selected) "selected"}} value={{option.key}} class="uni-select__option">
{{#if hasBlock}}
{{yield option}}
{{else}}
{{option.value}}
{{/if}}
</option>
{{/each}}
</optgroup>
{{/each}}
{{else}}
{{#each options as |option|}}
<option disabled={{option.disabled}} selected={{if (eq option.key selected) "selected"}} value={{option.key}} class="uni-select__option">
{{#if hasBlock}}
{{yield option}}
{{else}}
{{option.value}}
{{/if}}
</option>
{{/each}}
{{/if}}
</select>

{{#if useAlias}}
Expand Down
146 changes: 141 additions & 5 deletions tests/integration/components/uni-select-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,52 @@ moduleForComponent('uni-select', 'Integration | Component | uni select', {
{ key: 2, value: 'long explanation for two', alias: 'two' }
]);
this.set('placeholder', 'Pick me!');
this.set('groups', [
{
key: 'g-1',
label: 'group 1',
options: [
{ key: 'pt', value: 'Portugal' },
{ key: 'it', value: 'Italy' }
]
},
{
key: 'g-2',
label: 'group 2',
options: [
{ key: 'nl', value: 'Nederlands' },
{ key: 'en', value: 'England' }
]
}
]);
this.set('disabledOptionsGroups', [
{
key: 'g-1',
label: 'group 1',
options: [
{ key: 'pt', value: 'Portugal', disabled: true },
{ key: 'it', value: 'Italy', disabled: true }
]
},
{
key: 'g-2',
label: 'group 2',
options: [
{ key: 'nl', value: 'Nederlands', disabled: false },
{ key: 'en', value: 'England' }
]
}
]);
this.set('aliasGroups', [
{
key: 'g-1',
label: 'group 1',
options: [
{ key: 1, value: 'long explanation for one', alias: 'one' },
{ key: 2, value: 'long explanation for two', alias: 'two' }
]
}
]);
}
});

Expand All @@ -31,7 +77,17 @@ test('It renders', function(assert) {
this.render(hbs`{{uni-select options=options}}`);

assert.ok(find('.uni-select'), 'It renders the select');
assert.ok(findAll('.uni-select__option').length, 4, 'It renders the four options');
assert.equal(findAll('.uni-select__option').length, 4, 'It renders the four options');
});

test('It renders groups', function(assert) {
assert.expect(3);

this.render(hbs`{{uni-select groups=groups}}`);

assert.ok(find('.uni-select'), 'It renders the select');
assert.equal(findAll('.uni-select__option').length, 4, 'It renders the options');
assert.equal(findAll('optgroup').length, 2, 'It renders the groups');
});

test('It renders with placeholder', function(assert) {
Expand All @@ -40,7 +96,17 @@ test('It renders with placeholder', function(assert) {
this.render(hbs`{{uni-select options=options placeholder=placeholder}}`);

assert.ok(find('.uni-select'), 'It renders the select');
assert.ok(findAll('.uni-select__option').length, 5, 'It renders the four options and the placeholder');
assert.equal(findAll('option').length, 5, 'It renders the four options and the placeholder');
});

test('It renders groups with placeholder', function(assert) {
assert.expect(3);

this.render(hbs`{{uni-select groups=groups placeholder=placeholder}}`);

assert.ok(find('.uni-select'), 'It renders the select');
assert.equal(findAll('option').length, 5, 'It renders the four options and the placeholder');
assert.equal(findAll('optgroup').length, 2, 'It renders the groups');
});

test('It ignores the placeholder when there is a selected option', function(assert) {
Expand All @@ -49,15 +115,34 @@ test('It ignores the placeholder when there is a selected option', function(asse
this.set('selected', this.get('options.firstObject.key'));
this.render(hbs`{{uni-select options=options selected=selected placeholder=placeholder}}`);

assert.ok(findAll('.uni-select__option').length, 4, 'It renders the four options and ignores the placeholder');
assert.equal(findAll('.uni-select__option').length, 4, 'It renders the four options and ignores the placeholder');
});

test('It ignores the placeholder when there is a selected option - groups', function(assert) {
assert.expect(2);

this.set('selected', this.get('groups[0].options.firstObject.key'));
this.set('selectedGroup', this.get('groups[0].key'));
this.render(hbs`{{uni-select groups=groups selected=selected selectedGroup=selectedGroup placeholder=placeholder}}`);

assert.equal(findAll('.uni-select__option').length, 4, 'It renders the four options and ignores the placeholder');
assert.equal(findAll('optgroup').length, 2, 'It renders the groups');
});

test('It renders disabled options', function(assert) {
assert.expect(1);

this.render(hbs`{{uni-select options=disabledOptions placeholder=placeholder}}`);

assert.ok(findAll('.uni-select__option:disabled').length, 2, 'It renders the two disabled options');
assert.equal(findAll('.uni-select__option:disabled').length, 2, 'It renders the two disabled options');
});

test('It renders disabled options - groups', function(assert) {
assert.expect(1);

this.render(hbs`{{uni-select groups=disabledOptionsGroups placeholder=placeholder}}`);

assert.equal(findAll('.uni-select__option:disabled').length, 2, 'It renders the two disabled options');
});

test('It renders the yielded content', function(assert) {
Expand All @@ -72,7 +157,23 @@ test('It renders the yielded content', function(assert) {
let options = findAll('.uni-select__option');

this.get('options').forEach(({ key }, index) => {
assert.ok(options[index].textContent.trim(), key, 'It renders the option key as the yielded content');
assert.equal(options[index].textContent.trim(), key, 'It renders the option key as the yielded content');
});
});

test('It renders the yielded content - groups', function(assert) {
assert.expect(this.get('options.length'));

this.render(hbs`
{{#uni-select groups=groups as |option|}}
{{option.key}}
{{/uni-select}}
`);

let options = findAll('.uni-select__option');

this.get('options').forEach(({ key }, index) => {
assert.equal(options[index].textContent.trim(), key, 'It renders the option key as the yielded content');
});
});

Expand All @@ -87,6 +188,17 @@ test('It renders placeholder using the useAlias flag', function(assert) {
assert.equal(find('div.uni-select').textContent.trim(), 'Pick me!');
});

test('It renders placeholder using the useAlias flag - groups', function(assert) {
assert.expect(2);

this.set('useAlias', true);

this.render(hbs`{{uni-select groups=aliasGroups useAlias=useAlias placeholder=placeholder}}`);

assert.equal(this.$('select.uni-select').val(), null);
assert.equal(find('div.uni-select').textContent.trim(), 'Pick me!');
});

test('It renders the first available value when a placeholder is not provided and the useAlias flag is set to true', function(assert) {
assert.expect(2);

Expand All @@ -98,6 +210,17 @@ test('It renders the first available value when a placeholder is not provided an
assert.equal(find('div.uni-select').textContent.trim(), 'one');
});

test('It renders the first available value when a placeholder is not provided and the useAlias flag is set to true - groups', function(assert) {
assert.expect(2);

this.set('useAlias', true);

this.render(hbs`{{uni-select groups=aliasGroups useAlias=useAlias}}`);

assert.equal(this.$('select.uni-select').val(), 1);
assert.equal(find('div.uni-select').textContent.trim(), 'one');
});

test('It renders the alias of the selected option', function(assert) {
assert.expect(2);

Expand All @@ -109,3 +232,16 @@ test('It renders the alias of the selected option', function(assert) {
assert.equal(this.$('select.uni-select').val(), 2);
assert.equal(find('div.uni-select').textContent.trim(), 'two');
});

test('It renders the alias of the selected option - groups', function(assert) {
assert.expect(2);

this.set('useAlias', true);
this.set('selected', 2);
this.set('selectedGroup', 'g-1');

this.render(hbs`{{uni-select groups=aliasGroups useAlias=useAlias selected=selected selectedGroup=selectedGroup placeholder=placeholder}}`);

assert.equal(this.$('select.uni-select').val(), 2);
assert.equal(find('div.uni-select').textContent.trim(), 'two');
});

0 comments on commit 69e1876

Please sign in to comment.