ng2-completer selected event not triggered on mouse click

1.5k Views Asked by At

As the question suggests, I have a problem applying the selected event for ng2-completer.

It also seems to be an open issue with ng2-completer because they haven't released any fix for this issue on Github. However there is no work-around solution yet.

Here's the code that I use.

HTML template:

<ng2-completer 
   [(ngModel)]="searchStr"
   [datasource]="items"
   [minSearchLength]="0"
   [openOnFocus]="true"
   [placeholder]="'Please enter'"
   [textNoResults]="false"
   [maxChars]="6"
   (keyup)="onKeyDown($event)"
   (selected)="onItemSelect($event)"
   (blur)="onTouched()">
</ng2-completer>

Component:

onItemSelect(selected: CompleterItem): void {
   console.log('selected item');
   console.log(selected);
}

It doesn't print anything when I click or double click on any item. I've tried typing Enter as well but it also doesn't work. Please help to suggest a work around solution for this if you have. Thank you in advance.

2

There are 2 best solutions below

1
On BEST ANSWER

Since ng2-completer implemented ControlValueAccessor internally, you can use ngModelChange event emitter to get emitted value.

Try this:

<ng2-completer 
    [(ngModel)]="searchStr"
    [datasource]="items"
    [minSearchLength]="0"
    [openOnFocus]="true"
    [placeholder]="'Please enter'"
    [textNoResults]="false"
    [maxChars]="6"
    (ngModelChange)="onItemSelect($event)" >
</ng2-completer>
0
On

UPDATE:

Even though Chellappan's answer works, but it will not suitable if you want to pass the selected event into other component. You can see that due to (ngModelChange), onItemSelect will be trigger whenever the searchStr change, and with ng2-completer, you can change the [(ngModel)] by hovering on the item from the dropdown list. This is quite annoying because there is no property to turn it off.

The other solution is to override click event on each .completer-row.

You can have the html file looks something like this

<div class="applicant-search-field" #autoComplete>
    <ng2-completer 
        ngDefaultControl
        [(ngModel)]="searchValue"
        [datasource]="dataSource"
        [minSearchLength]="minSearchLength"
        [maxChars]="33"
        [placeholder]="placeHolder"
        (keyup)="onKeyUp($event)">
    </ng2-completer>
 </div>

and listen to key event to override the click event listener (because the drop down will be shown only if you're typing something searchable).

@ViewChild('autoComplete', { static: false }) child: ElementRef;
onKeyUp(event: any): void {
    this.overrideNg2CompleterOnSelected();

    this.hasValue = this.searchValue.length > 0;
    this.valueBeforeHoverOnItem = this.searchValue;
    if (event.key === 'Enter') {
        this.autocompleteEventNotifier.emitData(this.searchValue);
    }
}

private overrideNg2CompleterOnSelected(): void {
    // we have to do this manually because (selected) event of ng2-completer is broken.
    const dropDownRows = this.child.nativeElement.querySelectorAll('.completer-row') as HTMLElement[];
    if (dropDownRows !== null) {
        for (const row of dropDownRows) {
            row.addEventListener('click', this.onItemSelect.bind(this));
        }
    }
}

This is just a workaround, I still don't want to apply this if the dropdown contains a lot of item, we might run into performance issue.