3

I'm using bootstrap-autocomplete, but the bound model is not updated when selecting a value.

I looked into the bootstrap-autocomplete source code, and it is using JQuery.val() to assign a selected value, and it looks like if JQuery.val() is used, the model is not updated.

-- template
<input id="test" class="form-control" type="text" autocomplete="off" [(ngModel)]="myValue">
Angular Model: {{myValue}}
<br />
Jquery Val: {{getJqueryValue()}}


-- component
import { Component, AfterViewInit } from '@angular/core';
import 'bootstrap-autocomplete'
declare const $: any;
@Component({
  selector: 'app-app-list',
  templateUrl: './app-list.component.html',
  styleUrls: ['./app-list.component.css']
})
export class AppListComponent implements AfterViewInit {
  public myValue: string;
  ngAfterViewInit(): void {
    $('#test').autoComplete({
      resolver: 'custom',
      events: {
        search: function (qry, callback) {
          callback(["google", "yahoo", "amazon"])
        }
      }
    });
  }
  getJqueryValue() {
    return $('#test').val();
  }
}

enter image description here

How can I make Angular to understand that the value is changed?

FYI, I cannot use Angular material or other angular compatible autocomplete.

https://stackblitz.com/edit/angular-playground-6dpemy?file=app%2Fapp.component.ts

17
  • you could use the (blur)="setAngularModel(getJqueryValue())" on your <input> tag. Also, if you are using angular, you shouldn't be using jquery Commented Sep 15, 2020 at 21:01
  • @rhavelka, I know it is not good to use Jquery in Angular in general , but there are some cases you cannot avoid it, and I have my reasons why I'm using Jquery plugins in my project. I just tried your solution, but it does not work, because when blur is called, the value is yet assigned. So, when I type "yah" and click "yahoo", $("#test").val() returns "yah" not "yahoo". Commented Sep 15, 2020 at 21:21
  • Not sure if it helps. add private changeRef: ChangeDetectorRef to your constructor. Then try to use changeRef.detectChanges() after a selection. Commented Sep 15, 2020 at 21:36
  • 2
    How about if you change to the event autocomplete.select and change the handler to $('#test').on('autocomplete.select', (ev, item) => this.myValue = item); would that work? Here is a fiddle without Angular though. Commented Sep 15, 2020 at 22:54
  • 1
    I have added an answer with the solution I mentioned. Nonetheless, either @naveen answers or mine will solve the issue. Good luck :) Commented Sep 16, 2020 at 15:19

2 Answers 2

3

Using your StackBlitz as a reference I was able to build this solution:

Template

<!--   | Add a template reference so you can grab this element from your component. -->
<!--   v Name it what ever you like. -->
<input #test id="test" class="form-control" type="text" autocomplete="off" [(ngModel)]="myValue">

Component

export class YourComponent implements AfterViewInit {
    public myValue: string;
    @ViewChild('test') test: ElementRef; // <- The name in quotes must match on the template

     ngAfterViewInit(): void {
         $('#test').autoComplete({
             resolver: 'custom',
             events: {
                 search: function (qry, callback) {
                     callback(["google", "yahoo", "amazon"])
                 }
             }
          });
          $('#test').on('autocomplete.select', (ev, item) => {              
              this.test.nativeElement.dispatchEvent(
                  new CustomEvent('input', { bubbles: true })
              );
          });
     }
}

Demo https://stackblitz.com/edit/angular-playground-r3s5b3?file=app/app.component.ts

Sign up to request clarification or add additional context in comments.

Comments

1

This will do

$('#test').on('autocomplete.select', (ev, item) => {
  this.myValue = item;
});

Link: https://stackblitz.com/edit/angular-jq-autocomplete-z6bc1r

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.