<!DOCTYPE html>
<html>
<head>
<title>Fuel Travel Angular2 OrderBy Pipe</title>
<link rel="stylesheet" href="style.css" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.35.0/es6-sham.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.23/system-polyfills.js"></script>
<script src="https://cdn.polyfill.io/v2/polyfill.js?features=Intl.~locale.en"></script>
<script src="https://code.angularjs.org/2.0.0-beta.7/angular2-polyfills.js"></script>
<script src="https://code.angularjs.org/tools/system.js"></script>
<script src="https://code.angularjs.org/tools/typescript.js"></script>
<script src="config.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.7/Rx.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.7/angular2.min.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.7/http.min.js"></script>
<script>
System.import('app')
.catch(console.error.bind(console));
</script>
</head>
<body>
<main class="container">
<my-app>
loading...
</my-app>
</main>
</body>
</html>
/* Styles go here */
### Angular2 Starter Plunker - Typescript - Beta 0
A simple plunker demonstrating Angular2 usage:
- Uses SystemJS + TypeScript to compile on the fly
- Includes binding, directives, http, pipes, and DI usage.
System.config({
//use typescript for compilation
transpiler: 'typescript',
//typescript compiler options
typescriptOptions: {
emitDecoratorMetadata: true
},
//map tells the System loader where to look for things
map: {
app: "./src"
},
//packages defines our app package
packages: {
app: {
main: './main.ts',
defaultExtension: 'ts'
}
}
});
//main entry point
import {bootstrap} from 'angular2/platform/browser';
import {App} from './app';
bootstrap(App, [])
.catch(err => console.error(err));
//our root app component
import {Component,ChangeDetectionStrategy} from 'angular2/core'
import {OrderBy} from "./orderBy"
export class Person {
constructor(public firstName: string, public lastName: string, public age: number) {}
}
@Component({
selector: 'my-app',
templateUrl: 'src/app.html',
pipes: [OrderBy],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class App {
fruit: string[] = ["orange", "apple", "pear", "grape", "banana"];
numbers: number[] = [1234, 0.214, 8675309, -1, 582];
people: Person[] = [
new Person('Linus', 'Torvalds', 46),
new Person('Larry', 'Ellison', 71),
new Person('Mark', 'Zuckerberg', 31),
new Person('Sergey', 'Brin', 42),
new Person('Vint', 'Cerf', 72),
new Person('Richard', 'Stallman', 62),
new Person('John', 'Papa', 42)
];
added: boolean = false;
constructor() {}
addToArrays(): void{
this.fruit.push("new fruit");
this.numbers.push(843);
this.people.push(new Person('New', 'Person', 47));
this.added = true;
}
}
/*
* Example use
* Basic Array of single type: *ngFor="#todo of todoService.todos | orderBy : '-'"
* Multidimensional Array Sort on single column: *ngFor="#todo of todoService.todos | orderBy : ['-status']"
* Multidimensional Array Sort on multiple columns: *ngFor="#todo of todoService.todos | orderBy : ['status', '-title']"
*/
import {Pipe, PipeTransform} from 'angular2/core';
@Pipe({name: 'orderBy', pure: false})
export class OrderBy implements PipeTransform {
static _orderByComparator(a:any, b:any):number{
if((isNaN(parseFloat(a)) || !isFinite(a)) || (isNaN(parseFloat(b)) || !isFinite(b))){
//Isn't a number so lowercase the string to properly compare
if(a.toLowerCase() < b.toLowerCase()) return -1;
if(a.toLowerCase() > b.toLowerCase()) return 1;
}
else{
//Parse strings as numbers to compare properly
if(parseFloat(a) < parseFloat(b)) return -1;
if(parseFloat(a) > parseFloat(b)) return 1;
}
return 0; //equal each other
}
transform(input:any, [config = '+']): any{
if(!Array.isArray(input)) return input;
if(!Array.isArray(config) || (Array.isArray(config) && config.length == 1)){
var propertyToCheck:string = !Array.isArray(config) ? config : config[0];
var desc = propertyToCheck.substr(0, 1) == '-';
//Basic array
if(!propertyToCheck || propertyToCheck == '-' || propertyToCheck == '+'){
return !desc ? input.sort() : input.sort().reverse();
}
else {
var property:string = propertyToCheck.substr(0, 1) == '+' || propertyToCheck.substr(0, 1) == '-'
? propertyToCheck.substr(1)
: propertyToCheck;
return input.sort(function(a:any,b:any){
return !desc
? OrderBy._orderByComparator(a[property], b[property])
: -OrderBy._orderByComparator(a[property], b[property]);
});
}
}
else {
//Loop over property of the array in order and sort
return input.sort(function(a:any,b:any){
for(var i:number = 0; i < config.length; i++){
var desc = config[i].substr(0, 1) == '-';
var property = config[i].substr(0, 1) == '+' || config[i].substr(0, 1) == '-'
? config[i].substr(1)
: config[i];
var comparison = !desc
? OrderBy._orderByComparator(a[property], b[property])
: -OrderBy._orderByComparator(a[property], b[property]);
//Don't return 0 yet in case of needing to sort by next property
if(comparison != 0) return comparison;
}
return 0; //equal each other
});
}
}
}
<h2>OrderBy Examples</h2>
<button (click)="addToArrays()" [style.display]="added?'none':'block'" class="btn btn-primary">Add to Arrays</button>
<section class="row m-a">
<h3>One-Dimensional Arrays</h3>
<div class="col-sm-4 col-md-4">
<h4>Unordered</h4>
<code>*ngFor="#elem of someArray"</code><br/>
<div class="row">
<div class="col-sm-6 col-md-6">
<ul>
<li *ngFor="#f of fruit">{{f}}</li>
</ul>
</div>
<div class="col-sm-6 col-md-6">
<ul>
<li *ngFor="#n of numbers">{{n}}</li>
</ul>
</div>
</div>
</div>
<div class="col-sm-4 col-md-4">
<h4>Asc</h4>
<code>*ngFor="#elem of someArray | orderBy"</code><br/>
OR<br/>
<code>*ngFor="#elem of someArray | orderBy : '+'"</code><br/>
OR<br/>
<code>*ngFor="#elem of someArray | orderBy : ['+']"</code><br/>
<div class="row">
<div class="col-sm-6 col-md-6">
<ul>
<li *ngFor="#f of fruit | orderBy">{{f}}</li>
</ul>
</div>
<div class="col-sm-6 col-md-6">
<ul>
<li *ngFor="#n of numbers | orderBy">{{n}}</li>
</ul>
</div>
</div>
</div>
<div class="col-sm-4 col-md-4">
<h4>Desc</h4>
<code>*ngFor="#elem of someArray | orderBy : '-'"</code><br/>
OR<br/>
<code>*ngFor="#elem of someArray | orderBy : ['-']"</code><br/>
<div class="row">
<div class="col-sm-6 col-md-6">
<ul>
<li *ngFor="#f of fruit | orderBy : '-'">{{f}}</li>
</ul>
</div>
<div class="col-sm-6 col-md-6">
<ul>
<li *ngFor="#n of numbers | orderBy : '-'">{{n}}</li>
</ul>
</div>
</div>
</div>
</section>
<section class="row m-a">
<h3>Multi-Dimensional Arrays</h3>
<div class="col-sm-4 col-md-4">
<h4>Unordered</h4>
<code>*ngFor="#person of people"</code><br/>
<ul>
<li *ngFor="#person of people">{{person.firstName}} {{person.lastName}}, {{person.age}}</li>
</ul>
</div>
<div class="col-sm-4 col-md-4">
<h4>By Last Name Asc</h4>
<code>*ngFor="#person of people | orderBy : 'lastName'"</code><br/>
OR<br/>
<code>*ngFor="#elem of someArray | orderBy : ['lastName']"</code><br/>
<ul>
<li *ngFor="#person of people | orderBy : 'lastName'">{{person.firstName}} {{person.lastName}}, {{person.age}}</li>
</ul>
</div>
<div class="col-sm-4 col-md-4">
<h4>By Age Desc Then First Name Asc</h4>
<code>*ngFor="#person of people | orderBy : ['-age', 'firstName']"</code><br/>
<ul>
<li *ngFor="#person of people | orderBy : ['-age', 'firstName']">{{person.firstName}} {{person.lastName}}, {{person.age}}</li>
</ul>
</div>
</section>
<button (click)="addToArrays()" [style.display]="added?'none':'block'" class="btn btn-primary">Add to Arrays</button>