-
Notifications
You must be signed in to change notification settings - Fork 129
About Custom Templates
If defining columns just isn't giving you the level of flexibility you need, then it's probably time you override one of the default templates that KoGrid uses to render rows and headers.
KoGrid leverages the template engine that Knockout has been configured to use (usually its own native engine if you are unsure what I am talking about).
The best place to start is to simply override the default cell template that KoGrid uses when it renders rows.
In order to get started writing your own cell template, you need to know what data is being passed to your cell template:
$data : {
entity : ko.observable(), // this is the original item from your observableArray
cells: [], // an array of cells in order of your columns
cellMap: {}, // a map of cells by the column's 'field' name
rowIndex: number, // the number of the row in the grid
rowDisplayIndex: number, // if you are paging through data this stays in sync with your current page
selected: ko.observable() // boolean indicating if the grid row is selected
}
$data
ALSO now includes all of the properties of your entity (just pointers straight to those properties). So you can easily just do $data.firstName
when you want to access a property of your entity
Each cell in the $data.cells
or $data.cellMap
has the following properties:
cell : {
data: ko.observable(), // an observable that holds the value of your object's bound property
column: // the actual kg.Column class that your cell is bound to
row: // the actual kg.Row class that your cell belongs to
}
An often needed cell template is one that allows editing values in place in the grid:
<script type="text/html" id="editingCellTemplate">
<div data-bind="kgCell: { value: 'firstName' }">
<input type="text" data-bind="value: $data.entity().firstName"/>
</div>
</script>
Ok great, but what about the kgCell: { value: 'firstName' }
binding? This binding will ensure that your cell is aligned correctly in the row and that it is formatted like the other cells (margin, padding, width, etc...)
As of 1.0, cell templates also get 3 shortcut identifiers you can use to make your templates re-usable and easier to understand:
-
$cell
--> translates into{ value: '<your column's bound property>' }
-
$cellValue
--> translates into$data.<your column's bound property>
-
$cellClass
--> translates into thecellClass
that you have defined in your columnDef for this column
This means the template above could be re-written like:
<script type="text/html" id="editingCellTemplate">
<div data-bind="kgCell: $cell, attr: { class: '$cellClass' }">
<input type="text" data-bind="value: $cellValue"/>
</div>
</script>
These shortcut identifiers should be really handy for making re-usable templates all over your app!
Once you have defined the custom cell template, you can add it to your colDefs
like so:
colDefs: [{ field: 'firstName', displayName: 'First Name', cellTemplate: 'editingCellTemplate' }]
Row templates work very similarly to cell templates. An example row template would look like:
<div data-bind="kgRow: $data">
<div data-bind="kgCell: { value: 'firstName' }"></div>
<div data-bind="kgCell: { value: 'lastName' }"></div>
</div>
As before, you will need to use the custom kgRow
binding. This binding ensures the correct data is passed throughout the row, and that the row is correctly formatted/rendered in the grid.
Each <div>
for the cells can use the kgCell
binding. This binding is smart enough to figure out how to display the cell's correct data even if a text or value binding hasn't been coded out.
A special note - you cannot use $cell
and its friends in custom Row Templates. If you think about it, it makes sense - but just to clarify.