Skip to content

Commit

Permalink
fix multiple unselected items
Browse files Browse the repository at this point in the history
  • Loading branch information
anjmao committed Jun 11, 2018
1 parent ef5e35f commit 7c6fe82
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 35 deletions.
31 changes: 27 additions & 4 deletions src/ng-select/items-list.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ describe('ItemsList', () => {
let cmp: NgSelectComponent;
beforeEach(() => {
cmp = ngSelect();
cmp.multiple = true;
list = itemsList(cmp);
});

Expand All @@ -158,7 +159,7 @@ describe('ItemsList', () => {
expect(list.selectedItems.length).toBe(0);
});

it('should unselect selected item and return it back to filtered items list when hideSelected=true', () => {
it('should unselect selected item and insert it back to filtered items list when hideSelected=true', () => {
cmp.hideSelected = true;
list.setItems([
{ label: 'K1', val: 'V1' },
Expand All @@ -171,7 +172,7 @@ describe('ItemsList', () => {
expect(list.filteredItems.length).toBe(2);
});

it('should unselect selected group and return it back to filtered items with child items when hideSelected=true', () => {
it('should unselect selected group and insert it back to filtered items with child items when hideSelected=true', () => {
cmp.hideSelected = true;
cmp.groupBy = 'groupKey';
list.setItems([
Expand All @@ -185,18 +186,40 @@ describe('ItemsList', () => {
expect(list.filteredItems.length).toBe(3);
});

it('should unselect selected item and return it back to filtered with item parent group items when hideSelected=true', () => {
it('should unselect selected item and insert it back to filtered with item parent group items when hideSelected=true', () => {
cmp.hideSelected = true;
cmp.groupBy = 'groupKey';
list.setItems([
{ label: 'K1', val: 'V1', groupKey: 'K1' }
{ label: 'K1', val: 'V1', groupKey: 'G1' }
]);

list.select(list.items[1]);
expect(list.filteredItems.length).toBe(0);
list.unselect(list.items[1]);
expect(list.filteredItems.length).toBe(2);
});

it('should not inserted unselected group parent item to filtered items if it is already exsists', () => {
cmp.hideSelected = true;
cmp.groupBy = 'groupKey';
list.setItems([
// G1
{ label: 'K1', val: 'V1', groupKey: 'G1' },
{ label: 'K2', val: 'V2', groupKey: 'G1' },
// G2
{ label: 'K3', val: 'V3', groupKey: 'G2' },
{ label: 'K4', val: 'V4', groupKey: 'G2' },
]);

list.select(list.items[1]);
list.select(list.items[2]);
list.select(list.items[4]);
list.unselect(list.items[1]);
list.unselect(list.items[2]);

expect(list.filteredItems.length).toBe(5);
expect(list.selectedItems.length).toBe(1);
});
});
});

Expand Down
70 changes: 40 additions & 30 deletions src/ng-select/items-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,44 +65,24 @@ export class ItemsList {
if (item.selected || this.maxItemsSelected) {
return;
}
if (!this._ngSelect.multiple) {
const multiple = this._ngSelect.multiple;
if (!multiple) {
this.clearSelected();
}

this._selectionModel.select(this._items, item, this._ngSelect.multiple);

if (this._ngSelect.hideSelected) {
this._filteredItems = this._filteredItems.filter(x => x !== item);
if (isDefined(item.parent)) {
const children = this._filteredItems.filter(x => x.parent === item.parent);
if (children.length === 0) {
this._filteredItems = this._filteredItems.filter(x => x !== item.parent);
}
} else if (item.hasChildren) {
this._filteredItems = this.filteredItems.filter(x => x.parent !== item);
}
this._selectionModel.select(this._items, item, multiple);
if (this._ngSelect.hideSelected && multiple) {
this._hideSelectedItems(item);
}
}

unselect(item: NgOption) {
if (!item.selected) {
return;
}
this._selectionModel.unselect(this._items, item, this._ngSelect.multiple);

if (this._ngSelect.hideSelected && isDefined(item.index)) {
this._filteredItems.splice(item.index, 0, item);
if (isDefined(item.parent)) {
const isParentAddedBack = isDefined(this._filteredItems.find(x => x === item.parent));
if (!isParentAddedBack) {
const parent = this._items.find(x => x === item.parent);
this._filteredItems.splice(parent.index, 0, parent);
}
} else if (item.hasChildren) {
const children = this._items.filter(x => x.parent === item);
for (const child of children) {
child.selected = false;
this._filteredItems.splice(child.index, 0, child);
}
}
this._filteredItems = [...this._filteredItems.sort((a, b) => (a.index - b.index))];
if (this._ngSelect.hideSelected && isDefined(item.index) && this._ngSelect.multiple) {
this._showSelectedItems(item);
}
}

Expand Down Expand Up @@ -270,6 +250,36 @@ export class ItemsList {
}
}

private _showSelectedItems(current: NgOption) {
this._filteredItems.splice(current.index, 0, current);
if (isDefined(current.parent)) {
const parent = current.parent;
const alreadyAdded = this._filteredItems.find(x => x === parent);
if (!alreadyAdded) {
this._filteredItems.splice(parent.index, 0, parent);
}
} else if (current.hasChildren) {
const children = this._items.filter(x => x.parent === current);
for (const child of children) {
child.selected = false;
this._filteredItems.splice(child.index, 0, child);
}
}
this._filteredItems = [...this._filteredItems.sort((a, b) => (a.index - b.index))];
}

private _hideSelectedItems(current: NgOption) {
this._filteredItems = this._filteredItems.filter(x => x !== current);
if (isDefined(current.parent)) {
const children = this._filteredItems.filter(x => x.parent === current.parent);
if (children.length === 0) {
this._filteredItems = this._filteredItems.filter(x => x !== current.parent);
}
} else if (current.hasChildren) {
this._filteredItems = this.filteredItems.filter(x => x.parent !== current);
}
}

private _defaultSearchFn(search: string, opt: NgOption) {
const label = searchHelper.stripSpecialChars(opt.label).toLocaleLowerCase();
return label.indexOf(search) > -1
Expand Down
3 changes: 2 additions & 1 deletion src/ng-select/selection-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ export class SelectionModel {
item.selected = false;
if (multiple) {
if (isDefined(item.parent) && item.parent.selected) {
this._selected = items.filter(x => x.parent === item.parent && x !== item);
this._selected = this._selected.filter(x => x !== item.parent);
this._selected.push(...items.filter(x => x.parent === item.parent && x !== item));
item.parent.selected = false;
} else if (item.hasChildren) {
const children = items.filter(x => x.parent === item);
Expand Down

0 comments on commit 7c6fe82

Please sign in to comment.