diff --git a/spec/tests/autocomplete/autocompleteSpec.js b/spec/tests/autocomplete/autocompleteSpec.js index 7ad08978f7..f5e5c08b57 100644 --- a/spec/tests/autocomplete/autocompleteSpec.js +++ b/spec/tests/autocomplete/autocompleteSpec.js @@ -263,5 +263,41 @@ describe('Autocomplete Plugin', () => { done(); }, 10); }); + + it('selected options should preselect option in single select', (done) => { + const normal = document.querySelector('#normal-autocomplete'); + M.Autocomplete.getInstance(normal).destroy(); + M.Autocomplete.init(normal, { + data: [{ id: 'Value A', text: 'Text 1' }, { id: 'Value B', text: 'Text 2' }], + selected: ['Value B'], + }); + + setTimeout(() => { + expect(normal.value) + .withContext('Value should equal chosen option.') + .toBe('Text 2'); + done(); + }, 10); + }); + + it('selected options should preselect options in multi select', (done) => { + const normal = document.querySelector('#normal-autocomplete'); + M.Autocomplete.getInstance(normal).destroy(); + M.Autocomplete.init(normal, { + data: [{ id: 'Value A', text: 'Text 1' }, { id: 'Value B', text: 'Text 2' }, { id: 'Value C', text: 'Text 3' }], + selected: ['Value A', 'Value B'] + }); + const instance = M.Autocomplete.getInstance(normal); + + setTimeout(() => { + const dropdownAutocompleteIds = Array.from(instance.selectedValues).map( + (selectedValue) => selectedValue.id + ); + expect(dropdownAutocompleteIds) + .withContext('Value should equal chosen option.') + .toEqual(['Value A', 'Value B']); + done(); + }, 10); + }); }); }); diff --git a/src/autocomplete.ts b/src/autocomplete.ts index 56619e76aa..b9a1ce122d 100644 --- a/src/autocomplete.ts +++ b/src/autocomplete.ts @@ -66,6 +66,10 @@ export interface AutocompleteOptions extends BaseOptions { * @default {} */ dropdownOptions: Partial; + /** + * Predefined selected values + */ + selected: number[] | string[]; } const _defaults: AutocompleteOptions = { @@ -90,7 +94,8 @@ const _defaults: AutocompleteOptions = { ); }, maxDropDownHeight: '300px', - allowUnsafeHTML: false + allowUnsafeHTML: false, + selected: [] }; export class Autocomplete extends Component { @@ -124,7 +129,7 @@ export class Autocomplete extends Component { this.count = 0; this.activeIndex = -1; this.oldVal = ''; - this.selectedValues = []; + this.selectedValues = this.selectedValues || this.options.selected.map((value) => { id: value }) || []; this.menuItems = this.options.data || []; this.$active = null; this._mousedown = false; @@ -242,6 +247,10 @@ export class Autocomplete extends Component { // Sketchy removal of dropdown click handler this.el.removeEventListener('click', this.dropdown._handleClick); + if(!this.options.isMultiSelect && !(this.options.selected.length === 0)) { + const selectedValue = this.menuItems.filter((value) => value.id === this.selectedValues[0].id); + this.el.value = selectedValue[0].text; + } // Set Value if already set in HTML if (this.el.value) this.selectOption(this.el.value); // Add StatusInfo @@ -543,16 +552,18 @@ export class Autocomplete extends Component { const entry = this.menuItems.find((item) => item.id == id); if (!entry) return; // Toggle Checkbox - const li = this.container.querySelector('li[data-id="' + id + '"]'); - if (!li) return; + /* const li = this.container.querySelector('li[data-id="' + id + '"]'); + if (!li) return;*/ if (this.options.isMultiSelect) { - const checkbox = li.querySelector('input[type="checkbox"]'); - checkbox.checked = !checkbox.checked; - if (checkbox.checked) this.selectedValues.push(entry); - else - this.selectedValues = this.selectedValues.filter( - (selectedEntry) => selectedEntry.id !== entry.id - ); + /* const checkbox = li.querySelector('input[type="checkbox"]'); + checkbox.checked = !checkbox.checked;*/ + if (!(this.selectedValues.filter( + (selectedEntry) => selectedEntry.id === entry.id + ).length >= 1)) this.selectedValues.push(entry); + else this.selectedValues = this.selectedValues.filter( + (selectedEntry) => selectedEntry.id !== entry.id + ); + this._renderDropdown(); this.el.focus(); } else { // Single-Select