From 2cc84351214e761651c9a58d5f54fea49e18f4b9 Mon Sep 17 00:00:00 2001 From: Carina Antunes Date: Mon, 27 Aug 2018 11:54:47 +0100 Subject: [PATCH] add groups to uni select --- addon/components/uni-select.js | 33 +++- addon/templates/components/uni-select.hbs | 34 ++-- .../integration/components/uni-select-test.js | 146 +++++++++++++++++- 3 files changed, 193 insertions(+), 20 deletions(-) diff --git a/addon/components/uni-select.js b/addon/components/uni-select.js index 1509d77b..fbdfb57d 100644 --- a/addon/components/uni-select.js +++ b/addon/components/uni-select.js @@ -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, @@ -10,9 +11,15 @@ export default Component.extend({ options: [], selected: null, + selectedGroup: null, placeholder: null, useAlias: false, aliasValue: null, + groups: [], + + hasGroups: computed('groups', function() { + return this.get('groups').length > 0; + }), onChange() {}, @@ -24,28 +31,36 @@ 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 = this.get('options'); + + if (group) { + options = A(this.get('groups')).findBy('key', group).options; + } + + let option = A(options).findBy('key', key); if (isPresent(option)) { this.set('aliasValue', option.alias); @@ -53,7 +68,13 @@ export default Component.extend({ }, _getFirstAvailableValue() { - let option = A(this.get('options')).find(({ disabled }) => isNone(disabled)); + let options = this.get('options'); + + if (this.get('groups').length > 0) { + options = this.get('groups')[0].options; + } + + let option = A(options).find(({ disabled }) => isNone(disabled)); return isPresent(option) ? option.key : null; } diff --git a/addon/templates/components/uni-select.hbs b/addon/templates/components/uni-select.hbs index b06b5749..48d0d168 100644 --- a/addon/templates/components/uni-select.hbs +++ b/addon/templates/components/uni-select.hbs @@ -4,15 +4,31 @@ {{placeholder}} {{/if}} - {{#each options as |option|}} - - {{/each}} + {{#if groups}} + {{#each groups as |group|}} + + {{#each group.options as |option|}} + + {{/each}} + + {{/each}} + {{else}} + {{#each options as |option|}} + + {{/each}} + {{/if}} {{#if useAlias}} diff --git a/tests/integration/components/uni-select-test.js b/tests/integration/components/uni-select-test.js index 8b3fddfb..4b48a471 100644 --- a/tests/integration/components/uni-select-test.js +++ b/tests/integration/components/uni-select-test.js @@ -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' } + ] + } + ]); } }); @@ -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) { @@ -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) { @@ -49,7 +115,18 @@ 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) { @@ -57,7 +134,15 @@ test('It renders disabled options', function(assert) { 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) { @@ -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'); }); }); @@ -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); @@ -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); @@ -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', 'group-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'); +});