Skip to content

Commit

Permalink
feat: disable virtual scroll by default (#299)
Browse files Browse the repository at this point in the history
  • Loading branch information
anjmao committed Feb 28, 2018
1 parent 5798ae7 commit ea6b636
Show file tree
Hide file tree
Showing 14 changed files with 282 additions and 166 deletions.
35 changes: 18 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,36 +119,37 @@ map: {
## API
| Input | Type | Default | Required | Description |
| ------------- | ------------- | ------------- | ------------- | ------------- |
| [items] | `Array<NgOption>` | `[]` | yes | Items array |
| bindLabel | `string` | `label` | no | Object property to use for label. Default `label` |
| [addTag] | `boolean | ((term: string) => any | Promise<any>)` | `false` | no | Allows to create custom options. |
| addTagText | `string` | `Add item` | no | Set custom text when using tagging |
| appendTo | `string` | null | no | Append drodown to body or any other element using css selector |
| bindValue | `string` | `-` | no | Object property to use for selected model. By default binds to whole object. |
| bindLabel | `string` | `label` | no | Object property to use for label. Default `label` |
| closeOnSelect | `boolean` | true | no | Whether to close the menu when a value is selected |
| [clearable] | `boolean` | `true` | no | Allow to clear selected value. Default `true`|
| clearAllText | `string` | `Clear all` | no | Set custom text for clear all icon title |
| dropdownPosition | `bottom`,`top`,`auto` | `bottom` | no | Set the dropdown position on open |
| [items] | `Array<NgOption>` | `[]` | yes | Items array |
| loading | `boolean` | `-` | no | You can set the loading state from the outside (e.g. async items loading) |
| loadingText | `string` | `Loading...` | no | Set custom text when for loading items |
| [markFirst] | `boolean` | `true` | no | Marks first item as focused when opening/filtering. Default `true`|
| [searchable] | `boolean` | `true` | no | Allow to search for value. Default `true`|
| multiple | `boolean` | `false` | no | Allows to select multiple items. |
| maxSelectedItems | `number` | none | no | When multiple = true, allows to set a limit number of selection. |
| [addTag] | `boolean \| ((term: string) => any \| Promise<any>)` | `false` | no | Allows to create custom options. |
| placeholder | `string` | `-` | no | Placeholder text. |
| multiple | `boolean` | `false` | no | Allows to select multiple items. |
| notFoundText | `string` | `No items found` | no | Set custom text when filter returns empty result |
| typeToSearchText | `string` | `Type to search` | no | Set custom text when using Typeahead |
| clearAllText | `string` | `Clear all` | no | Set custom text for clear all icon title |
| addTagText | `string` | `Add item` | no | Set custom text when using tagging |
| loadingText | `string` | `Loading...` | no | Set custom text when for loading items |
| placeholder | `string` | `-` | no | Placeholder text. |
| [searchable] | `boolean` | `true` | no | Allow to search for value. Default `true`|
| [typeahead] | `Subject` | `-` | no | Custom autocomplete or filter. |
| dropdownPosition | `bottom`,`top`,`auto` | `bottom` | no | Set the dropdown position on open |
| appendTo | `string` | null | no | Append drodown to body or any other element using css selector |
| loading | `boolean` | `-` | no | you can set the loading state from the outside (e.g. async items loading) |
| closeOnSelect | `boolean` | true | no | whether to close the menu when a value is selected |
| typeToSearchText | `string` | `Type to search` | no | Set custom text when using Typeahead |
| [virtualScroll] | `boolean` | false | no | Enable virtual scroll for better performance when rendering a lot of data |

| Output | Description |
| ------------- | ------------- |
| (focus) | Fired on select focus |
| (add) | Fired when item is selected |
| (blur) | Fired on select blur |
| (change) | Fired on selected value change |
| (open) | Fired on select dropdown open |
| (close) | Fired on select dropdown close |
| (clear) | Fired on clear icon click |
| (add) | Fired when item is selected |
| (focus) | Fired on select focus |
| (open) | Fired on select dropdown open |
| (remove) | Fired when item is removed |
| (scrollToEnd) | Fired when scrolled to the end of items. Can be used for loading more items in chunks. |

Expand Down
20 changes: 17 additions & 3 deletions demo/app/examples/custom-templates.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,21 @@ import { DataService } from '../shared/data.service';
---html,true
<ng-select [items]="cities2" [(ngModel)]="selectedCity2" bindLabel="name" bindValue="name">
<ng-template ng-option-tmp let-item="item" let-index="index" let-search="searchTerm">
<img height="15" width="15" [src]="item.avatar"/>
<b [innerHTML]="item.name" [ngOptionHighlight]="search"></b>
<div *ngIf="item.name === 'Kaunas'">{{item.name}}</div>
<div class="card" *ngIf="item.name !== 'Kaunas'">
<div class="card-body">
<h5 class="card-title" [innerHTML]="item.name" [ngOptionHighlight]="search"></h5>
<h6 class="card-subtitle mb-2 text-muted">Card subtitle</h6>
<p class="card-text">
<img height="15" width="15" [src]="item.avatar"/>
Some quick example text to build
</p>
<div *ngIf="item.name === 'Pavilnys'">
<a href="#" class="card-link">Card link</a>
<a href="#" class="card-link">Another link</a>
</div>
</div>
</div>
</ng-template>
</ng-select>
---
Expand Down Expand Up @@ -79,7 +92,8 @@ export class SelectWithTemplatesComponent {
cities = [
{id: 1, name: 'Vilnius', avatar: '//www.gravatar.com/avatar/b0d8c6e5ea589e6fc3d3e08afb1873bb?d=retro&r=g&s=30 2x'},
{id: 2, name: 'Kaunas', avatar: '//www.gravatar.com/avatar/ddac2aa63ce82315b513be9dc93336e5?d=retro&r=g&s=15'},
{id: 3, name: 'Pavilnys', avatar: '//www.gravatar.com/avatar/6acb7abf486516ab7fb0a6efa372042b?d=retro&r=g&s=15'}
{id: 3, name: 'Pavilnys', avatar: '//www.gravatar.com/avatar/6acb7abf486516ab7fb0a6efa372042b?d=retro&r=g&s=15'},
{id: 4, name: 'Siauliai', avatar: '//www.gravatar.com/avatar/b0d8c6e5ea589e6fc3d3e08afb1873bb?d=retro&r=g&s=30 2x'},
];

cities2 = this.cities.slice();
Expand Down
16 changes: 16 additions & 0 deletions demo/app/examples/reactive-forms.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { NgOption } from '@ng-select/ng-select';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { DataService } from '../shared/data.service';
import { NgSelectComponent } from '../../../src/ng-select/ng-select.component';

@Component({
selector: 'reactive-forms',
Expand Down Expand Up @@ -75,9 +76,12 @@ import { DataService } from '../shared/data.service';
<div class="form-group">
<label for="album">Loading async data</label>
<ng-select [items]="albums"
#select
bindLabel="title"
dropdownPosition="auto"
bindValue="id"
placeholder="Select album"
[virtualScroll]="true"
formControlName="album">
<ng-template ng-option-tmp let-item="item" let-search="searchTerm">
<div><span>Title: </span><span [innerHTML]="item.title" [ngOptionHighlight]="search"></span></div>
Expand All @@ -89,6 +93,8 @@ import { DataService } from '../shared/data.service';
<button class="btn btn-secondary btn-sm" (click)="selectFirstAlbum()">Select first album</button>
<button class="btn btn-secondary btn-sm" (click)="selectAlbumsRange(0, 10)">Set 0-10 albums</button>
<button class="btn btn-secondary btn-sm" (click)="selectAlbumsRange(10, 20)">Set 10-20 albums</button>
<button (click)="openSelect(select)" class="btn btn-sm btn-secondary">Open</button>
<button (click)="closeSelect(select)" class="btn btn-sm btn-secondary">Close</button>
</div>
<hr>
Expand All @@ -98,6 +104,7 @@ import { DataService } from '../shared/data.service';
bindLabel="title"
bindValue="thumbnailUrl"
placeholder="Select photo"
[virtualScroll]="true"
formControlName="photo">
<ng-template ng-label-tmp let-item="item">
<img height="15" width="15" [src]="item.thumbnailUrl"/>
Expand Down Expand Up @@ -130,6 +137,7 @@ import { DataService } from '../shared/data.service';
bindLabel="title"
bindValue="thumbnailUrl"
placeholder="Select photo"
[virtualScroll]="true"
formControlName="photo">
<ng-template ng-label-tmp let-item="item">
<img height="15" width="15" [src]="item.thumbnailUrl"/>
Expand Down Expand Up @@ -193,6 +201,14 @@ export class ReactiveFormsComponent {
});
}

openSelect(select: NgSelectComponent) {
select.open();
}

closeSelect(select: NgSelectComponent) {
select.close();
}

toggleAgeDisable() {
if (this.heroForm.controls.age.disabled) {
this.heroForm.controls.age.enable();
Expand Down
14 changes: 10 additions & 4 deletions demo/app/examples/virtual-scroll.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { HttpClient } from '@angular/common/http';
</p>
---html,true
<ng-select [items]="photosBuffer"
[virtualScroll]="true"
[loading]="loading"
bindLabel="title"
bindValue="thumbnailUrl"
placeholder="Select photo"
Expand All @@ -30,6 +32,7 @@ export class VirtualScrollComponent {
photos = [];
photosBuffer = [];
bufferSize = 50;
loading = false;

constructor(private http: HttpClient) {}

Expand All @@ -40,11 +43,14 @@ export class VirtualScrollComponent {
});
}

fetchMore($event: {start: number; end: number}) {
fetchMore() {
const len = this.photosBuffer.length;
if ($event.end === len) {
const more = this.photos.slice(len, this.bufferSize + len);
const more = this.photos.slice(len, this.bufferSize + len);
this.loading = true;
// using timeout here to simulate backend API delay
setTimeout(() => {
this.loading = false;
this.photosBuffer = this.photosBuffer.concat(more);
}
}, 200)
}
}
3 changes: 1 addition & 2 deletions src/ng-select/items-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,10 @@ export class ItemsList {
this._markedIndex = this._filteredItems.indexOf(item);
}

markSelectedOrDefault(markDefault: boolean) {
markSelectedOrDefault(markDefault?: boolean) {
if (this._filteredItems.length === 0) {
return;
}

const indexOfLastSelected = this._filteredItems.indexOf(this._lastSelectedItem);
if (this._lastSelectedItem && indexOfLastSelected > -1) {
this._markedIndex = indexOfLastSelected;
Expand Down
76 changes: 0 additions & 76 deletions src/ng-select/ng-dropdown-panel.component.spec.ts

This file was deleted.

0 comments on commit ea6b636

Please sign in to comment.