简体   繁体   中英

show database fetched values if present else show default text in ng-select angular

I have 3 dropdowns for country,state,city in angular. I have used ng-select module for those dowpdowns from reference here . On country change states populates, and on state change city populate.

template HTML

<ng-select formControlName="country" (change)="onChangeCountry($event)" >
    <ng-option value="dbCountryId ? dbCountryId : ''">{{dbCountryName ? dbCountryName : 'Select Country' }}</ng-option>
    <ng-option *ngFor="let country of countryInfo" [value]="country.id">{{country.name}}</ng-option>
 </ng-select>
 <ng-select formControlName="state" (change)="onChangeState($event)">
    <ng-option value="dbStateId ? dbStateId : ''">{{dbStateName ? dbStateName : 'Select State' }}</ng-option>
    <ng-option *ngFor="let state of stateInfo" [value]="state.id">{{state.name}}</ng-option>
 </ng-select> 
 <ng-select formControlName="city" >
    <ng-option value="dbCityId ? dbCityId : ''">{{dbCityName ? dbCityName : 'Select City' }}</ng-option>
    <ng-option *ngFor="let city of cityInfo" [value]="city.id">{{city.name}}</ng-option>
 </ng-select>

ts code

 this.userService.getUserDetails(userDetails.id).subscribe((results) => {
  if (results['status'] === true) {

   this.dbCountryName = results.data.country ? results.data.country : null;
              this.dbCountryId = results.data.country_id
                ? results.data.country_id
                : null;
            this.dbStateName = results.data.state ? results.data.state : null;
            this.dbStateId = results.data.state_id
              ? results.data.state_id
              : null;
            this.dbCityName = results.data.city ? results.data.city : null;
            this.dbCityId = results.data.city_id ? results.data.city_id : null;


            this.form.patchValue({
              country:
                results.data.country_id === null ? '' : results.data.country_id,
              state:
                results.data.state_id === null ? '' : results.data.state_id,
              city: results.data.city_id === null ? '' : results.data.city_id,

  });
}
 });

I am using same form for add and edit data. I am storing id of country,state, city. In api response I get stored id, name of fields. I have patched id with respective form control.

I have 2 problems.

  1. 'Select country/state/city' like default text, it shows in dropdown not in inputbox在此处输入图像描述
  2. I am not able to show fetched data properly. its showing like below在此处输入图像描述

How I can solve these problems with ng-select in angular? please help and guide. Thanks.

Adding placeholder should work for your first problem:

<ng-select formControlName="country" (change)="onChangeCountry($event)" placeholder="Select Country">
    `<ng-option *ngFor="let country of countryInfo" [value]="country.id">{{country.name}}</ng-option>
`</ng-select>

you should try items instate of option as bellow

<ng-container ngFor="let country in countries"> \\ you can apply forloop like this and it will show default value
    <ng-select
      [items]="{{country.name}}"
      formControlName="country"
      bindLabel="label"                 
      [multiple]="true"
      placeholder="Select Country"
      [(ngModel)]="selectedAttributes">
    </ng-select>
</ng-container>

add following modules

import { NgSelectModule } from '@ng-select/ng-select';
import { FormsModule } from '@angular/forms';


@NgModule({
  imports: [
    FormsModule,
    NgSelectModule,
 

for more information you can checkout this link ng-select docs

From what I understand you are using Reactive Forms to manage these controls. If this is not true, please let me know.

The HTML template I am suggesting is similar to yours, but simpler. I am recommending to not add a separate <ng-option> for the selected value / default message:

<ng-select formControlName="country" (change)="onChangeCountry($event)" style="width: 200px;">
  <ng-option *ngFor="let country of countries" [value]="country.id">{{country.name}}</ng-option>
</ng-select>

<ng-select formControlName="state" (change)="onChangeState($event)" style="width: 200px;">
  <ng-option *ngFor="let state of statesToShow" [value]="state.id">{{state.name}}</ng-option>
</ng-select>

<ng-select formControlName="city" (change)="onChangeCity($event)" style="width: 200px;">
  <ng-option *ngFor="let city of citiesToShow" [value]="city.id">{{city.name}}</ng-option>
</ng-select>

I have also included a TS file with working example on how to set

  1. The placeholder messages when appropriate.
  2. The already selected value. Please see prefefinedValues() function.

Please note that in order for 2. to work as expected, the ID of the element needs to be in the data source currently selected for the control (in my example statesToShow or citiesToShow ). If not, it will be displayed as text (probably what you are experiencing).

import { Component } from '@angular/core';
import { FormBuilder, FormGroup, FormsModule } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'test2';

  guestForm: FormGroup;

  selectedCar: number = 0;

  // this is the data source for the STATES drop-down (initially empty)
  // => will be populated when a COUNTRY is selected
  public statesToShow: Array<any> = [];
  // this is the data source for the CITIES drop-down (initially empty)
  // => will be populated when a STATE is selected
  public citiesToShow: Array<any> = [];

  // TEST data start
  public countries = [
      { id: 1, name: 'Romania' },
      { id: 2, name: 'USA' },
      { id: 3, name: 'France' },
      { id: 4, name: 'Spain' },
  ];

  public states = [
    [],
    [
      {id: 1, name: "Cluj"},
      {id: 2, name: "Valcea"},
      {id: 3, name: "Sibiu"},
      {id: 4, name: "Mures"},
    ],
    [
      {id: 5, name: "New York"},
      {id: 6, name: "Oregon"},
      {id: 7, name: "Arizona"},
      {id: 8, name: "Texas"},
    ],
    [
      {id: 9, name: "Normandie"},
      {id: 10, name: "Ile-de-France"},
      {id: 11, name: "Grand Est"},
      {id: 12, name: "Occitanie"},
    ],
    [
      {id: 13, name: "Alicante"},
      {id: 14, name: "Valencia"},
      {id: 15, name: "Sevilla"},
      {id: 16, name: "Malaga"},
    ]
  ];


  public cities = [
    [],
    [
      {id: 1, name: "Cluj-Napoca"},
      {id: 2, name: "Turda"},
      {id: 3, name: "Huedin"},
    ],
    [
      {id: 4, name: "Ramnicul Valcea"},
      {id: 5, name: "Horezu"},
      {id: 6, name: "Olanesti"},
    ],
    [],
    [],
    [
      {id: 10, name: "New York city 1"},
      {id: 11, name: "New York city 2"},
      {id: 12, name: "New York city 3"},
    ],
    [
      {id: 13, name: "Oregon city 1"},
      {id: 14, name: "Oregon city 2"},
      {id: 15, name: "Oregon city 3"},
    ]
  ]

  // TEST data end

  private dbCountryId: number | null = null;
  private dbStateId: number | null = null;
  private dbCityId: number | null = null;
  
  constructor(private _fb: FormBuilder) {
    // add default placeholder messages for all the controls
    this.guestForm = this._fb.group({
      country: ['Please select country', null],
      state: ['Please select state', null],
      city: ['Please select city', null]
    });
  }

  ngOnInit() {
    
  }

  onChangeCountry(value: number) {
    // set the data source for the STATES drop-down
    this.statesToShow = this.states[value];
    // display placeholders for STATES and CITIES until the user
    // selects the values
    this.guestForm.patchValue({ 
      state: "Please select state !",
      city: "Please select city !"
    });
  }

  onChangeState(value: number) {
    // set the data source for the CITIES drop-down
    this.citiesToShow = this.cities[value] ? this.cities[value] : [];
    // display the placeholder until the user selects a new city
    this.guestForm.patchValue({ city: "Please select city !" });
  }

  onChangeCity(value: number) {
    console.log(value);
  }

  // example on how to correctly set preselected values
  // in the controls
  prefefinedValues() {
    // preselected values (MUST BE A VALID COMBINATION)
    this.dbCountryId = 2;
    this.dbStateId = 6;
    this.dbCityId = 14;

    // set the sources for STATES and CITIES drop-downs
    this.statesToShow = this.states[this.dbCountryId];
    this.citiesToShow = this.cities[this.dbStateId];

    // set the preselected IDs as current value in all drop-downs
    this.guestForm.patchValue({ 
      country: this.dbCountryId,
      state: this.dbStateId,
      city: this.dbCityId
    });
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM