slickgrid added to third-party
[myslice.git] / third-party / slickgrid-2.1 / slick.remotemodel.js
1 (function ($) {
2   /***
3    * A sample AJAX data store implementation.
4    * Right now, it's hooked up to load Hackernews stories, but can
5    * easily be extended to support any JSONP-compatible backend that accepts paging parameters.
6    */
7   function RemoteModel() {
8     // private
9     var PAGESIZE = 50;
10     var data = {length: 0};
11     var searchstr = "";
12     var sortcol = null;
13     var sortdir = 1;
14     var h_request = null;
15     var req = null; // ajax request
16
17     // events
18     var onDataLoading = new Slick.Event();
19     var onDataLoaded = new Slick.Event();
20
21
22     function init() {
23     }
24
25
26     function isDataLoaded(from, to) {
27       for (var i = from; i <= to; i++) {
28         if (data[i] == undefined || data[i] == null) {
29           return false;
30         }
31       }
32
33       return true;
34     }
35
36
37     function clear() {
38       for (var key in data) {
39         delete data[key];
40       }
41       data.length = 0;
42     }
43
44
45     function ensureData(from, to) {
46       if (req) {
47         req.abort();
48         for (var i = req.fromPage; i <= req.toPage; i++)
49           data[i * PAGESIZE] = undefined;
50       }
51
52       if (from < 0) {
53         from = 0;
54       }
55
56       if (data.length > 0) {
57         to = Math.min(to, data.length - 1);
58       }
59
60       var fromPage = Math.floor(from / PAGESIZE);
61       var toPage = Math.floor(to / PAGESIZE);
62
63       while (data[fromPage * PAGESIZE] !== undefined && fromPage < toPage)
64         fromPage++;
65
66       while (data[toPage * PAGESIZE] !== undefined && fromPage < toPage)
67         toPage--;
68
69       if (fromPage > toPage || ((fromPage == toPage) && data[fromPage * PAGESIZE] !== undefined)) {
70         // TODO:  look-ahead
71         onDataLoaded.notify({from: from, to: to});
72         return;
73       }
74
75       var url = "http://api.thriftdb.com/api.hnsearch.com/items/_search?filter[fields][type][]=submission&q=" + searchstr + "&start=" + (fromPage * PAGESIZE) + "&limit=" + (((toPage - fromPage) * PAGESIZE) + PAGESIZE);
76
77       if (sortcol != null) {
78           url += ("&sortby=" + sortcol + ((sortdir > 0) ? "+asc" : "+desc"));
79       }
80
81       if (h_request != null) {
82         clearTimeout(h_request);
83       }
84
85       h_request = setTimeout(function () {
86         for (var i = fromPage; i <= toPage; i++)
87           data[i * PAGESIZE] = null; // null indicates a 'requested but not available yet'
88
89         onDataLoading.notify({from: from, to: to});
90
91         req = $.jsonp({
92           url: url,
93           callbackParameter: "callback",
94           cache: true,
95           success: onSuccess,
96           error: function () {
97             onError(fromPage, toPage)
98           }
99         });
100         req.fromPage = fromPage;
101         req.toPage = toPage;
102       }, 50);
103     }
104
105
106     function onError(fromPage, toPage) {
107       alert("error loading pages " + fromPage + " to " + toPage);
108     }
109
110     function onSuccess(resp) {
111       var from = resp.request.start, to = from + resp.results.length;
112       data.length = Math.min(parseInt(resp.hits),1000); // limitation of the API
113
114       for (var i = 0; i < resp.results.length; i++) {
115         var item = resp.results[i].item;
116
117         // Old IE versions can't parse ISO dates, so change to universally-supported format.
118         item.create_ts = item.create_ts.replace(/^(\d+)-(\d+)-(\d+)T(\d+:\d+:\d+)Z$/, "$2/$3/$1 $4 UTC"); 
119         item.create_ts = new Date(item.create_ts);
120
121         data[from + i] = item;
122         data[from + i].index = from + i;
123       }
124
125       req = null;
126
127       onDataLoaded.notify({from: from, to: to});
128     }
129
130
131     function reloadData(from, to) {
132       for (var i = from; i <= to; i++)
133         delete data[i];
134
135       ensureData(from, to);
136     }
137
138
139     function setSort(column, dir) {
140       sortcol = column;
141       sortdir = dir;
142       clear();
143     }
144
145     function setSearch(str) {
146       searchstr = str;
147       clear();
148     }
149
150
151     init();
152
153     return {
154       // properties
155       "data": data,
156
157       // methods
158       "clear": clear,
159       "isDataLoaded": isDataLoaded,
160       "ensureData": ensureData,
161       "reloadData": reloadData,
162       "setSort": setSort,
163       "setSearch": setSearch,
164
165       // events
166       "onDataLoading": onDataLoading,
167       "onDataLoaded": onDataLoaded
168     };
169   }
170
171   // Slick.Data.RemoteModel
172   $.extend(true, window, { Slick: { Data: { RemoteModel: RemoteModel }}});
173 })(jQuery);