Skip to content

Instantly share code, notes, and snippets.

@kfranqueiro
Created March 15, 2013 04:22
Show Gist options
  • Save kfranqueiro/5167465 to your computer and use it in GitHub Desktop.
Save kfranqueiro/5167465 to your computer and use it in GitHub Desktop.
Example of extending dgrid's `_StoreMixin` to present a list or grid progressively, one page at a time.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="../../dojo/resources/dojo.css">
<link rel="stylesheet" href="../../dgrid/css/skins/claro.css">
<style>
#list {
border: none;
height: auto;
}
#list .dgrid-scroller {
position: relative;
overflow-y: hidden;
}
#list .dgrid-header-scroll {
display: none;
}
#list .dgrid-header {
right: 0;
}
</style>
</head>
<body class="claro">
<div id="list"></div>
<div>
<button id="showMore">Show More</button>
</div>
<script src="../../dojo/dojo.js" data-dojo-config="async: true"></script>
<script>
require([
"dojo/_base/declare",
"dojo/when",
"dojo/store/Memory",
"dgrid/List",
"dgrid/_StoreMixin",
"put-selector/put",
"dojo/on" // For test only
], function (declare, when, Memory, List, _StoreMixin, put, on) {
var MoreMixin = declare(_StoreMixin, {
// summary:
// Mixin extending dgrid/_StoreMixin, providing a variant of
// paging functionality involving a `showMore` method which can
// be called to incrementally display additional rows.
// initialRows: Number
// Number of items to request for initial display.
initialRows: 10,
// rowsPerPage: Number
// Number of additional items to request on each call to showMore.
rowsPerPage: 10,
startup: function () {
if (this._started) {
return;
}
this.inherited(arguments);
// Call showMore for the first time to load the first page
this.showMore();
},
refresh: function () {
var loadingMore = this._loadingMore;
this.inherited(arguments);
delete this._total;
delete this._loadedRows;
if (loadingMore && loadingMore.cancel) {
// Async query is in progress; cancel it and remove the flag.
loadingMore.cancel();
delete this._loadingMore;
}
},
destroy: function () {
var loadingMore = this._loadingMore;
this.inherited(arguments);
// Cancel any pending async query upon destruction
if (loadingMore && loadingMore.cancel) {
loadingMore.cancel();
}
},
showMore: function () {
// summary:
// Requests the next set of items from the store and adds them to
// the list/grid.
var self = this,
loadedRows = this._loadedRows || 0,
options,
results;
if (this._loadingMore || (typeof loadedRows === "number" && loadedRows === this._total)) {
// Either we're already loading more, or there's no more to load
return;
}
// Build options for initial query.
// get("queryOptions") always returns a delegated object,
// so it's safe to add to it without having side effects
options = this.get("queryOptions");
// On the first query (when loadedRows is undefined),
// set start to 0 and set count to initialRows, not rowsPerPage
options.start = loadedRows;
options.count = this[loadedRows ? "rowsPerPage" : "initialRows"];
// Query for results, and store into _loadingMore to indicate that
// a query is under way - only needed/useful for async stores;
// will be immediately unset for synchronous ones
this._loadingMore = results = this.store.query(this.query, options);
// Store total count and the number of rows loaded, for next time
when(results.total, function (total) {
self._total = total;
self._loadedRows = Math.min(loadedRows + options.count, total);
});
// Return the QueryResults, particularly useful for if anything
// should happen after async queries resolve
// (e.g. hiding a loading indicator)
return when(this.renderArray(results), function () {
self._loadingMore = false;
return results;
});
}
});
var data = [],
store,
list,
i;
for (i = 1; i <= 35; i++) {
data.push({ id: i });
}
store = new Memory({ data: data });
list = new (declare([List, MoreMixin]))({
store: store,
renderRow: function (item) {
return put("div", "Item " + item.id);
}
}, "list");
on(document.getElementById("showMore"), "click", function () {
list.showMore();
});
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment