valor-software / ng2-select

Angular based replacement for select boxes
http://valor-software.github.io/ng2-select/
MIT License
675 stars 585 forks source link

Feature Request: AJAX - Loading Remote Data #97

Open scaryroy opened 8 years ago

scaryroy commented 8 years ago

Select2 has the option to load data through ajax calls when a phrase is searched.

I think this is important as sometimes the list could be huge and you don't want to load all the data on init.

rkralston commented 8 years ago

You should probably do this through a service rather than a direct call from the component. This will give you better control.

bmsdave commented 8 years ago

Hello. Is there an example of such an implementation?

bmsdave commented 8 years ago

please see https://github.com/valor-software/ng2-select/pull/238

I was able to do so

selectSingle.html:

<div style="width: 300px; margin-bottom: 20px;">
  <h3>Select a single city</h3>
  <ng-select [allowClear]="true"
              [items]="items | async"
              (data)="refreshValue($event)"
              (selected)="selected($event)"
              (removed)="removed($event)"
              (typed)="typed($event)"
              placeholder="No city selected">
  </ng-select>
  <pre>{{value.text}}</pre>
</div>

selectSingle.component.ts:

import {Component} from '@angular/core';
import {CORE_DIRECTIVES, FORM_DIRECTIVES, NgClass, AsyncPipe} from '@angular/common';
import {SELECT_DIRECTIVES} from "../../ng2-select/components/select";
import {Observable} from "rxjs/Rx";
import {SelectSingleService} from "./selectSingle.service";

@Component({
  selector: 'select-single',
  pipes: [AsyncPipe],
  template: require('./selectSingle.html'),
  directives: [SELECT_DIRECTIVES, NgClass, CORE_DIRECTIVES, FORM_DIRECTIVES ],
  providers: [SelectSingleService]
})
export class SelectSingleComponent {

  constructor(private _DataService: SelectSingleService) {
  }

  ngOnInit() {
    this.items = this._DataService.getFiltered('');
  }

  public items:Observable<Array<any>>;

  private value:any = {};

  public selected(value:any):void {
    console.log('Selected value is: ', value);
  }

  public removed(value:any):void {
    console.log('Removed value is: ', value);
  }

  public typed(value:any):void {
    this.items = this._DataService.getFiltered(value);
  }

  public refreshValue(value:any):void {
    this.value = value;
  }
}

selectSingle.service.ts:

/**
 * Created by bmsdave on 08.06.16.
 */
/**
 * Created by bmsdave on 07.06.16.
 */
import { Injectable }     from '@angular/core';
import { Http, Response } from '@angular/http';
import {Observable} from 'rxjs/Rx';
import 'rxjs/add/operator/catch'

@Injectable()
export class SelectSingleService {

  private urlData = '/assets/json/country.json';

  constructor(private http:Http) {
  }

  getData():Observable<Array<any>> {
    return this.http.get(this.urlData)
    .map(this.extractData)
    .catch(this.handleError);
  }

  getFiltered(filter: string):Observable<Array<any>> {
    return this.http.get(this.urlData)
    .map( (res) => {return this.extractFilteredData(res, filter)} )
    .catch(this.handleError);
  }

  private extractData(res: Response) {
    let body = res.json();
    return body || [];
  }

  private extractFilteredData(res: Response, filter: string) {
    let body = res.json().filter((item: any) => { return item.text.toLowerCase().indexOf(filter) != -1});
    return body || [];
  }

  private handleError (error: any) {
    // In a real world app, we might use a remote logging infrastructure
    // We'd also dig deeper into the error to get a better message
    let errMsg = (error.message) ? error.message :
      error.status ? `${error.status} - ${error.statusText}` : 'Server error';
    console.error(errMsg); // log to console instead
    return Observable.throw(errMsg);
  }

}

coutnry.json:

[
{"text": "South Africa", "id": 1},
{"text": "Palau", "id": 2},
{"text": "Greenland", "id": 3},
{"text": "Cote d'Ivoire", "id": 4}
]
superstarmcawesome commented 8 years ago

good evening,

welll i did kinda exact so, just that I pass an observable from the parent component and then add those elements to the items array. this is working fine.... but it looks like the dropdown is not refreshing... so I changed the select.js with #238 ... but still no luck.. getting...

"Error: Uncaught (in promise): TypeError: Cannot read property 'query' of null"

any ideas on this one?

https://plnkr.co/edit/Jgm22NB2f1fEPBNwd1VO

bmsdave commented 8 years ago

@bona1337 please give a full example . you do not have some class. For example "Countrys" aka counties.

  1. you dont use "import 'rxjs/add/operator/catch'" in service
  2. what is "query"?
  3. in component use "providers: [QueryCountryService]"
superstarmcawesome commented 8 years ago

@bmsdave added the missing class to plunkr.. --> 2. "If omitted, items are not available locally, and the query option should be provided to fetch data." I guess this could maybe the issue? --> 3. I'm not sure if the providers is still needed in this component.. cause the parent subcribed to it. added it anyway just to be sure!

superstarmcawesome commented 8 years ago

I've updated my plnker. but still no success... https://plnkr.co/edit/Jgm22NB2f1fEPBNwd1VO?p=info

also attached a screenshot of the error when changed select.js with #238 ... bildschirmfoto 2016-06-29 um 12 40 22 seems to be a jquery problem....

oliviadawd commented 8 years ago

I'm also getting the same error that bona1337 is getting. I followed exactly what bmsdave suggested. Any ideas what might be causing it? Any help would be awesome!

Gillardo commented 8 years ago

Any idea when this is gonna be sorted? I would say this is a pretty BIG feature that is missing.

superstarmcawesome commented 8 years ago

@valorkin is there a plan to fix this very important issue in the next release?

DanielKucal commented 8 years ago

@scaryroy @bona1337 @Gillardo here is a solution

JimJafar commented 7 years ago

This might help: https://github.com/valor-software/ng2-select/issues/635#issuecomment-281094377

optimistex commented 6 years ago

New life the component is there: https://github.com/optimistex/ng2-select-ex