/**
* Copyright (c) 2014, Oracle and/or its affiliates.
* All rights reserved.
*/
/**
* @preserve Copyright 2013 jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
*/
/*jslint browser: true,devel:true*/
/**
* Implementation of PagingModel backed by an array of data. ArrayPagingDataSource
* provides a window into the array in both standard JavaScript array and Knockout observable array formats.
* @export
* @class oj.ArrayPagingDataSource
* @classdesc Implementation of PagingModel using array data
* @extends oj.DataSource
* @implements oj.PagingModel
* @param {Array} data
* @constructor
*/
oj.ArrayPagingDataSource = function(data)
{
this.data = data;
// Start at the beginning
this.current = 0;
this.Init();
// Default the page size to 10
this._setPageSize(10);
};
// Subclass from oj.DataSource
oj.Object.createSubclass(oj.ArrayPagingDataSource, oj.DataSource, "oj.ArrayPagingDataSource");
/**
* Initializes the instance.
* @export
*/
oj.ArrayPagingDataSource.prototype.Init = function()
{
oj.ArrayPagingDataSource.superclass.Init.call(this);
};
oj.ArrayPagingDataSource.prototype._getSize = function() {
if (!this._hasMore()) {
// Return a size representing only what's left if we'd go over the bounds
return this.totalSize() - this.current;
}
// Otherwise window size should match the page size
return this.currentPageSize;
};
oj.ArrayPagingDataSource.prototype._refreshDataWindow = function(options) {
options = options || {};
// Reinit the array
this.dataWindow = new Array(this._getSize());
// Copy from the source data
for (var i = 0; i < this.dataWindow.length; i++) {
this.dataWindow[i] = this.data[this.current + i];
}
// Update the observable array
this._refreshObservableDataWindow();
this._endIndex = this._startIndex + this.dataWindow.length - 1;
if (!options['silent'])
{
this.handleEvent("sync", {'data': this.dataWindow, 'startIndex': this.current});
}
};
oj.ArrayPagingDataSource.prototype._refreshObservableDataWindow = function() {
if (this.observableDataWindow !== undefined) {
// Manage the observable window array
this.observableDataWindow.removeAll();
for (var i = 0; i < this.dataWindow.length; i++) {
this.observableDataWindow.push(this.dataWindow[i]);
}
}
};
oj.ArrayPagingDataSource.prototype.handleEvent = function(eventType, event)
{
return oj.ArrayPagingDataSource.superclass.handleEvent.call(this, eventType, event);
};
/**
* @export
* Return the current set of data in the paging window
*
* @returns {Array} the current set of data in the paging window
*/
oj.ArrayPagingDataSource.prototype.getWindow = function() {
return this.dataWindow;
};
/**
* @export
* Get the observable array representing the current set of data in the paging window
*
* @returns {Object} an observable array representing the current data in the paging window
*/
oj.ArrayPagingDataSource.prototype.getWindowObservable = function() {
if (this.observableDataWindow === undefined) {
this.observableDataWindow = ko.observableArray();
this._refreshObservableDataWindow();
}
return this.observableDataWindow;
};
/**
* Get the current page
* @return {number} The current page
* @export
* @expose
* @memberof! oj.ArrayPagingDataSource
* @instance
*/
oj.ArrayPagingDataSource.prototype.getPage = function()
{
return this._page;
};
/**
* Set the current page
* @param {number} value The current page
* @param {Object=} options Options<p>
* pageSize: The page size.<p>
* @return {Promise} promise object triggering done when complete..
* @export
* @expose
* @memberof! oj.ArrayPagingDataSource
* @instance
*/
oj.ArrayPagingDataSource.prototype.setPage = function(value, options)
{
options = options || {};
value = parseInt(value, 10);
try
{
oj.ArrayPagingDataSource.superclass.handleEvent.call(this, oj.PagingModel.EventType['BEFOREPAGE'], {'page' : value, 'previousPage' : this._page});
}
catch (err)
{
return Promise.reject(null);
}
this.pageSize = options['pageSize'] != null ? options['pageSize'] : this.pageSize;
options['startIndex'] = value * this.pageSize;
var previousPage = this._page;
this._page = value;
this._startIndex = options['startIndex'];
var self = this;
return new Promise(function(resolve, reject)
{
self._fetchInternal(options).then(function(result)
{
oj.ArrayPagingDataSource.superclass.handleEvent.call(self, oj.PagingModel.EventType['PAGE'], {'page' : self._page, 'previousPage' : previousPage});
resolve(null);
}, function (error)
{
// restore old page
self._page = previousPage;
self._startIndex = self._page * self.pageSize;
reject(null);
});
});
};
/**
* Get the current page start index
* @return {number} The current page start index
* @export
* @expose
* @memberof! oj.ArrayPagingDataSource
* @instance
*/
oj.ArrayPagingDataSource.prototype.getStartItemIndex = function()
{
return this._startIndex;
};
/**
* Get the current page end index
* @return {number} The current page end index
* @export
* @expose
* @memberof! oj.ArrayPagingDataSource
* @instance
*/
oj.ArrayPagingDataSource.prototype.getEndItemIndex = function()
{
return this._endIndex;
};
/**
* Get the page count
* @return {number} The total number of pages
* @export
* @expose
* @memberof! oj.ArrayPagingDataSource
* @instance
*/
oj.ArrayPagingDataSource.prototype.getPageCount = function()
{
var totalSize = this.totalSize();
return totalSize == -1 ? -1 : Math.ceil(totalSize / this.pageSize);
};
/**
* Fetch the row data.
* @param {Object=} options Options to control fetch
* @param {number} options.startIndex The index at which to start fetching records.
* @param {boolean} options.silent If set, do not fire a sync event.
* @return {Promise} Promise object resolves to a compound object which contains an array of row data objects and the startIndex triggering done when complete.<p>
* The structure of the resolved compound object is:<p>
* <table>
* <tbody>
* <tr><td><b>data</b></td><td>An array of raw row data</td></tr>
* <tr><td><b>startIndex</b></td><td>The startIndex for the returned set of rows</td></tr>
* </tbody>
* </table>
* @export
* @expose
* @memberof! oj.ArrayPagingDataSource
* @instance
*/
oj.ArrayPagingDataSource.prototype.fetch = function(options)
{
var opts = options || {};
if (opts['pageSize'] !== undefined && opts['startIndex'] !== undefined) {
if (!this._hasMore())
{
// At the limit
return Promise.resolve();
}
this.currentPageSize = opts['startIndex'] + opts['pageSize'];
}
this._refreshDataWindow(null);
return Promise.resolve();
};
/**
* Fetch the row data.
* @private
*/
oj.ArrayPagingDataSource.prototype._fetchInternal = function(options)
{
// No fetching, but set up window according to options
var opts = options || {};
if (opts['startIndex'] !== undefined) {
this.current = opts['startIndex'];
}
if (opts['pageSize'] !== undefined) {
this.pageSize = opts['pageSize'];
this.currentPageSize = opts['pageSize'];
}
this._refreshDataWindow(options);
return Promise.resolve({'data': this.dataWindow, 'startIndex': this.current});
};
/**
* Return whether there is more data which can be fetched.
* @private
*/
oj.ArrayPagingDataSource.prototype._hasMore = function()
{
return this.current + this.currentPageSize < this.totalSize();
};
/**
* Set or change the number of models in a page
*
* @private
*/
oj.ArrayPagingDataSource.prototype._setPageSize = function(n)
{
this.pageSize = n;
this.currentPageSize = n;
this._refreshDataWindow(null);
};
/**
* Return the total size of data available, including server side if not local.
* @returns {number} total size of data
* @expose
* @memberof! oj.ArrayPagingDataSource
* @instance
*/
oj.ArrayPagingDataSource.prototype.totalSize = function()
{
return this.data.length;
};
Source: src/main/javascript/oracle/oj/ojpagingcontrol-model/ArrayPagingDataSource.js
Oracle® JavaScript Extension Toolkit (JET)
1.1.2
E65298-01