aboutsummaryrefslogtreecommitdiffstats
path: root/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/knockout.simpleGrid.js
blob: f9fbafc23fe2bf3c09133a1136bd3f24564faf7d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// This is an example of one possible way to make a reusable component (or 'plugin'), consisting of:
//  * A view model class, which gives a way to configure the component and to interact with it (e.g., by exposing currentPageIndex as an observable, external code can change the page index)
//  * A custom binding (ko.bindingHandlers.simpleGrid in this example) so a developer can place instances of it into the DOM
//     - in this example, the custom binding works by rendering some predefined templates using the ko.jqueryTmplTemplateEngine template engine
//
// There are loads of ways this grid example could be expanded. For example,
//  * Letting the developer override the templates used to create the table header, table body, and page links div
//  * Adding a "sort by clicking column headers" option
//  * Creating some API to fetch table data using Ajax requests
//  ... etc



(function(factory) {
    if (typeof define === "function" && define.amd) {
        // AMD anonymous module
        define("knockout.simpleGrid",["jquery","knockout","utils","i18n"], factory);
    } else {
        // No module loader (plain <script> tag) - put directly in global namespace
        factory(window.ko, jQuery);
    }
})(function ($,ko,utils,i18n) {


  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;
      this.columns = configuration.columns;

      this.itemsOnCurrentPage = ko.computed(function () {
          var startIndex = this.pageSize * this.currentPageIndex();
          return this.data.slice(startIndex, startIndex + this.pageSize);
      }, this);

      this.maxPageIndex = ko.computed(function () {
          return Math.ceil(ko.utils.unwrapObservable(this.data).length / this.pageSize);
      }, this);
      this.i18n=function(key){
        return $.i18n.prop(key);
      };
      this.gridUpdateCallBack = configuration.gridUpdateCallBack;
      this.pageLinksUpdateCallBack = configuration.pageLinksUpdateCallBack;

    }
  };

  // Templates used to render the grid
  var templateEngine = new ko.jqueryTmplTemplateEngine();


  // The "simpleGrid" binding
  ko.bindingHandlers.simpleGrid = {
      // 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, allBindingsAccessor) {
        var viewModel = viewModelAccessor(), allBindings = allBindingsAccessor();

        // Empty the element
        while(element.firstChild) {
            ko.removeNode(element.firstChild);
        }

        // Allow the default templates to be overridden
        var gridTemplateName      = allBindings.simpleGridTemplate || "ko_usersGrid_grid",
            pageLinksTemplateName = allBindings.simpleGridPagerTemplate || "ko_simpleGrid_pageLinks";

        // Render the main grid
        var gridContainer = element.appendChild(document.createElement("DIV"));
        ko.renderTemplate(gridTemplateName, viewModel, { templateEngine: templateEngine }, gridContainer, "replaceNode")
            .subscribe(viewModel.gridUpdateCallBack?viewModel.gridUpdateCallBack:function(){});

        if (viewModel.gridUpdateCallBack) viewModel.gridUpdateCallBack();

        // Render the page links
        var pageLinksContainer = $("#"+allBindings.pageLinksId).get(0);
        var renderedTemplate = ko.renderTemplate(pageLinksTemplateName, viewModel, { templateEngine: templateEngine }, pageLinksContainer, "replaceNode");
        if (renderedTemplate.subscribe){
          renderedTemplate.subscribe(viewModel.pageLinksUpdateCallBack?viewModel.pageLinksUpdateCallBack:function(){});
        }
        if (viewModel.pageLinksUpdateCallBack) viewModel.pageLinksUpdateCallBack();
      }
  };
})