Last active
July 22, 2016 10:40
-
-
Save vegarringdal/8d5fc464893b77101faf4effeec43f27 to your computer and use it in GitHub Desktop.
aurelia-v-grid - Demo: Custom pager
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<require from="valueConverters"></require> | |
<require from="v-grid-control-form.html"></require> | |
<div class="row"> | |
<v-grid | |
class="col-md-6" | |
style="height:350px" | |
v-row-height="25" | |
v-header-height="50" | |
v-footer-height="50" | |
v-multi-select="true" | |
v-custom-pager="<own-pager></own-pager>" | |
v-row-onclick.delegate="singleClick($event.detail)" | |
v-row-ondblclick.delegate="singleDblClick($event.detail)" | |
v-current-entity.bind=myCurrentEntity | |
v-remote-index="id" | |
v-event-onremote.call="callRemoteServer($event)" | |
v-row-on-draw.call="onRowDraw($event)" | |
v-collection.bind=myCollection | |
v-grid-context.bind=myGrid> | |
<v-grid-col col-width="50" col-type="selection" col-add-row-attributes="v-key-move"></v-grid-col> | |
<v-grid-col col-width="120" col-type="text" col-field="name" col-sort="name" col-header-name="Full name" col-filter="name|*|onKeyDown" col-filter-top="false" col-add-row-attributes="v-row-menu='name' v-key-move" col-add-filter-attributes="v-col-header-name-menu='name'"></v-grid-col> | |
<v-grid-col col-width="100" col-field="number | numberFormat & updateTrigger:'blur':'paste'" col-sort="number" col-header-name="Salery" col-filter="number|>=" col-filter-top="true" col-add-row-attributes="v-row-menu='number' v-key-move" col-add-filter-attributes="v-col-header-name-menu='number'" col-css="color:${tempRef.numberColor};font-weight:${tempRef.numberFont}"></v-grid-col> | |
<v-grid-col col-width="105" col-type="text" col-field="date | dateFormat & updateTrigger:'blur':'paste'" col-sort="date" col-header-name="Created" col-filter="date|>|dateFormat" col-filter-top="true" col-add-row-attributes="v-row-menu='date' v-key-move" col-add-filter-attributes="v-col-header-name-menu='date'"></v-grid-col> | |
<v-grid-col col-width="100" col-type="checkbox" col-field="bool" col-sort="bool" col-header-name="Booked" col-filter="bool|=" col-filter-top="true" col-add-row-attributes="v-row-menu='bool' v-key-move" col-add-filter-attributes="v-col-header-name-menu='bool'"></v-grid-col> | |
<v-grid-col col-width="107" col-type="image" col-field="images" col-header-name="Profile Img" col-filter-top="true" col-add-row-attributes="v-row-menu='images' v-key-move tabindex='0'" col-add-filter-attributes="v-col-header-name-menu='images'"></v-grid-col> | |
</v-grid> | |
<!-- Form to the right --> | |
<v-grid-control-form entity.bind="myCurrentEntity"></v-grid-control-form> | |
</div> | |
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {RemoteData} from 'remoteData' | |
export class BasicUse { | |
//utillity functions | |
myGrid = {}; | |
//current entity, link this to inputs etc | |
myCurrentEntity = {}; | |
//collection to display | |
myCollection = []; | |
//on row draw event, setting some extra fields to tempRef we will use in the css | |
onRowDraw(data) { | |
if (data) { | |
if (data.tempRef) { | |
if (data.tempRef.number > 100) { | |
data.tempRef.numberColor = "green"; | |
data.tempRef.numberFont = "normal"; | |
} else { | |
data.tempRef.numberColor = "red"; | |
data.tempRef.numberFont = "bold"; | |
} | |
} | |
} | |
} | |
//helper for dummy data | |
constructor() { | |
//create a new remote data class | |
this.remoteData = new RemoteData('https://vgriddummydata-nodedataapi.rhcloud.com/', 'data/people'); | |
} | |
attached(){ | |
//call our load data | |
this.loadData(); | |
} | |
loadData() { | |
//tell grid to set loading overlay while we get our data | |
this.myGrid.ctx.setLoadingOverlay(true); | |
//set limit//offset in our dataclass | |
this.remoteData.setLimit(40); | |
this.remoteData.setOffset(0); | |
//get the data from class | |
this.remoteData.getData() | |
.then((data)=>{ | |
//set data to grid (the data have limit % length included) | |
//-> data ={col:data.result, length:data.length, limit:40} | |
// you could include offset here if you wanted.. | |
this.myGrid.ctx.setData(data); | |
}) | |
} | |
//called by grid | |
callRemoteServer(param){//filterArray, orderByArray, callback) { | |
//create orderby string in dataclass | |
this.remoteData.createOrderByString(param.sort); | |
//create qquery string in dataclass | |
this.remoteData.createQueryString(param.filter); | |
//set limit and offset in dataclass | |
this.remoteData.setLimit(param.limit); | |
this.remoteData.setOffset(param.offset); | |
//call datac,lss and return the data obj. | |
return this.remoteData.getData() | |
.then((data)=> { | |
return data; | |
}).catch((err)=> { | |
console.error(err); | |
console.log(err) | |
}); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html> | |
<head> | |
<title>Aurelia</title> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous"> | |
</head> | |
<body aurelia-app="main"> | |
<h1>Loading...</h1> | |
<script src="https://cdn.rawgit.com/vegarringdal/vGridGistRunJSPMBundle/v.1.0.8/jspm_packages/system.js"></script> | |
<script src="https://cdn.rawgit.com/vegarringdal/vGridGistRunJSPMBundle/v.1.0.8/config.js"></script> | |
<script> | |
System.import('aurelia-bootstrapper'); | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export function configure(aurelia) { | |
aurelia.use | |
.standardConfiguration() | |
.developmentLogging() | |
.globalResources('./mypager') | |
.plugin('aurelia-v-grid'); | |
aurelia.start().then(a => a.setRoot()); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div class="row"> | |
<div class="btn-group btn-group-justified" role="group"> | |
<button style="width:50px" disabled.bind="!statusFirstButton" click.trigger="firstBtn()" type="button" class="btn btn-primary">${statusFirstButtonTitle}</button > | |
<button style="width:50px" disabled.bind="!statusPrevButton" click.trigger="prevBtn()" type="button" class="btn btn-primary">${statusPrevButtonTitle}</button > | |
<button style="width:40px" disabled.bind="!sg0" click.trigger="setG(0)" type="button" class="btn btn-primary">${g0}</button > | |
<button style="width:40px" disabled.bind="!sg1" click.trigger="setG(1)" type="button" class="btn btn-primary">${g1}</button > | |
<button style="width:40px" disabled.bind="!sg2" click.trigger="setG(2)" type="button" class="btn btn-primary">${g2}</button > | |
<button style="width:40px" disabled.bind="!sg3" click.trigger="setG(3)" type="button" class="btn btn-primary">${g3}</button > | |
<button style="width:40px" disabled.bind="!sg4" click.trigger="setG(4)" type="button" class="btn btn-primary">${g4}</button > | |
<button style="width:60px" disabled.bind="!statusMiddle" type="button" class="btn btn-primary">${middle}</button > | |
<button style="width:40px" disabled.bind="!sg5" click.trigger="setG(5)" type="button" class="btn btn-primary">${g5}</button > | |
<button style="width:40px" disabled.bind="!sg6" click.trigger="setG(6)" type="button" class="btn btn-primary">${g6}</button > | |
<button style="width:40px" disabled.bind="!sg7" click.trigger="setG(7)" type="button" class="btn btn-primary">${g7}</button > | |
<button style="width:40px" disabled.bind="!sg8" click.trigger="setG(8)" type="button" class="btn btn-primary">${g8}</button > | |
<button style="width:40px" disabled.bind="!sg9" click.trigger="setG(9)" type="button" class="btn btn-primary">${g9}</button > | |
<button style="width:50px" disabled.bind="!statusNextButton" click.trigger="nextBtn()" type="button" class="btn btn-primary">${statusNextButtonTitle}</button > | |
<button style="width:50px" disabled.bind="!statusLastButton" click.trigger="lastBtn()" type="button" class="btn btn-primary">${statusLastButtonTitle}</button > | |
</div> | |
</div> | |
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/***************************************************************************************************************** | |
* VGridFooterPager | |
* Custom element for use in the footer container | |
* Created by vegar ringdal | |
* | |
****************************************************************************************************************/ | |
import {inject, customElement, bindable} from 'aurelia-framework'; | |
@customElement('own-pager') | |
@inject(Element) | |
export class VGridElementFooterPager { | |
info = ""; | |
//sorry in advance for horrible naming! | |
//buttons between prev and next | |
g0 = "-"; | |
g1 = "-"; | |
g2 = "-"; | |
g3 = "-"; | |
g4 = "-"; | |
middle = "<->"; | |
g5 = "-"; | |
g6 = "-"; | |
g7 = "-"; | |
g8 = "-"; | |
g9 = "-"; | |
constructor(element) { | |
this.element = element; | |
} | |
bind(parent) { | |
this.parent = parent; | |
this.vGrid = parent.vGrid; | |
this.vGridConfig = parent.vGrid.vGridConfig; | |
this.vGrid.vGridPager = this; | |
} | |
attached() { | |
this.statusNextButton = false; | |
this.statusLastButton = false; | |
this.statusFirstButton = false; | |
this.statusPrevButton = false; | |
this.statusNextButtonTitle = this.getLang("pagerBtnNext") || "Next"; | |
this.statusLastButtonTitle = this.getLang("pagerBtnLast") || "Last"; | |
this.statusFirstButtonTitle = this.getLang("pagerBtnFirst") || "First"; | |
this.statusPrevButtonTitle = this.getLang("pagerBtnLast") || "Prev"; | |
this.pagerStringPage = this.getLang("pagerStringPage") || "Page "; | |
this.pagerStringOf = this.getLang("pagerStringOf") || " of "; | |
this.pagerStringTotalEntities = this.getLang("pagerStringTotalEntities") || ", Total entities:"; | |
this.pagerStringPageSize = this.getLang("pagerStringPageSize") || ", page size "; | |
} | |
getLang(value){ | |
return this.vGrid.vGridConfig.attLanguage[value]; | |
} | |
setButtonsAllOver5 = ()=> { | |
//set status first 5 | |
for (let i = 0; i < 5; i++) { | |
this["g" + i] = this.page + (i - 5); | |
this["sg" + i] = true; | |
if (this["g" + i] > this.pages) { | |
this["g" + i] = "-"; | |
this["sg" + i] = false | |
} | |
} | |
//set status last 5 | |
let y = 0; | |
for (let i = 5; i < 10; i++) { | |
this["g" + i] = this.page + (y + 1); | |
this["sg" + i] = true; | |
if (this["g" + i] > this.pages) { | |
this["g" + i] = "-"; | |
this["sg" + i] = false | |
} | |
y++ | |
} | |
}; | |
setButtonsLessThen10 = () =>{ | |
for (let i = 0; i < 10; i++) { | |
this["g" + i] = (i + 1); | |
this["sg" + i] = true; | |
if (this["g" + i] > this.pages) { | |
this["g" + i] = "-"; | |
this["sg" + i] = false | |
} | |
} | |
} | |
setButtonsUnder5AtStart = () =>{ | |
for (let i = 0; i < 10; i++) { | |
this["g" + i] = (i + 1); | |
this["sg" + i] = true; | |
if (this["g" + i] > this.pages) { | |
this["g" + i] = "-"; | |
this["sg" + i] = false | |
} | |
} | |
} | |
setButtonsUnder5AtEnd = () =>{ | |
for (let i = 0; i < 10; i++) { | |
this["g" + i] = (this.pages - 10) + i + 1; | |
this["sg" + i] = true; | |
if (this["g" + i] > this.pages) { | |
this["g" + i] = "-"; | |
this["sg" + i] = false | |
} | |
} | |
} | |
setMiddlebuttons() { | |
if (this.pages > 10) { | |
if (this.page < this.pages - 10) { | |
if (this.page < 6) { | |
//under 5 in the start | |
this.setButtonsUnder5AtStart(); | |
} else { | |
//over 5 in the start | |
this.setButtonsAllOver5() | |
} | |
} else { | |
//more then 10, and page is more then top page -10 | |
if (this.page > this.pages - 5) { | |
//unde 5 at the end | |
this.setButtonsUnder5AtEnd(); | |
} else { | |
//over 5 in the end | |
this.setButtonsAllOver5() | |
} | |
} | |
} else { | |
//less then 10 pages, usually when someone have run a filter | |
this.setButtonsLessThen10() | |
} | |
//set pager | |
this.middle = this.page + "#" + this.pages; | |
} | |
updatePager(data) { | |
this.collectionLength = data.length; | |
this.limit = data.limit; | |
this.offset = data.offset; | |
this.page = this.offset ? Math.ceil(this.offset / this.limit) + 1 : 1; | |
if (this.page === 1) { | |
this.statusFirstButton = false; | |
this.statusPrevButton = false; | |
} else { | |
this.statusFirstButton = true; | |
this.statusPrevButton = true; | |
} | |
if (this.offset >= this.collectionLength - this.limit) { | |
this.statusNextButton = false; | |
this.statusLastButton = false; | |
} else { | |
this.statusNextButton = true; | |
this.statusLastButton = true; | |
} | |
this.pages = Math.ceil(this.collectionLength / this.limit); | |
//do we show page info? | |
if (!this.vGridConfig.attHidePagerInfo) { | |
this.info = `${this.pagerStringPage}${this.page}${this.pagerStringOf}${this.pages}${this.pagerStringTotalEntities}${this.collectionLength}${this.pagerStringPageSize}${this.limit}`; | |
} | |
//raise event | |
this.vGrid.raiseEvent("v-remote-collection-event", { | |
evt: "v-remote-collection-event", | |
page: this.page, | |
pages: this.pages, | |
length: this.collectionLength, | |
pageSize: this.limit | |
}); | |
this.setMiddlebuttons() | |
} | |
firstBtn() { | |
this.vGrid.loading = true; | |
this.vGridConfig.remoteOffset = 0; | |
this.vGridConfig.remoteCall(); | |
} | |
nextBtn() { | |
this.vGrid.loading = true; | |
this.vGridConfig.remoteOffset = this.vGridConfig.remoteOffset + this.vGridConfig.remoteLimit; | |
this.vGridConfig.remoteCall(); | |
} | |
prevBtn() { | |
this.vGrid.loading = true; | |
this.vGridConfig.remoteOffset = this.vGridConfig.remoteOffset - this.vGridConfig.remoteLimit; | |
this.vGridConfig.remoteCall(); | |
} | |
lastBtn() { | |
this.vGrid.loading = true; | |
this.vGridConfig.remoteOffset = this.vGridConfig.remoteLength - this.vGridConfig.remoteLimit; | |
this.vGridConfig.remoteCall(); | |
} | |
setG(x){ | |
this.vGrid.loading = true; | |
this.vGridConfig.remoteOffset = (this["g"+x]-1) * this.vGridConfig.remoteLimit; | |
this.vGridConfig.remoteCall(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {HttpClient, json} from 'aurelia-fetch-client'; | |
//helper class to generate my reuests to the "dummy data server" (open shift) | |
//for anyone that want to create a own opensift server for same purpose can use this one: | |
//https://github.com/vegarringdal/v-grid-remote-dummy-data | |
export class RemoteData { | |
constructor(baseUrl, dataApi){ | |
this.http = new HttpClient(); | |
this.baseUrl = baseUrl; | |
this.dataApi = dataApi; | |
this.queryString = null; | |
this.orderbyString = null; | |
this.limit = null; | |
this.offset = null; | |
this.length = null; | |
this.configureHttp() | |
} | |
/* | |
configure http with base url | |
*/ | |
configureHttp(){ | |
this.http.configure(config => { | |
config | |
.withBaseUrl(this.baseUrl) | |
.withDefaults({ | |
credentials: 'same-origin' | |
}); | |
}); | |
} | |
/* | |
Get data from remote | |
*/ | |
getData(){ | |
return new Promise((resolve, reject)=>{ | |
var params = ''; | |
if(this.queryString){ | |
params = '?'+this.queryString | |
} | |
if(this.orderbyString){ | |
var op = params ? '&':'?'; | |
params = params + op + this.orderbyString; | |
} | |
if(this.limit){ | |
var op = params ? '&':'?'; | |
params = params + op + 'sqlLimit=' + this.limit; | |
} | |
if(this.offset){ | |
var op = params ? '&':'?'; | |
params = params + op + 'sqlOffset=' + this.offset; | |
} | |
console.log('request params:' + params); | |
var encodedString = params !== '' ? window.encodeURI(params):''; | |
this.http.fetch(this.dataApi + encodedString) | |
.then(response => response.json()) | |
.then(data => { | |
if(data.success = true){ | |
this.length = data.length; | |
resolve({col:data.result, length:data.length, limit:40}); | |
} else { | |
this.length = 0; | |
reject({error:data.error}); | |
} | |
}) | |
}) | |
} | |
/* | |
set limit | |
*/ | |
setLimit(x){ | |
this.limit = x || 40; | |
} | |
/* | |
set offset | |
*/ | |
setOffset(x){ | |
this.offset = x || 0; | |
} | |
/* | |
create orderby string | |
*/ | |
createOrderByString(orderByArray){ | |
if(orderByArray){ | |
var sortString = null; | |
orderByArray.forEach((param, index)=> { | |
if (index === 0) { | |
sortString = 'sqlOrderby=' | |
} else { | |
sortString = sortString + ',' | |
} | |
sortString = sortString + `${param.attribute} ${param.asc ? "asc" : "desc"}` | |
}); | |
this.orderbyString = sortString; | |
} else { | |
this.orderbyString = null; | |
} | |
} | |
/* | |
create query string | |
*/ | |
createQueryString(queryArray){ | |
if (queryArray) { | |
var queryString = null; | |
queryArray.forEach((param, index)=> { | |
if (index === 0) { | |
queryString = 'sqlQuery='; | |
} else { | |
queryString = queryString + ' and ' | |
} | |
switch (param.operator) { | |
case "=": //"equals" | |
queryString = queryString + `${param.attribute} = "${param.value}"`; | |
break; | |
case "*": //"contains" | |
queryString = queryString + `${param.attribute} LIKE "%${param.value}%"`; | |
break; | |
case "!=": //"not equal to" | |
queryString = queryString + `${param.attribute} IS NOT "${param.value}"`; | |
break; | |
case "<": //"less than" | |
queryString = queryString + `${param.attribute} ${param.operator} "${param.value}"`; | |
break; | |
case ">": //"greater than" | |
queryString = queryString + `${param.attribute} ${param.operator} "${param.value}"`; | |
break; | |
case "<=": //"less than or eq" | |
queryString = queryString + `${param.attribute} ${param.operator} "${param.value}"`; | |
break; | |
case ">=": //"greater than or eq" | |
queryString = queryString + `${param.attribute} ${param.operator} "${param.value}"`; | |
break; | |
case "*=": //"begins with" | |
queryString = queryString + `${param.attribute} LIKE "${param.value}%"`; | |
break; | |
case "=*": //"ends with" | |
queryString = queryString + `${param.attribute} LIKE "%${param.value}"`; | |
break; | |
case "!*": //"no contain" | |
queryString = queryString + `${param.attribute} IS NOT "%${param.value}%"`; | |
break; | |
} | |
}); | |
this.queryString = queryString; | |
} else { | |
this.queryString = null; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template bindable="entity"> | |
<form class="col-md-6"> | |
<div style="height:350px" class="well well-sm "> | |
<div class="form-group"> | |
<label for="name">Name</label> | |
<input class="form-control" id="name" value.bind="entity.name" disabled.bind="!entity.__vGridKey"> | |
</div> | |
<div class="form-group"> | |
<label for="Number">Number</label> | |
<input class="form-control" id="Number" value.bind="entity.number" disabled.bind="!entity.__vGridKey"> | |
</div> | |
<div class="form-group"> | |
<label for="Date">Date</label> | |
<input class="form-control" id="Date" value.bind="entity.date" disabled.bind="!entity.__vGridKey"> | |
</div> | |
<div class="checkbox"> | |
<label> | |
<input type="checkbox" checked.bind="entity.bool" disabled.bind="!entity.__vGridKey"> Bool | |
</label> | |
</div> | |
<img if.bind="entity.__vGridKey" src.bind="entity.images" alt="images" class="img-circle"> | |
</div> | |
</form> | |
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Created by vegar on 6/8/2016. | |
*/ | |
import moment from 'moment'; | |
export class DateFormatValueConverter { | |
toView(value) { | |
if(value){ | |
var x = moment(value).format('DD.MM.YYYY'); | |
return x; | |
} else { | |
return value; | |
} | |
} | |
fromView(value) { | |
if(value){ | |
return new Date(moment(value,'DD.MM.YYYY')._d); | |
} else { | |
return value; | |
} | |
} | |
} | |
import numeral from 'numeral'; | |
export class NumberFormatValueConverter { | |
toView(value) { | |
if (value) { | |
return numeral(value).format('($0,0.00)'); | |
} else { | |
return value; | |
} | |
} | |
fromView(value) { | |
if (value) { | |
return numeral().unformat(value); | |
} else { | |
return value; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment