ng2-select
ng2-select copied to clipboard
Multiple Instances on the Same Page stay open
There is some strange functionality when there are multiple instances of the ng2-select on the same page. For instance, if you click into one and then click into a second one, the first one should collapse/hide I believe. Clicking on neither collapses/hides both. Is that right?
Although it is ugly and without CSS, here is a plunkr as an example: https://plnkr.co/edit/4eEYw4Urg80EDjCcRcgG?p=preview
- 1 . The problem is that the off-click event is not triggered when clicking into another box.
I have implemented the solution suggested on stackoverflow and removed the [offClick] directives. This solution works fine for me.
@Component({ host: { '(document:click)': 'onClick($event)', }, }) class SomeComponent() { constructor(private _eref: ElementRef) { }
onClick(event) { if (!this._eref.nativeElement.contains(event.target)) // or some similar check doSomething(); } }
What do you do exactly in the doSomething(); to close the dropdowns that are not the one you clicked on?
I just implemented the following solution, by changing the file: ng2-select/select/select.js:
SelectComponent.prototype.ngOnInit = function () {
//custom code to fix the issue of multiple ng2-selects being opened at the same time\\
var _select = this;
//create a listener for the cucstom clicked event we created
this.element.nativeElement.addEventListener("ng2-select-clicked", function (event) {
//if the id that was clicked on is different than this one
if (event.detail.id != _select.element.nativeElement.id) {
//close the options
_select.inputMode = false;
_select.optionsOpened = false;
};
});
//end custom code\\
this.behavior = (this.firstItemHasChildren) ?
new ChildrenBehavior(this) : new GenericBehavior(this);
};
SelectComponent.prototype.matchClick = function (e) {
//custom code to fire events to be caught and solve the issue of multiple selects being opened at the same time NOTE: this is fired only when the main input is clicked on\\
//select all ng-selects
let selectElements = document.querySelectorAll("ng-select");
//create a custom click event and attach this ng-select's id to it
let event = new CustomEvent("ng2-select-clicked", { detail: {id: this.element.nativeElement.id} });
for (let SelectElement of selectElements) {
//dispatch the custom event to every ng-select on the page
SelectElement.dispatchEvent(event)
};
//end custom code\\
if (this._disabled === true) {
return;
}
this.inputMode = !this.inputMode;
if (this.inputMode === true && ((this.multiple === true && e) || this.multiple === false)) {
this.focusToInput();
this.open();
}
};
just make sure that each
I would still appreciate an official fix though as this is definitely not the intended behavior
official fix plz
I also did a little workaround of my own, I created a (dropdownOpen) event which I listen to at my ng-select element component and call a function which will close all the other SelectComponent opened apart from the currently opened SelectComponent. I modified one function inside select.ts file like below to emit event :-
private open():void {
this.options = this.itemObjects
.filter((option:SelectItem) => (this.multiple === false ||
this.multiple === true && !this.active.find((o:SelectItem) => option.text === o.text)));
if (this.options.length > 0) {
this.behavior.first();
}
this.optionsOpened = true;
this.dropOpened.emit(true);
}
In html I added event listener for (dropdownOpened)
<ng-select #elem (dropdownOpened)="closeOtherElems(elem)"
[multiple]="true"
[items]="items"
[disabled]="disabled"
[isInputAllowed]="true"
(data)="refreshValue($event)"
(selected)="selected($event)"
(removed)="removed($event)"
placeholder="No city selected"></ng-select>
This is my calling function on event trigger inside the component having ng-select
@ViewChildren(SelectComponent) selectElem :QueryList<SelectComponent>;
public closeOtherElems(element){
let a = this.selectElem.filter(function(el){
return (el != element)
});
a.forEach(function(e:SelectComponent){
e.closeDropdown();
})
}
i fixed it, tk gauzpan 😄 i had to create event emitter for dropOpened and subscribe it in each select, method dropdownOpened is not output in select.ts
@gauzpan @KeitaElric It's not possible if you work with a package manager as NPM, never edit a packaged file. Any other workaround ?
Exactly, working in NPM Modules is wrong. Do you have a official solution?
@LFeh @khylias @KeitaElric @gauzpan
@ViewChildren(SelectComponent) selectElem :QueryList<SelectComponent>; public closeOtherElems(element){ let a = this.selectElem.filter(function(el){ return (el != element) }); a.forEach(function(e:SelectComponent){ e.clickedOutside(); }) }
@hucheng91 Can you expand on your answer? I tried adding this but typescript is complaining. [ts] Generic type 'QueryList<T>' requires 1 type argument(s).
Download source code and put in your project then update select.html to add output event selectBoxClickEvent as
<div tabindex="0" *ngIf="multiple === false" (keyup)="mainClick($event)" [offClick]="clickedOutside" (selectBoxClickEvent)="matchClick($event)" ...
<div tabindex="0" *ngIf="multiple === true" (keyup)="mainClick($event)" (focus)="focusToInput('')" [offClick]="clickedOutside" (selectBoxClickEvent)="matchClick($event)"...
then change off-click.ts as
export class OffClickDirective implements OnInit, OnDestroy {
@Input('offClick') public offClickHandler: any;
@Output('selectBoxClickEvent') selectBoxClickEvent= new EventEmitter();
@HostListener('click', ['$event']) public onClick($event: MouseEvent): void {
// $event.stopPropagation();
setTimeout(() => {
this.selectBoxClickEvent.emit($event);
});
}
public ngOnInit(): any {
setTimeout(() => { if (typeof document !== 'undefined') { document.addEventListener('click', this.offClickHandler); } }, 0);
}
public ngOnDestroy(): any {
if (typeof document !== 'undefined') { document.removeEventListener('click', this.offClickHandler); }
}
}
is there a official fix for this? I have 1.2.0 version, is there a newer one with this fix?
@iosifpetre18 No, it's waiting on PR... #712
There is a fork located here for this plugin - https://github.com/psilospore/ng-next-select/issues/12#issuecomment-323241650
They said if some one can fix the merge conflict, they will merge the PR.
Duplicate #913 Hi. It was fixed in that fork: https://github.com/optimistex/ng2-select-ex
I am using 1.2.0 version.can anyone tell me if it is fixed?
@trinanjan12 No, still waiting on few fork and PR.
@valorkin it's time to close this one-year-old issue! 😱 PR #712 is waiting your approval... 😑
This feature is very much needed. It would be really awesome if you could get the pull request merged and do a release, I am sure many people would feel very grateful for it.
In addition, thanks a lot @gauzpan and @hucheng91 for your work and for the code you pasted above, it was really helpful for me to discover the clicked outside method to close a bunch of selector when one gets the selected event.
@jesusreal Hi. It was fixed in that fork: https://github.com/optimistex/ng2-select-ex Try the demo: https://optimistex.github.io/ngx-select-ex/