Skip to content

Instantly share code, notes, and snippets.

@jmvtrinidad
Last active April 26, 2017 12:15
Show Gist options
  • Save jmvtrinidad/f525c20670d7fbd1db81a4d282aa49b4 to your computer and use it in GitHub Desktop.
Save jmvtrinidad/f525c20670d7fbd1db81a4d282aa49b4 to your computer and use it in GitHub Desktop.
Aurelia Gist
<template>
<require from="./pagination"></require>
<h1>Array Observation</h1>
<div>
<button click.delegate="pushTableMessage()">Push</button>
<h2>Table</h2>
<ul repeat.for="item of table.itemsOnCurrentPage">
<li>
${item}
</li>
</ul>
<span> ${table.info}</span>
<pagination max-page-index.bind="table.maxPageIndex"
page-number-changed.call="changed(currentPageIndex)">
</pagination>
<button click.delegate="pushMessage()">Push</button>
<button click.delegate="mutateMessages()">Mutate</button>
<button click.delegate="clearMessages()">Clear</button>
<h2>Messages</h2>
<ul repeat.for="message of messages">
<li>
${message}
</li>
</ul>
<h2>Filtered Messages</h2>
<ul repeat.for="message of messagesFiltered">
<li>
${message}
</li>
</ul>
</div>
</template>
import {computedFrom} from 'aurelia-framework';
import { AuGrid } from './au-grid';
export class App {
constructor(auGrid) {
this.table = new AuGrid([])
for(var i = 0; i < 100; i++){
this.table.items.push('message ' + i)
}
}
messages = ['message 0']
// @computedFrom('messages')
get messagesFiltered() {
return this.messages
}
changed(e) {
this.table.currentPageIndex = e;
}
pushTableMessage() {
this.table.items.push('message ' + this.table.items.length)
}
pushMessage() {
this.messages.push('message ' + this.messages.length)
}
mutateMessages(){
this.messages = [
'mutation 1',
'mutation 2'
]
}
clearMessages(){
this.messages = []
}
}
import './objectExtensions';
import { computedFrom } from 'aurelia-framework';
export class AuGrid {
searchValue = {};
currentPageIndex = 1;
pageSize;
items;
constructor(items, pageSize = 10) {
this.items = items;
this.pageSize = pageSize;
this.searchValue = typeof this.items[0] === 'object'
? {}
: '';
}
@computedFrom('items.length')
get totalRows(){
return this.items.length;
}
@computedFrom('itemsFiltered')
get totalFilteredRows() {
return this.itemsFiltered.length;
}
@computedFrom('startRow', 'pageSize', 'totalRows')
get currentRowStart() {
return this.totalRows > this.pageSize
? (this.startRow + 1)
: this.totalRows === 0 ? 0 : 1;
}
@computedFrom('startRow', 'pageSize', 'totalRows')
get currentRowEnd() {
return (this.startRow + this.pageSize) < this.totalRows
? (this.startRow + this.pageSize)
: this.totalRows;
}
@computedFrom('currentPageIndex', 'pageSize')
get startRow() {
if (this.currentPageIndex === 0)
return 0;
return (this.currentPageIndex - 1) * this.pageSize;
}
@computedFrom('totalFilteredRows', 'pageSize')
get maxPageIndex() {
let index = Math.ceil(this.totalFilteredRows / this.pageSize);
return index;
}
// @computedFrom('items', 'searchValue')
get itemsFiltered() {
if(this.searchValue){
return this.items.filter(item => typeof item === 'object'
? Object.same(this.searchValue, item)
: this.searchValue === item);
}
return this.items;
}
// @computedFrom('startRow', 'itemsFiltered', 'pageSize')
get itemsOnCurrentPage() {
return this.itemsFiltered.slice(this.startRow,
this.startRow + this.pageSize);
}
@computedFrom('currentRowStart', 'currentRowEnd', 'totalRows')
get info(): string {
return `Showing ${this.currentRowStart} to ${this.currentRowEnd} of ${this.totalRows} entries`;
}
}
<!doctype html>
<html>
<head>
<title>Aurelia</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body aurelia-app>
Loading...
<script src="https://jdanyow.github.io/rjs-bundle/node_modules/requirejs/require.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/config.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/bundles/aurelia.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/bundles/babel.js"></script>
<script>
require(['aurelia-bootstrapper']);
</script>
</body>
</html>
export function configure(aurelia) {
aurelia.use
.standardConfiguration()
.developmentLogging()
.globalResources('./pagination');
aurelia.start().then(() => aurelia.setRoot());
}
Object.same = function (source, target) {
if (source === target) return true;
if (!(source instanceof Object) || !(target instanceof Object)) return false;
// if they are not strictly equal, they both need to be Objects
for (let prop in source) {
if (!source.hasOwnProperty(prop)) continue;
if (source[prop] === undefined || source[prop] === null || source[prop] === '') continue;
if (typeof source[prop] === 'object' && Object.same(source[prop], target[prop])) continue;
if (typeof source[prop] === 'string' && target[prop].startsWith(source[prop])) continue;
if (source[prop] === target[prop]) continue;
return false;
}
return true;
};
Object.equals = function (x, y) {
if (x === y) return true;
// if both x and y are null or undefined and exactly the same
if (!(x instanceof Object) || !(y instanceof Object)) return false;
// if they are not strictly equal, they both need to be Objects
if (x.constructor !== y.constructor) return false;
// they must have the exact same prototype chain, the closest we can do is
// test there constructor.
for (var p in x) {
if (!x.hasOwnProperty(p)) continue;
// other properties were tested using x.constructor === y.constructor
if (!y.hasOwnProperty(p)) return false;
// allows to compare x[ p ] and y[ p ] when set to undefined
if (x[p] === y[p]) continue;
// if they have the same strict value or identity then they are equal
if (typeof (x[p]) !== "object") return false;
// Numbers, Strings, Functions, Booleans must be strictly equal
if (!Object.equals(x[p], y[p])) return false;
// Objects and Arrays must be tested recursively
}
for (p in y) {
if (y.hasOwnProperty(p) && !x.hasOwnProperty(p)) return false;
// allows x[ p ] to be set to undefined
}
return true;
};
<template>
<ul class="pagination pull-right">
<li class.bind="currentPageNumber === 1 || !maxPageIndex ? 'disabled' : ''">
<a href="#" click.delegate="setCurrentPage(1, $event)" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
<li class.bind="currentPageNumber === 1 || !maxPageIndex ? 'disabled' : ''">
<a href="#" aria-label="Previous"
click.delegate="setCurrentPage(currentPageNumber - 1, $event)">
<span aria-hidden="true">&lsaquo;</span>
</a>
</li>
<li repeat.for="index of range(pageStartNumber, pageEndNumber)"
class.bind="currentPageNumber === index ? 'active' : ''">
<a href="#" click.delegate="setCurrentPage(index, $event)">
<span aria-hidden="true">${ index }</span>
</a>
</li>
<li class.bind="currentPageNumber === maxPageIndex
|| !maxPageIndex ? 'disabled' : ''">
<a href="#" click.delegate="setCurrentPage(currentPageNumber + 1, $event)" aria-label="Last">
<span aria-hidden="true">&rsaquo;</span>
</a>
</li>
<li class.bind="currentPageNumber === maxPageIndex
|| !maxPageIndex ? 'disabled' : ''">
<a href="#" click.delegate="setCurrentPage(maxPageIndex, $event)" aria-label="Last">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
</ul>
</template>
import { bindable, computedFrom, observable } from 'aurelia-framework';
export class Pagination {
@bindable value;
//@observable
@bindable maxPageIndex;
//@observable
@bindable rowIndex;
@bindable pageNumberChanged;
currentPageNumber = 1;
rowIndexChanged(newValue, oldValue) {
}
activate() {
this.setCurrentPage(1);
}
maxPageIndexChanged(newValue, oldValue) {
if (this.currentPageNumber > newValue) {
this.setCurrentPage(1);
}
}
setCurrentPage(pageNumber, event) {
//if (event) {
// event.preventDefault();
//}
if (pageNumber === 0 || pageNumber > this.maxPageIndex
|| pageNumber === this.currentPageNumber) {
return;
}
this.pageNumberChanged({
currentPageIndex: pageNumber
});
if (!this.rowIndex) {
this.currentPageNumber = pageNumber;
}
}
range(min, max) {
let result = [];
for (let i = min; i <= max; i++) {
result.push(i);
}
return result;
}
get pageStartNumber() {
let startNumber = this.currentPageNumber <= 4
? 1
: this.currentPageNumber >= this.maxPageIndex - 3
? this.maxPageIndex - 6
: this.currentPageNumber - 3;
return startNumber < 1 ? 1 : startNumber;
}
@computedFrom('pageStartNumber', 'maxPageIndex')
get pageEndNumber() {
let pageEnd = this.pageStartNumber + 6;
return pageEnd > this.maxPageIndex ? this.maxPageIndex : pageEnd;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment