import { Component } from '@angular/core';
import { HomePage } from '../pages/home/home';
@Component({
template: `<ion-nav [root]="rootPage"></ion-nav>`
})
export class AppComponent {
rootPage = HomePage;
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { IonicApp, IonicModule } from 'ionic-angular';
import { SelectSearchableModule } from 'ionic-select-searchable';
import { AppComponent } from './app.component';
import { HomePage } from '../pages/home/home';
import { ModalPage } from '../pages/modal/modal';
import { PortService } from '../services/index';
let components = [AppComponent, HomePage, ModalPage];
@NgModule({
imports: [
BrowserModule,
IonicModule.forRoot(AppComponent),
SelectSearchableModule
],
bootstrap: [IonicApp],
declarations: components,
entryComponents: components,
providers: [PortService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);
<!DOCTYPE html>
<html>
<head>
<title>Ionic SelectSearchable Demo</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://unpkg.com/core-js@2.4.1/client/shim.min.js"></script>
<script src="https://unpkg.com/zone.js@0.6.26?main=browser"></script>
<script src="https://unpkg.com/systemjs@0.19.40/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
<link href="https://unpkg.com/ionic-angular@3.1.1/css/ionic.css" rel="stylesheet">
<link href="https://unpkg.com/ionic-select-searchable@latest/select-searchable.style.min.css" rel="stylesheet">
</head>
<body>
<ion-app></ion-app>
<script>
System.import('app').catch(function(error) {
console.error(error);
});
</script>
</body>
</html>
# Ionic SelectSearchable Demo
A demo app for [Ionic SelectSearchable](https://github.com/eakoriakin/ionic-select-searchable) component.
(function(global) {
System.config({
transpiler: 'ts',
typescriptOptions: {
tsconfig: true
},
meta: {
typescript: {
"exports": "ts"
}
},
// Paths serve as alias.
paths: {
'npm:': 'https://unpkg.com/'
},
// Map tells the System loader where to look for things.
map: {
'@angular/core': 'npm:@angular/core@4.0.2/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common@4.0.2/bundles/common.umd.js',
'@angular/compiler': 'npm:@angular/compiler@4.0.2/bundles/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser@4.0.2/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic@4.0.2/bundles/platform-browser-dynamic.umd.js',
'@angular/http': 'npm:@angular/http@4.0.2/bundles/http.umd.js',
'@angular/forms': 'npm:@angular/forms@4.0.2/bundles/forms.umd.js',
'ionic-angular': 'npm:ionic-angular@3.1.1',
'rxjs': 'npm:rxjs@5.5.2',
'rxjs/operators': 'npm:rxjs@5.5.2/operators/index.js',
'ts': 'npm:plugin-typescript@5.2.7/lib/plugin.js',
'typescript': 'npm:typescript@2.2.1/lib/typescript.js',
'ionic-select-searchable': 'npm:ionic-select-searchable@2.1.1/index.js'
},
// Packages tells the System loader how to load when
// no file name and/or no extension.
packages: {
rxjs: {
defaultExtension: 'js'
},
'ionic-angular': {
main: './umd/index.js',
defaultExtension: 'js'
},
app: {
main: './main.ts',
defaultExtension: 'ts'
},
pages: {
defaultExtension: 'ts'
},
components: {
defaultExtension: 'ts'
},
services: {
defaultExtension: 'ts'
},
types: {
defaultExtension: 'ts'
}
}
});
})(this);
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true
}
}
export class Port {
public id: number;
public name: string;
public country: string;
}
export * from './port';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { delay } from 'rxjs/operators';
import { Port } from '../types/index';
@Injectable()
export class PortService {
private ports: Port[] = [
{ id: 0, name: 'Tokai', country: 'Japan' },
{ id: 2, name: 'Vladivostok', country: 'Russia' },
{ id: 3, name: 'Navlakhi', country: 'India' },
{ id: 4, name: 'Cayman Brac', country: 'Cayman Islands' },
{ id: 5, name: 'Areia Branca', country: 'Brazil' },
{ id: 6, name: 'Port Ibrahim', country: 'Egypt' },
{ id: 7, name: 'Brahestad', country: 'Finland' },
{ id: 8, name: 'Brake', country: 'Germany' },
{ id: 9, name: 'Hantsport NS', country: 'Canada' },
{ id: 10, name: 'Santa Maria Bay', country: 'Cape Verde' },
{ id: 11, name: 'Antofagasta', country: 'Chile' },
{ id: 12, name: 'San Antonio', country: 'Chile' },
{ id: 13, name: 'Santa Barbara', country: 'Chile' },
{ id: 14, name: 'Cabo San Antonio', country: 'Argentina' },
{ id: 15, name: 'Diamante', country: 'Argentina' },
{ id: 16, name: 'San Antonio Este Arg', country: 'Argentina' },
{ id: 17, name: 'Santa Anna Bay', country: 'Curacao' },
{ id: 18, name: 'Hambantota', country: 'Sri Lanka' },
{ id: 19, name: 'Antananarivo', country: 'Madagascar' },
{ id: 20, name: 'Navegantes', country: 'Brazil' },
{ id: 21, name: 'Bantry Bay', country: 'Ireland' },
{ id: 22, name: 'Porto Levante', country: 'Italy' },
{ id: 23, name: 'Port of Antikyra', country: 'Greece' },
{ id: 24, name: 'Berantai FPSO', country: 'Malaysia' },
{ id: 25, name: "Alicante", country: 'Spain' },
{ id: 26, name: "Almirante", country: 'Panama' },
{ id: 27, name: "Canton", country: 'China' },
{ id: 28, name: "Dante", country: 'Somalia' },
{ id: 29, name: "Davant LA", country: 'United States' },
{ id: 30, name: "Fremantle", country: 'Australia' },
{ id: 31, name: "General Santos", country: 'Philippines' },
{ id: 32, name: "Granton", country: 'United Kingdom' },
{ id: 33, name: "Guanta", country: 'Venezuela' },
{ id: 34, name: "Hambantota", country: 'Sri Lanka' },
{ id: 35, name: "Kalimantan", country: 'Indonesia' },
{ id: 36, name: "Kantang", country: 'Thailand' },
{ id: 37, name: "Kantvik", country: 'Finland' },
{ id: 38, name: "Kuantan", country: 'Malaysia' },
{ id: 39, name: "Lantian", country: 'China' },
{ id: 40, name: "Manta", country: 'Ecuador' },
{ id: 41, name: "Mantes", country: 'France' },
{ id: 42, name: "Nantong", country: 'China' },
{ id: 43, name: "Antonina", country: 'Brazil' },
{ id: 44, name: "Santa Cruz", country: 'Argentina' },
{ id: 45, name: "Santa Eugenia De Riveira", country: 'Spain' }
];
getPorts(page: number = 1, size: number = 15): Port[] {
return this.ports.slice((page - 1) * size, ((page - 1) * size) + size);
}
getPortsAsync(page: number = 1, size: number = 15): Observable<Port[]> {
return new Observable<Port[]>(observer => {
observer.next(this.getPorts(page, size));
observer.complete()
}).pipe(delay(2000));
}
}
export * from './port.service';
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, FormControl, Validators } from '@angular/forms';
import { InfiniteScroll, ModalController } from 'ionic-angular';
import { SelectSearchableComponent } from 'ionic-select-searchable';
import { Port } from '../../types/index';
import { PortService } from '../../services/index';
import { ModalPage } from '../modal/modal';
@Component({
selector: 'page-home',
templateUrl: './pages/home/home.html'
})
export class HomePage {
ports: Port[];
ports10: Port[];
portNames: string[];
port1: Port;
port2: Port;
port3: Port;
port4: Port;
port5: Port;
port6: Port;
port7: Port;
port9: string = 'Vladivostok';
port10: Port;
form: FormGroup;
port8Control: FormControl;
ports10Page = 2;
constructor(
private formBuilder: FormBuilder,
private modalController: ModalController,
private portService: PortService
) {
this.ports = this.portService.getPorts();
this.portNames = this.portService.getPorts().map(port => port.name);
this.port2 = this.ports[1];
this.port7 = this.ports[5];
this.port8Control = this.formBuilder.control(this.ports[6], Validators.required);
this.form = this.formBuilder.group({
port8: this.port8Control
});
this.ports10 = this.portService.getPorts();
}
getMorePorts(event: { component: SelectSearchableComponent, infiniteScroll: InfiniteScroll }) {
// Trere're no more ports - disable infinite scroll.
if (this.ports10Page > 3) {
event.infiniteScroll.enable(false);
return;
}
this.portService.getPortsAsync(this.ports10Page).subscribe(ports => {
event.component.items = event.component.items.concat(ports);
event.infiniteScroll.complete();
this.ports10Page++;
});
}
searchPorts(event: { component: SelectSearchableComponent, text: string }) {
let text = (event.text || '').trim().toLowerCase();
if (!text) {
event.component.items = [];
return;
} else if (event.text.length < 3) {
return;
}
event.component.isSearching = true;
this.portService.getPortsAsync().subscribe(ports => {
event.component.items = ports.filter(port => {
return port.name.toLowerCase().indexOf(text) !== -1 ||
port.country.toLowerCase().indexOf(text) !== -1;
});
event.component.isSearching = false;
});
}
portChange(event: { component: SelectSearchableComponent, value: any }) {
console.log('port:', event.value);
}
reset() {
this.port8Control.reset();
}
openModal() {
let modal = this.modalController.create(ModalPage);
modal.present();
}
}
<ion-header>
<ion-navbar>
<ion-title>Ionic SelectSearchable</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<ion-item-group margin-bottom>
<ion-item-divider color="light">
<h1>Basic</h1>
</ion-item-divider>
<ion-item>
<select-searchable
[(ngModel)]="port1"
itemValueField="id"
itemTextField="name"
[items]="ports"
(onChange)="portChange($event)">
<ng-template selectSearchableLabelTemplate>
Port
</ng-template>
</select-searchable>
</ion-item>
</ion-item-group>
<ion-item-group margin-bottom>
<ion-item-divider color="light">
<h1>Initial value</h1>
</ion-item-divider>
<ion-item>
<select-searchable
[(ngModel)]="port2"
itemValueField="id"
itemTextField="name"
[items]="ports"
(onChange)="portChange($event)">
<ng-template selectSearchableLabelTemplate>
Port
</ng-template>
</select-searchable>
</ion-item>
</ion-item-group>
<ion-item-group margin-bottom>
<ion-item-divider color="light">
<h1>Search</h1>
</ion-item-divider>
<ion-item>
<select-searchable
[(ngModel)]="port3"
itemValueField="id"
itemTextField="name"
[items]="ports"
[canSearch]="true"
(onChange)="portChange($event)">
<ng-template selectSearchableLabelTemplate>
Port
</ng-template>
</select-searchable>
</ion-item>
</ion-item-group>
<ion-item-group margin-bottom>
<ion-item-divider color="light">
<h1>Search (Async)</h1>
</ion-item-divider>
<ion-item>
<select-searchable
[(ngModel)]="port4"
itemValueField="id"
itemTextField="name"
[items]="ports"
[canSearch]="true"
searchPlaceholder="Enter 3 or more characters, e.g. "san""
(onSearch)="searchPorts($event)"
(onChange)="portChange($event)">
<ng-template selectSearchableLabelTemplate>
Port
</ng-template>
</select-searchable>
</ion-item>
</ion-item-group>
<ion-item-group margin-bottom>
<ion-item-divider color="light">
<h1>Item template</h1>
</ion-item-divider>
<ion-item>
<select-searchable
[(ngModel)]="port5"
itemValueField="id"
itemTextField="name"
[items]="ports"
[canSearch]="true"
(onChange)="portChange($event)">
<ng-template selectSearchableLabelTemplate>
Port
</ng-template>
<ng-template selectSearchableItemTemplate let-port="item">
{{port.name}} ({{port.country}})
</ng-template>
</select-searchable>
</ion-item>
</ion-item-group>
<ion-item-group margin-bottom>
<ion-item-divider color="light">
<h1>Multiple selection</h1>
</ion-item-divider>
<ion-item>
<select-searchable
[(ngModel)]="port6"
itemValueField="id"
itemTextField="name"
[items]="ports"
[canSearch]="true"
[isMultiple]="true"
(onChange)="portChange($event)">
<ng-template selectSearchableLabelTemplate>
Port
</ng-template>
</select-searchable>
</ion-item>
</ion-item-group>
<ion-item-group margin-bottom>
<ion-item-divider color="light">
<h1>"Clear" button</h1>
</ion-item-divider>
<ion-item>
<select-searchable
[(ngModel)]="port7"
itemValueField="id"
itemTextField="name"
[items]="ports"
(onChange)="portChange($event)"
[canReset]="true">
<ng-template selectSearchableLabelTemplate>
Port
</ng-template>
</select-searchable>
</ion-item>
</ion-item-group>
<form [formGroup]="form" margin-bottom>
<ion-item-group>
<ion-item-divider color="light">
<h1>Angular Forms support</h1>
</ion-item-divider>
<ion-item>
<select-searchable
formControlName="port8"
itemValueField="id"
itemTextField="name"
[items]="ports"
[canSearch]="true"
(onChange)="portChange($event)">
<ng-template selectSearchableLabelTemplate>
Port
</ng-template>
</select-searchable>
</ion-item>
<ion-item>
<ion-badge color="danger" *ngIf="!form.valid">Invalid</ion-badge>
<ion-badge color="secondary" *ngIf="form.valid">Valid</ion-badge>
<button ion-button item-right (click)="reset()" [disabled]="!form.valid">
Reset
</button>
</ion-item>
</ion-item-group>
</form>
<ion-item-group margin-bottom>
<ion-item-divider color="light">
<h1>Flat array, e.g. ['Vladivostok', ...]</h1>
</ion-item-divider>
<ion-item>
<select-searchable
[(ngModel)]="port9"
[items]="portNames"
[canSearch]="true"
(onChange)="portChange($event)">
<ng-template selectSearchableLabelTemplate>
Port
</ng-template>
</select-searchable>
</ion-item>
</ion-item-group>
<ion-item-group margin-bottom>
<ion-item-divider color="light">
<h1>Infinite scroll</h1>
</ion-item-divider>
<ion-item>
<select-searchable
[(ngModel)]="port10"
itemValueField="id"
itemTextField="name"
[items]="ports10"
[hasInfiniteScroll]="true"
[canSearch]="true"
(onInfiniteScroll)="getMorePorts($event)"
(onChange)="portChange($event)">
<ng-template selectSearchableLabelTemplate>
Port
</ng-template>
</select-searchable>
</ion-item>
</ion-item-group>
<ion-item-group margin-bottom>
<ion-item-divider color="light">
<h1>Inside modal</h1>
</ion-item-divider>
<ion-item>
<button ion-button (click)="openModal()">Open</button>
</ion-item>
</ion-item-group>
</ion-content>
<ion-header>
<ion-toolbar>
<ion-title>
Modal
</ion-title>
<ion-buttons start>
<button ion-button (click)="dismiss()">
<ion-icon name="md-close"></ion-icon>
</button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<ion-item>
<select-searchable
[(ngModel)]="port"
itemValueField="id"
itemTextField="name"
[items]="ports">
<ng-template selectSearchableLabelTemplate>
Port
</ng-template>
</select-searchable>
</ion-item>
</ion-list>
</ion-content>
import { Component } from '@angular/core';
import { ViewController } from 'ionic-angular';
import { Port } from '../../types/index';
import { PortService } from '../../services/index';
@Component({
selector: 'page-modal',
templateUrl: './pages/modal/modal.html'
})
export class ModalPage {
port: Port;
ports: Port[];
constructor(private viewController: ViewController, private portService: PortService) {
this.ports = this.portService.getPorts();
}
dismiss() {
this.viewController.dismiss();
}
}