Last active
May 13, 2020 14:50
-
-
Save rogersillito/1e2e6ba696b81c30f0471229814568aa to your computer and use it in GitHub Desktop.
A version of the knockout.simpleGrid binding that works in amd (e.g. requirejs). It uses DOM append instead of document.write().
This file contains hidden or 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
define(['knockout'], function(ko) { | |
'use strict'; | |
// adapted from: https://github.com/knockout/knockout/blob/gh-pages/examples/resources/knockout.simpleGrid.3.0.js | |
// Private function | |
function getColumnsForScaffolding(data) { | |
if ((typeof data.length !== 'number') || data.length === 0) { | |
return []; | |
} | |
var columns = []; | |
for (var propertyName in data[0]) { | |
columns.push({ headerText: propertyName, rowText: propertyName }); | |
} | |
return columns; | |
} | |
ko.simpleGrid = { | |
// Defines a view model class you can use to populate a grid | |
viewModel: function (configuration) { | |
this.data = configuration.data; | |
this.currentPageIndex = ko.observable(0); | |
this.pageSize = configuration.pageSize || 5; | |
// If you don't specify columns configuration, we'll use scaffolding | |
this.columns = configuration.columns || getColumnsForScaffolding(ko.unwrap(this.data)); | |
this.itemsOnCurrentPage = ko.computed(function () { | |
var startIndex = this.pageSize * this.currentPageIndex(); | |
return ko.unwrap(this.data).slice(startIndex, startIndex + this.pageSize); | |
}, this); | |
this.maxPageIndex = ko.computed(function () { | |
return Math.ceil(ko.unwrap(this.data).length / this.pageSize) - 1; | |
}, this); | |
} | |
}; | |
// Templates used to render the grid | |
var templateEngine = new ko.nativeTemplateEngine(); | |
templateEngine.addTemplate = function(templateName, templateMarkup) { | |
var scriptTag = document.createElement('script'); | |
scriptTag.type = 'text/html'; | |
scriptTag.id = templateName; | |
scriptTag.text = templateMarkup; | |
document.getElementsByTagName('body')[0].appendChild(scriptTag); | |
}; | |
templateEngine.addTemplate('ko_simpleGrid_grid', | |
'<table class="ko-grid" cellspacing="0">' + | |
'<thead>' + | |
'<tr data-bind="foreach: columns">' + | |
'<th data-bind="text: headerText"></th>' + | |
'</tr>' + | |
'</thead>' + | |
'<tbody data-bind="foreach: itemsOnCurrentPage">' + | |
'<tr data-bind="foreach: $parent.columns">' + | |
'<td data-bind="text: typeof rowText == \'function\' ? rowText($parent) : $parent[rowText]"></td>' + | |
'</tr>' + | |
'</tbody>' + | |
'</table>'); | |
templateEngine.addTemplate('ko_simpleGrid_pageLinks', | |
'<div class="ko-grid-pageLinks">' + | |
'<span>Page:</span>' + | |
'<!-- ko foreach: ko.utils.range(0, maxPageIndex) -->' + | |
'<a href="#" data-bind="text: $data + 1, ' + | |
'click: function() { $root.currentPageIndex($data) }, ' + | |
'css: { selected: $data == $root.currentPageIndex() }">' + | |
'</a>' + | |
'<!-- /ko -->' + | |
'</div>'); | |
// The "simpleGrid" binding | |
ko.bindingHandlers.simpleGrid = { | |
init: function() { | |
return { 'controlsDescendantBindings': true }; | |
}, | |
// This method is called to initialize the node, | |
// and will also be called again if you change what the grid is bound to | |
update: function (element, viewModelAccessor, allBindings) { | |
var viewModel = viewModelAccessor(); | |
// Empty the element | |
while(element.firstChild) | |
ko.removeNode(element.firstChild); | |
// Allow the default templates to be overridden | |
var gridTemplateName = allBindings.get('simpleGridTemplate') || 'ko_simpleGrid_grid', | |
pageLinksTemplateName = allBindings.get('simpleGridPagerTemplate') || 'ko_simpleGrid_pageLinks'; | |
// Render the main grid | |
var gridContainer = element.appendChild(document.createElement('DIV')); | |
ko.renderTemplate(gridTemplateName, viewModel, { templateEngine: templateEngine }, | |
gridContainer, 'replaceNode'); | |
// Render the page links | |
var pageLinksContainer = element.appendChild(document.createElement('DIV')); | |
ko.renderTemplate(pageLinksTemplateName, viewModel, { templateEngine: templateEngine }, | |
pageLinksContainer, 'replaceNode'); | |
} | |
}; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment