ng2-select icon indicating copy to clipboard operation
ng2-select copied to clipboard

Multiple Instances on the Same Page stay open

Open blubberbo opened this issue 8 years ago • 22 comments
trafficstars

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

blubberbo avatar Feb 24 '17 06:02 blubberbo

  • 1 . The problem is that the off-click event is not triggered when clicking into another box.

jlstrat avatar Mar 02 '17 15:03 jlstrat

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(); } }

jlstrat avatar Mar 02 '17 15:03 jlstrat

What do you do exactly in the doSomething(); to close the dropdowns that are not the one you clicked on?

blubberbo avatar Mar 17 '17 20:03 blubberbo

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 has the id attribute assigned to something unique

blubberbo avatar Mar 17 '17 23:03 blubberbo

I would still appreciate an official fix though as this is definitely not the intended behavior

blubberbo avatar Mar 17 '17 23:03 blubberbo

official fix plz

hvqthong avatar Apr 01 '17 03:04 hvqthong

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();
    })
  }

gauzpan avatar Apr 04 '17 08:04 gauzpan

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

hvqthong avatar Apr 04 '17 09:04 hvqthong

@gauzpan @KeitaElric It's not possible if you work with a package manager as NPM, never edit a packaged file. Any other workaround ?

khylias avatar May 17 '17 12:05 khylias

Exactly, working in NPM Modules is wrong. Do you have a official solution?

felipefialho avatar May 17 '17 14:05 felipefialho

@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 avatar Aug 06 '17 07:08 hucheng91

@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).

carlhussey avatar Aug 08 '17 20:08 carlhussey

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); }
  }
}

shah-dhaval avatar Sep 13 '17 10:09 shah-dhaval

is there a official fix for this? I have 1.2.0 version, is there a newer one with this fix?

iosifpetre18 avatar Sep 14 '17 10:09 iosifpetre18

@iosifpetre18 No, it's waiting on PR... #712

khylias avatar Sep 14 '17 14:09 khylias

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.

carlhussey avatar Sep 20 '17 13:09 carlhussey

Duplicate #913 Hi. It was fixed in that fork: https://github.com/optimistex/ng2-select-ex

optimistex avatar Feb 01 '18 13:02 optimistex

I am using 1.2.0 version.can anyone tell me if it is fixed?

trinanjan12 avatar Apr 02 '18 12:04 trinanjan12

@trinanjan12 No, still waiting on few fork and PR.

khylias avatar Apr 04 '18 09:04 khylias

@valorkin it's time to close this one-year-old issue! 😱 PR #712 is waiting your approval... 😑

maximelafarie avatar Apr 04 '18 09:04 maximelafarie

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 avatar Apr 12 '18 14:04 jesusreal

@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/

optimistex avatar Apr 12 '18 15:04 optimistex