Skip to content
This repository has been archived by the owner on Nov 6, 2024. It is now read-only.

Commit

Permalink
Fix multiple select display value (#213)
Browse files Browse the repository at this point in the history
  • Loading branch information
jfcere authored Sep 29, 2017
1 parent f3b146e commit dbf9544
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 32 deletions.
36 changes: 13 additions & 23 deletions src/app/select/select-container/select-container.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,39 +42,29 @@ export class MzSelectContainerComponent implements AfterViewInit, OnDestroy {
});

this.selectValueSubscription = this.ngControl.valueChanges.subscribe((value: any) => {
// to synchronize input and select when value changes programmatically
const isDropdownOpen = this.mzSelectDirective.inputElement.hasClass('active');
const inputValue = this.mzSelectDirective.inputElement.val();
const selectedOptionText = this.mzSelectDirective.selectElement
.children('option:selected')
.text();
const options = this.mzSelectDirective.selectElement.children('option');
const selectedOptions = options.filter('option:selected').toArray();
const disabledOptions = options.filter(':disabled').toArray();

// synchronize input and select when value changes programmatically
if (inputValue !== selectedOptionText) {
this.mzSelectDirective.inputElement.val(selectedOptionText);
const selectedOptionText = selectedOptions.length === 0
? disabledOptions.map(option => option.textContent)[0]
: selectedOptions.map(option => option.textContent).join(', ');

const dropdownOptions = this.mzSelectDirective.inputElement
.siblings('ul.dropdown-content')
.children('li');

dropdownOptions
.removeClass('active selected');

dropdownOptions
.filter((index, element: HTMLLIElement) => element.textContent === selectedOptionText)
.filter((index, element: HTMLLIElement) => !element.classList.contains('disabled'))
.addClass('active');

if (this.mzValidationComponent) {
this.mzValidationComponent.setValidationState();
}
if (inputValue !== selectedOptionText && !isDropdownOpen) {
this.mzSelectDirective.updateMaterialSelect();
}
});
}
}

initSelectSubscription() {
if (this.mzSelectDirective) {
this.mzSelectDirective.onUpdate.subscribe(() => this.registerOnBlur());
this.registerOnBlur();
this.mzSelectDirective.onUpdate
.subscribe(() => this.registerOnBlur())
.next();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,6 @@ describe('MzSelectContainerComponent:view', () => {
return nativeElement.querySelector('select');
}

function activeDropdownOptionElement(): HTMLOptionElement {
return nativeElement.querySelector('ul.dropdown-content li.active');
}

it('should be disabled/enabled correctly when control disabled status changes', async(() => {

buildComponent<any>(`
Expand Down Expand Up @@ -189,14 +185,12 @@ describe('MzSelectContainerComponent:view', () => {
tick();

expect(inputElement().value).toBe('Option 2');
expect(activeDropdownOptionElement().textContent).toBe('Option 2');

component.value = null;
fixture.detectChanges();
tick();

expect(inputElement().value).toBe('placeholder');
expect(activeDropdownOptionElement()).toBeFalsy();
});
}));

Expand Down Expand Up @@ -241,22 +235,118 @@ describe('MzSelectContainerComponent:view', () => {
fixture.detectChanges();
tick();

expect(inputElement().value).toBe(value.text);
expect(inputElement().value).toBe('Option 1');

component.value = options[1];
fixture.detectChanges();
tick();

expect(inputElement().value).toBe('Option 2');
expect(activeDropdownOptionElement().textContent).toBe('Option 2');

component.value = null;
fixture.detectChanges();
tick();

expect(inputElement().value).toBe('placeholder');
expect(activeDropdownOptionElement()).toBeFalsy();
});
}));

describe('multiple select', () => {

it('should have correctly value when control value changes using string value', fakeAsync(() => {

buildComponent<{ value: string[] }>(`
<mz-select-container>
<select mz-select multiple
id="select"
[label]="'label'"
[placeholder]="'placeholder'"
[(ngModel)]="value">
<option *ngFor="let option of options" [value]="option">{{ option }}</option>
</select>
</mz-select-container>`,
{
options: ['Option 1', 'Option 2', 'Option 3'],
value: ['Option 2', 'Option 3'],
},
).then((fixture) => {
nativeElement = fixture.nativeElement;
const component = fixture.componentInstance;
fixture.detectChanges();
tick();

expect(inputElement().value).toBe('Option 2, Option 3');

component.value = ['Option 1'];
fixture.detectChanges();
tick();

expect(inputElement().value).toBe('Option 1');

component.value = null;
fixture.detectChanges();
tick();

expect(inputElement().value).toBe('placeholder');
});
}));

it('should have correctly value when control value changes using object value', fakeAsync(() => {

interface Option {
text: string,
value: number,
}

const options: Option[] = [
{ text: 'Option 1', value: 1 },
{ text: 'Option 2', value: 2 },
{ text: 'Option 3', value: 3 },
];

const value = options.slice(0, 1);

buildComponent<{ options: Option[], value: Option[] }>(`
<mz-select-container>
<select mz-select multiple
id="select"
[label]="'label'"
[placeholder]="'placeholder'"
[(ngModel)]="value">
<option *ngFor="let option of options" [ngValue]="option">{{ option.text }}</option>
</select>
</mz-select-container>`,
{
options,
value,
},
).then((fixture) => {
nativeElement = fixture.nativeElement;
const component = fixture.componentInstance;
fixture.detectChanges();

// couldn't force mutationobserver to execute before the end of the test
// therefore options used with *ngFor need to be present for the test to work
$('select').material_select();

fixture.detectChanges();
tick();

expect(inputElement().value).toBe('Option 1');

component.value = options.slice(1, 3);
fixture.detectChanges();
tick();

expect(inputElement().value).toBe('Option 2, Option 3');

component.value = null;
fixture.detectChanges();
tick();

expect(inputElement().value).toBe('placeholder');
});
}));
});
});
});

0 comments on commit dbf9544

Please sign in to comment.