Skip to content

Instantly share code, notes, and snippets.

@valichek
Forked from charlespockert/compiler.ts
Last active September 17, 2015 21:54
Show Gist options
  • Save valichek/fdb7e2a3346ec1a0d437 to your computer and use it in GitHub Desktop.
Save valichek/fdb7e2a3346ec1a0d437 to your computer and use it in GitHub Desktop.
Kendo grid with Aurelia
import {inject, ViewCompiler, ViewResources, Container} from 'aurelia-framework';
/**
* Compiler service
*
* compiles an HTML element with aurelia
*/
@inject(ViewCompiler, ViewResources, Container)
export class Compiler {
viewCompiler: any;
resources: any;
container: any;
constructor(viewCompiler, resources, container) {
this.viewCompiler = viewCompiler;
this.resources = resources;
this.container = container;
}
compile(templateOrFragment, ctx = null, viewSlot = null):any {
if (typeof templateOrFragment === "string") {
var temp = document.createElement('span');
temp.innerHTML = templateOrFragment;
templateOrFragment = temp;
}
var view = this.viewCompiler.compile(templateOrFragment, this.resources).create(this.container, ctx);
return view;
}
}
<kendo-grid refresh-flag.bind="refresh" read.call="getData($event)" auto-bind.bind="false" pageable.bind="true" sortable.bind="true">
<kendo-grid-col title="Name" field="Name"></kendo-grid-col>
<kendo-grid-col title="Id" field="Id">
<kendo-template>This is a template ${ $item.Id }</kendo-template>
</kendo-grid-col>
</kendo-grid>
export class Example {
getData(options) {
return {
data: [{ name: "hello", Id: 1}, { name:"world", Id: 2}],
total: 2
}
}
<template>
<div>
<content></content>
</div>
</template>
import {inject, processContent, customAttribute, bindable, sync, ViewCompiler, ViewSlot, Container, ViewResources, TargetInstruction} from 'aurelia-framework';
import { EventAggregator } from 'aurelia-event-aggregator';
import {Compiler} from '../compiler';
import * as kendoUi from 'kendo-ui';
import 'kendo-ui/styles/kendo.common-bootstrap.min.css!';
import 'kendo-ui/styles/kendo.bootstrap.min.css!';
@processContent((compiler, resources, element, instruction) => {
parseUserTemplate(element, resources, instruction);
return true;
})
@inject(Element, Compiler, EventAggregator, TargetInstruction)
export class KendoGrid {
element: HTMLElement;
widget: any;
columns: any[] = null;
@bindable selectable: boolean;
@bindable filterable: boolean;
@bindable pageable: boolean;
@bindable sortable: boolean;
@bindable pageSize: number = 10;
@bindable page: number = 1;
@bindable selectedItem: any;
@bindable selectedItems: any[];
@bindable autoBind: boolean;
@bindable refreshFlag: any;
@bindable read: any;
aggregator: EventAggregator;
compiler: Compiler;
dataSource: kendo.data.DataSource;
constructor(element, compiler, aggregator, targetInstruction) {
this.element = element;
this.compiler = compiler;
this.aggregator = aggregator;
kendo.culture("en-GB");
this.columns = targetInstruction.behaviorInstructions[0].kendoGridColumns;
}
bind(ctx) {
this["$parent"] = ctx;
// Post parse the templates in "columns"
this.columns.forEach(c => {
if (c.hasOwnProperty("template")) {
// If there's no template string it must be the first time we are visiting the columns
// Push the template string into a new property and wrap the string with a func to compile the template
if (!c.hasOwnProperty("templateString"))
c["templateString"] = c["template"];
c["template"] = (dataItem) => {
try {
var cellctx = { "$item": dataItem, "$parent": ctx };
return this.compiler.compile(c["templateString"], cellctx).fragment.innerHTML;
}
catch (ex) {
console.error(ex);
}
}
}
});
}
refreshFlagChanged() {
this.refresh();
}
selectedItemChanged() {
}
attached() {
// Create the datasource
this.dataSource = new kendoUi.data.DataSource({
serverFiltering: true,
serverSorting: true,
serverPaging: true,
page: this.page,
pageSize: this.pageSize,
pageable: this.pageable,
schema: {
data: "data",
total: "total"
},
transport: {
read: (options) => {
// Check if we have a grid read setup
if (!this.read) {
console.warn("No read method provided to Kendo Grid");
options.error([]);
return;
}
// User can transform the kendo options
this.read(options.data)
.then(e => {
return options.success(e);
})
.catch(e => {
return options.error([]);
});
}
}
});
// Create the widget
$(this.element).kendoGrid({
dataSource: this.dataSource,
columns: this.columns,
filterable: this.filterable,
pageable: this.pageable,
selectable: this.selectable,
sortable: this.sortable,
autoBind: this.autoBind,
// Row selection
change: (e) => {
var selectedRows = this.widget.select();
var selectedItems = Array.prototype.slice.call(selectedRows).map(row => {
return this.widget.dataItem(row);
});
this.selectedItem = selectedItems[0];
this.selectedItems = selectedItems;
}
});
this.widget = $(this.element).data("kendoGrid");
}
refresh() {
if (this.widget)
this.widget.dataSource.read();
}
detached() {
$(this.element).data("kendoGrid").destroy();
}
}
function parseUserTemplate(element, resources, instruction) {
// Pull all of the attributes off the kendo-grid-col element
var columns = Array.prototype.slice.call(element.querySelectorAll("kendo-grid-col"));
var colSpecs = columns.map(col => {
var obj = {};
for (var i = col.attributes.length - 1; i >= 0; i--) {
var attr = col.attributes.item(i);
obj[attr.name] = attr.value;
}
parseCellTemplate(col, obj);
return obj;
});
// Remove any inner HTML from the element - we don't want it in the DOM
element.innerHTML = "";
instruction.kendoGridColumns = colSpecs;
}
function parseCellTemplate(element, spec) {
var template = element.querySelector("kendo-template");
if (template)
spec.template = template.innerHTML;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment