Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to clear the typeahead input after a result is selected?

I'm using the ng-bootstrap typeahead component to search a customer database. When the user selects a customer from the typeahead results list, I navigate to a customer details page. I've got this working, but I want to clear the input field after navigation has taken place. I've tried setting the model to null or an empty string in the selectItem event logic, but this isn't working:

customer-search-typeahead.component.html

<template #resultTemplate let-r="result" let-t="term">
  <div>
    <div>
      {{r.resource.name[0].given}} {{r.resource.name[0].family}}
    </div>
    <div>
      {{r.resource.birthDate | date: 'dd/MM/yyyy'}}
    </div>
  </div>
</template>

<input type="text" class="form-control" [resultTemplate]="resultTemplate" (selectItem)="onSelect($event)"
       [(ngModel)]="model" placeholder="Start typing a customer name..." [ngbTypeahead]="search"/>

customer-search-typeahead.component.ts

@Component({
  selector: 'customer-search-typeahead',
  template: require('./customer-search-typeahead.component.html'),
  styles: [`.form-control { width: 300px; }`]
})
export class CustomerSearchTypeaheadComponent {

  model: any;
  searching: boolean;

  constructor(private customerService: CustomerService, private router: Router) {}

  onSelect($event) {
    this.router.navigate(['/customers', $event.item.resource.id]);
    this.model = null;
  };

  search = (text$: Observable<string>) =>
   //omitted for brevity
}

The typeahead input looks like this after a selection has been made:

enter image description here


Solution

customer-search-typeahead.component.html

<input type="text" class="form-control" #input [ngbTypeahead]="search" (selectItem)="onSelect($event); input.value='' ">

customer-search-typeahead.component.ts

onSelect($event, input) {
    $event.preventDefault();
    this.router.navigate(['/customers', $event.item.resource.id]);
  };
like image 435
Blake Mumford Avatar asked Sep 30 '16 04:09

Blake Mumford


2 Answers

The issue you witnessing arises from the fact that the NgModel directive is updating model binding asynchronously and the actual model is updated after the onSelect method gets executed. So your model update gets overridden by the NgModel functionality.

Fortunately we (ng-bootstrap authors) got all the flex points in place to cover your use-case :-) There are a couple of things that you could do.

Firstly the $event object passed to the onSelect method has the preventDefault() method and you can call it to veto item selection (and as a result writing back to the model and input field update).

$event.preventDefault() will make sure that the model is not updated and the input field is not updated with the selected item. But text entered by a user will still be part of the input so if you want to clear up this as well you can directly update the input's value property.

Here is code demonstrating all those techniques together:

onSelect($event, input) {
    $event.preventDefault();
    this.selected.push($event.item);
    input.value = '';
  }

where input argument is a reference to the input DOM element:

<input type="text" class="form-control" #input 
   [ngbTypeahead]="search" (selectItem)="onSelect($event, input)">

Finally here is a plunker showing all this in practice: http://plnkr.co/edit/kD5AmZyYEhJO0QQISgbM?p=preview

like image 185
pkozlowski.opensource Avatar answered Nov 14 '22 08:11

pkozlowski.opensource


The above one is template ref value solution.

This is for ngModel solution.

Html code:

<input type="text" class="form-control" [resultTemplate]="resultTemplate" (selectItem)="onSelect($event)"
       [(ngModel)]="model" placeholder="Start typing a customer name..." [ngbTypeahead]="search"/>

Component code:

onSelect($event) {
    $event.preventDefault();
    this.model = null;
    this.router.navigate(['/customers', $event.item.resource.id]);
};

$event.preventDefault();

for ngModel value change empty

like image 31
Jai Kumaresh Avatar answered Nov 14 '22 08:11

Jai Kumaresh