|
- (function ($) {
- /***
- * A sample AJAX data store implementation.
- * Right now, it's hooked up to load Hackernews stories, but can
- * easily be extended to support any JSONP-compatible backend that accepts paging parameters.
- */
- function RemoteModel() {
- // private
- var PAGESIZE = 50;
- var data = {length: 0};
- var searchstr = "";
- var sortcol = null;
- var sortdir = 1;
- var h_request = null;
- var req = null; // ajax request
-
- // events
- var onDataLoading = new Slick.Event();
- var onDataLoaded = new Slick.Event();
-
-
- function init() {
- }
-
-
- function isDataLoaded(from, to) {
- for (var i = from; i <= to; i++) {
- if (data[i] == undefined || data[i] == null) {
- return false;
- }
- }
-
- return true;
- }
-
-
- function clear() {
- for (var key in data) {
- delete data[key];
- }
- data.length = 0;
- }
-
-
- function ensureData(from, to) {
- if (req) {
- req.abort();
- for (var i = req.fromPage; i <= req.toPage; i++)
- data[i * PAGESIZE] = undefined;
- }
-
- if (from < 0) {
- from = 0;
- }
-
- if (data.length > 0) {
- to = Math.min(to, data.length - 1);
- }
-
- var fromPage = Math.floor(from / PAGESIZE);
- var toPage = Math.floor(to / PAGESIZE);
-
- while (data[fromPage * PAGESIZE] !== undefined && fromPage < toPage)
- fromPage++;
-
- while (data[toPage * PAGESIZE] !== undefined && fromPage < toPage)
- toPage--;
-
- if (fromPage > toPage || ((fromPage == toPage) && data[fromPage * PAGESIZE] !== undefined)) {
- // TODO: look-ahead
- onDataLoaded.notify({from: from, to: to});
- return;
- }
-
- 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);
-
- if (sortcol != null) {
- url += ("&sortby=" + sortcol + ((sortdir > 0) ? "+asc" : "+desc"));
- }
-
- if (h_request != null) {
- clearTimeout(h_request);
- }
-
- h_request = setTimeout(function () {
- for (var i = fromPage; i <= toPage; i++)
- data[i * PAGESIZE] = null; // null indicates a 'requested but not available yet'
-
- onDataLoading.notify({from: from, to: to});
-
- req = $.jsonp({
- url: url,
- callbackParameter: "callback",
- cache: true,
- success: onSuccess,
- error: function () {
- onError(fromPage, toPage)
- }
- });
- req.fromPage = fromPage;
- req.toPage = toPage;
- }, 50);
- }
-
-
- function onError(fromPage, toPage) {
- alert("error loading pages " + fromPage + " to " + toPage);
- }
-
- function onSuccess(resp) {
- var from = resp.request.start, to = from + resp.results.length;
- data.length = Math.min(parseInt(resp.hits),1000); // limitation of the API
-
- for (var i = 0; i < resp.results.length; i++) {
- var item = resp.results[i].item;
-
- // Old IE versions can't parse ISO dates, so change to universally-supported format.
- item.create_ts = item.create_ts.replace(/^(\d+)-(\d+)-(\d+)T(\d+:\d+:\d+)Z$/, "$2/$3/$1 $4 UTC");
- item.create_ts = new Date(item.create_ts);
-
- data[from + i] = item;
- data[from + i].index = from + i;
- }
-
- req = null;
-
- onDataLoaded.notify({from: from, to: to});
- }
-
-
- function reloadData(from, to) {
- for (var i = from; i <= to; i++)
- delete data[i];
-
- ensureData(from, to);
- }
-
-
- function setSort(column, dir) {
- sortcol = column;
- sortdir = dir;
- clear();
- }
-
- function setSearch(str) {
- searchstr = str;
- clear();
- }
-
-
- init();
-
- return {
- // properties
- "data": data,
-
- // methods
- "clear": clear,
- "isDataLoaded": isDataLoaded,
- "ensureData": ensureData,
- "reloadData": reloadData,
- "setSort": setSort,
- "setSearch": setSearch,
-
- // events
- "onDataLoading": onDataLoading,
- "onDataLoaded": onDataLoaded
- };
- }
-
- // Slick.Data.RemoteModel
- $.extend(true, window, { Slick: { Data: { RemoteModel: RemoteModel }}});
- })(jQuery);
|