9

From Api, I get the countryName and code as like below

eg:-

  countryName        code
  -----------------------
  India              IND
  United States      USA
  Aruba              ABW

I want to use the ngSelect dropdown and want to display the value like countryName (code) in dropdown.

eg: India (IND)

Question:- I want concatenate the countryName and code. And want to filter the dropdown value based on both countryName and code. Below is the code which I tried. But its not working properly

component.html

  <ng-select [items]="countries" bindLabel="description" bindValue="code"
           clearAllText="Clear" formControlName="countryCode"
          [searchFn]="customSearchFn">
      <ng-template ng-label-tmp let-item="item">
          <span >{{ item.countryName + ' (' + item.code + ')' }}</span>
      </ng-template>
      <ng-template ng-option-tmp let-item="item" let-search="searchTerm" let-index="index">
           <span >{{ item.countryName + ' (' + item.code + ')' }}</span>
      </ng-template>
   </ng-select>

component.ts

getCountry() {
this.lookupService.getCountry().subscribe(
  data => {
    this.countries = data;
  });
 }

customSearchFn

customSearchFn(term: string, item: Lookup) {
  term = term.toLocaleLowerCase();
  return item.code.toLocaleLowerCase().indexOf(term) > -1 || item.countryName.toLocaleLowerCase() === term;
   }

Can anybody give me a solution for Searching?

S.Anitha
  • 171
  • 1
  • 1
  • 7

2 Answers2

15

I took your code and put it into a Stackblitz. It actually almost worked! I just made a minor change in the search function:

customSearchFn(term: string, item: any) {
    term = term.toLocaleLowerCase();
    return item.code.toLocaleLowerCase().indexOf(term) > -1 || 
           item.countryName.toLocaleLowerCase().indexOf(term) > -1;
}

(both countryName and code use indexOf instead of item.countryName.toLocaleLowerCase() === term)

The only other thing I removed was formControlName="countryCode", that gave me an error "No provider for NgControl". The error makes sense, I have not implemented an NgControl.

Now, ABW gives you Aruba and Aru gives you Aruba too. (That's what you want, right?)

dannybucks
  • 2,217
  • 2
  • 18
  • 24
  • Thank you Jeremy. Actually, the value fetches only when I type the countryName completely. I need to get value simultaneously when I start to type. Eg: When I type AR (Aruba) it should fetch all the values related to AR but it is fetching when I complete the word . Can u help me to solve this.? – S.Anitha May 16 '19 at 07:30
  • Ah, now I see. I corrected the customSearchFunction and updated my answer, now it works in the Stackblitz – dannybucks May 16 '19 at 11:28
  • Thank you so much, Jeremy. Its working good. can you explain to me the concept? – S.Anitha May 17 '19 at 06:53
  • Well, you in [items] you give an array of any type of object. Then you tell ng-select what to display as label and what is the code with bindLabel and bindValue. customSearchFunction called for each object in your array for each search term. You get the search term and each object and you have to return if that item does match the search term or not. – dannybucks May 17 '19 at 07:03
  • I need to use the " customSearchFn() " concept in multiple places. Can I control all the dropdown by writing a single function ( "customSearchFn() ") in common ts file? And if yes, how can I call and control the multiple drop downs by common customSearchFn()? – S.Anitha May 17 '19 at 07:19
  • I don't know. I think it's best to create a new stackoverflow question for that (but search first if someone else asked that already) – dannybucks May 17 '19 at 09:39
-1

I solved this problem by declaring this array in my ts:

countries = [
    { countryName: "India", code: "IND" },
    { countryName: "United States", code: "USA" },
    { countryName: "Aruba", code: "ABW" }];

I added the ng-select to my html like this, along with the class:

<ng-select
    bindLabel="description"
    class="searchable_select" 
    (change)="changed($event)">
    <ng-option *ngFor="let item of countries" [value]="item">
        {{ item.countryName + ' (' + item.code + ')' }}
    </ng-option>
</ng-select>

The changed function is just to display the value of the selected item.

And the most important thing, the SCSS class:

.searchable_select {
  .ng-input {
    display: flex;
    align-items: center;
  }
}

You can also add it as CSS, of course:

.searchable_select .ng-input {
  display: flex;
  align-items: center;
}
Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77