nativescript-sectioned-list-view
Version:
A native script listview plugin that can display sections
403 lines (402 loc) • 17.3 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var common = require("./list-view-common");
var utils = require("utils/utils");
var view = require("ui/core/view");
var label_1 = require("ui/label");
var formatted_string_1 = require("text/formatted-string");
var span_1 = require("text/span");
var enums_1 = require("ui/enums");
var CELLIDENTIFIER = "cell";
var HEADERIDENTIFIER = "header";
var ITEMLOADING = common.SectionedListView.itemLoadingEvent;
var HEADERLOADING = common.SectionedListView.headerLoadingEvent;
var LOADMOREITEMS = common.SectionedListView.loadMoreItemsEvent;
var ITEMTAP = common.SectionedListView.itemTapEvent;
var DEFAULT_HEIGHT = 44;
global.moduleMerge(common, exports);
var infinity = utils.layout.makeMeasureSpec(0, utils.layout.UNSPECIFIED);
var SectionedListViewCell = (function (_super) {
__extends(SectionedListViewCell, _super);
function SectionedListViewCell() {
_super.apply(this, arguments);
}
SectionedListViewCell.prototype.willMoveToSuperview = function (newSuperview) {
var parent = (this.view ? this.view.parent : null);
if (parent && !newSuperview) {
parent._removeContainer(this);
}
};
Object.defineProperty(SectionedListViewCell.prototype, "view", {
get: function () {
return this.owner ? this.owner.get() : null;
},
enumerable: true,
configurable: true
});
return SectionedListViewCell;
}(UITableViewCell));
var SectionedListViewHeaderView = (function (_super) {
__extends(SectionedListViewHeaderView, _super);
function SectionedListViewHeaderView() {
_super.apply(this, arguments);
}
SectionedListViewHeaderView.prototype.willMoveToSuperview = function (newSuperview) {
var parent = (this.view ? this.view.parent : null);
if (parent && !newSuperview) {
parent._removeContainer(this);
}
};
Object.defineProperty(SectionedListViewHeaderView.prototype, "view", {
get: function () {
return this.owner ? this.owner.get() : null;
},
enumerable: true,
configurable: true
});
return SectionedListViewHeaderView;
}(UITableViewHeaderFooterView));
function notifyForItemAtIndex(listView, cell, view, eventName, indexPath) {
var args = { eventName: eventName, object: listView, row: indexPath.row, section: indexPath.section, view: view, ios: cell, android: undefined };
listView.notify(args);
return args;
}
function notifyForHeaderAtSection(listView, header, view, eventName, section) {
var args = { eventName: eventName, object: listView, row: 0, section: section, view: view, ios: header, android: undefined };
listView.notify(args);
return args;
}
var SectionedDataSource = (function (_super) {
__extends(SectionedDataSource, _super);
function SectionedDataSource() {
_super.apply(this, arguments);
}
SectionedDataSource.initWithOwner = function (owner) {
var dataSource = SectionedDataSource.new();
dataSource._owner = owner;
return dataSource;
};
SectionedDataSource.prototype.numberOfSectionsInTableView = function (tableView) {
var owner = this._owner.get();
if (owner && owner.items && owner.items.getNoOfSections) {
return (owner.items).getNoOfSections();
}
return 1;
};
SectionedDataSource.prototype.tableViewNumberOfRowsInSection = function (tableView, section) {
var owner = this._owner.get();
if (owner && owner.items && owner.items.getNoOfItemsInSection) {
return (owner.items).getNoOfItemsInSection(section);
}
return (owner && owner.items) ? owner.items.length : 0;
};
SectionedDataSource.prototype.tableViewCellForRowAtIndexPath = function (tableView, indexPath) {
var cell = (tableView.dequeueReusableCellWithIdentifier(CELLIDENTIFIER) || SectionedListViewCell.new());
var owner = this._owner.get();
if (owner) {
owner._prepareCell(cell, indexPath);
var cellView = cell.view;
if (cellView) {
var width = utils.layout.getMeasureSpecSize(owner.widthMeasureSpec);
var rowHeight = owner._nativeView.rowHeight;
var cellHeight = rowHeight > 0 ? rowHeight : owner.getHeight(indexPath.row);
view.View.layoutChild(owner, cellView, 0, 0, width, cellHeight);
}
}
return cell;
};
SectionedDataSource.ObjCProtocols = [UITableViewDataSource];
return SectionedDataSource;
}(NSObject));
var SectionedTableViewDelegateImpl = (function (_super) {
__extends(SectionedTableViewDelegateImpl, _super);
function SectionedTableViewDelegateImpl() {
_super.apply(this, arguments);
}
SectionedTableViewDelegateImpl.initWithOwner = function (owner) {
var delegate = SectionedTableViewDelegateImpl.new();
delegate._owner = owner;
return delegate;
};
SectionedTableViewDelegateImpl.prototype.tableViewWillDisplayCellForRowAtIndexPath = function (tableView, cell, indexPath) {
var owner = this._owner.get();
console.log('Will display cell for row at indexpath');
if (owner && (indexPath.section == owner.items.getNoOfSections() - 1) && (indexPath.row === owner.items.getNoOfItemsInSection(indexPath.section) - 1)) {
owner.notify({ eventName: LOADMOREITEMS, object: owner });
}
};
SectionedTableViewDelegateImpl.prototype.tableViewWillSelectRowAtIndexPath = function (tableView, indexPath) {
var cell = tableView.cellForRowAtIndexPath(indexPath);
var owner = this._owner.get();
if (owner) {
notifyForItemAtIndex(owner, cell, cell.view, ITEMTAP, indexPath);
}
return indexPath;
};
SectionedTableViewDelegateImpl.prototype.tableViewDidSelectRowAtIndexPath = function (tableView, indexPath) {
tableView.deselectRowAtIndexPathAnimated(indexPath, true);
return indexPath;
};
SectionedTableViewDelegateImpl.prototype.tableViewHeightForRowAtIndexPath = function (tableView, indexPath) {
var owner = this._owner.get();
if (!owner) {
return 44;
}
var height = undefined;
if (utils.ios.MajorVersion >= 8) {
height = owner.getHeight(indexPath.row);
}
if (utils.ios.MajorVersion < 8 || height === undefined) {
var cell = this._measureCell;
if (!cell) {
this._measureCell = tableView.dequeueReusableCellWithIdentifier(CELLIDENTIFIER) || SectionedListViewCell.new();
cell = this._measureCell;
}
height = owner._prepareCell(cell, indexPath);
}
return height;
};
SectionedTableViewDelegateImpl.ObjCProtocols = [UITableViewDelegate];
return SectionedTableViewDelegateImpl;
}(NSObject));
var SectionedUITableViewRowHeightDelegateImpl = (function (_super) {
__extends(SectionedUITableViewRowHeightDelegateImpl, _super);
function SectionedUITableViewRowHeightDelegateImpl() {
_super.apply(this, arguments);
}
SectionedUITableViewRowHeightDelegateImpl.initWithOwner = function (owner) {
var delegate = SectionedUITableViewRowHeightDelegateImpl.new();
delegate._owner = owner;
return delegate;
};
SectionedUITableViewRowHeightDelegateImpl.prototype.tableViewWillDisplayCellForRowAtIndexPath = function (tableView, cell, indexPath) {
var owner = this._owner.get();
if (owner && (indexPath.section == owner.items.getNoOfSections() - 1) && (indexPath.row === owner.items.getNoOfItemsInSection(indexPath.section) - 1)) {
owner.notify({ eventName: LOADMOREITEMS, object: owner });
}
};
SectionedUITableViewRowHeightDelegateImpl.prototype.tableViewWillSelectRowAtIndexPath = function (tableView, indexPath) {
var cell = tableView.cellForRowAtIndexPath(indexPath);
var owner = this._owner.get();
if (owner) {
notifyForItemAtIndex(owner, cell, cell.view, ITEMTAP, indexPath);
}
return indexPath;
};
SectionedUITableViewRowHeightDelegateImpl.prototype.tableViewHeightForRowAtIndexPath = function (tableView, indexPath) {
var owner = this._owner.get();
if (!owner) {
return DEFAULT_HEIGHT;
}
return owner.rowHeight;
};
SectionedUITableViewRowHeightDelegateImpl.prototype.tableViewViewForHeaderInSection = function (tableView, section) {
var headerView = (tableView.dequeueReusableHeaderFooterViewWithIdentifier(HEADERIDENTIFIER) || SectionedListViewHeaderView.new());
var owner = this._owner.get();
if (owner) {
owner._prepareHeaderView(headerView, section);
var cellView = headerView.view;
if (cellView) {
var width = utils.layout.getMeasureSpecSize(owner.widthMeasureSpec);
var headerHeight = owner.headerHeight;
view.View.layoutChild(owner, cellView, 0, 0, width, headerHeight);
}
}
return headerView;
};
SectionedUITableViewRowHeightDelegateImpl.prototype.tableViewHeightForHeaderInSection = function (tableView, section) {
var owner = this._owner.get();
return owner.headerHeight;
};
SectionedUITableViewRowHeightDelegateImpl.ObjCProtocols = [UITableViewDelegate];
return SectionedUITableViewRowHeightDelegateImpl;
}(NSObject));
function onSeparatorColorPropertyChanged(data) {
var bar = data.object;
if (!bar.ios) {
return;
}
var color = require("color");
if (data.newValue instanceof color.Color) {
bar.ios.separatorColor = data.newValue.ios;
}
}
common.SectionedListView.separatorColorProperty.metadata.onSetNativeValue = onSeparatorColorPropertyChanged;
var SectionedListView = (function (_super) {
__extends(SectionedListView, _super);
function SectionedListView() {
_super.call(this);
this._preparingCell = false;
this._isDataDirty = false;
this.widthMeasureSpec = 0;
this._ios = UITableView.new();
this._ios.registerClassForCellReuseIdentifier(SectionedListViewCell.class(), CELLIDENTIFIER);
this._ios.autoresizingMask = UIViewAutoresizing.UIViewAutoresizingNone;
this._ios.estimatedRowHeight = DEFAULT_HEIGHT;
this._ios.rowHeight = UITableViewAutomaticDimension;
this._ios.dataSource = this._dataSource = SectionedDataSource.initWithOwner(new WeakRef(this));
this._delegate = SectionedTableViewDelegateImpl.initWithOwner(new WeakRef(this));
this._heights = new Array();
this._map = new Map();
}
SectionedListView.prototype.onLoaded = function () {
_super.prototype.onLoaded.call(this);
if (this._isDataDirty) {
this.refresh();
}
this._ios.delegate = this._delegate;
};
SectionedListView.prototype.onUnloaded = function () {
this._ios.delegate = null;
_super.prototype.onUnloaded.call(this);
};
Object.defineProperty(SectionedListView.prototype, "ios", {
get: function () {
return this._ios;
},
enumerable: true,
configurable: true
});
SectionedListView.prototype.scrollToIndexPath = function (index) {
if (this._ios) {
this._ios.scrollToRowAtIndexPathAtScrollPositionAnimated(NSIndexPath.indexPathForItemInSection(index, 0), UITableViewScrollPosition.UITableViewScrollPositionTop, false);
}
};
SectionedListView.prototype.refresh = function () {
if (this.isLoaded) {
this._ios.reloadData();
this.requestLayout();
this._isDataDirty = false;
}
else {
this._isDataDirty = true;
}
};
SectionedListView.prototype.getHeight = function (index) {
return this._heights[index];
};
SectionedListView.prototype.setHeight = function (index, value) {
this._heights[index] = value;
};
SectionedListView.prototype._onRowHeightPropertyChanged = function (data) {
if (data.newValue < 0) {
this._nativeView.rowHeight = UITableViewAutomaticDimension;
this._nativeView.estimatedRowHeight = DEFAULT_HEIGHT;
this._delegate = SectionedTableViewDelegateImpl.initWithOwner(new WeakRef(this));
}
else {
this._nativeView.rowHeight = data.newValue;
this._nativeView.estimatedRowHeight = data.newValue;
this._delegate = SectionedUITableViewRowHeightDelegateImpl.initWithOwner(new WeakRef(this));
}
if (this.isLoaded) {
this._nativeView.delegate = this._delegate;
}
_super.prototype._onRowHeightPropertyChanged.call(this, data);
};
SectionedListView.prototype.requestLayout = function () {
if (!this._preparingCell) {
_super.prototype.requestLayout.call(this);
}
};
SectionedListView.prototype.measure = function (widthMeasureSpec, heightMeasureSpec) {
this.widthMeasureSpec = widthMeasureSpec;
var changed = this._setCurrentMeasureSpecs(widthMeasureSpec, heightMeasureSpec);
_super.prototype.measure.call(this, widthMeasureSpec, heightMeasureSpec);
if (changed) {
this._ios.reloadData();
}
};
SectionedListView.prototype._layoutCell = function (cellView, indexPath) {
if (cellView) {
var measuredSize = view.View.measureChild(this, cellView, this.widthMeasureSpec, infinity);
var height = measuredSize.measuredHeight;
this.setHeight(indexPath.row, height);
return height;
}
return 0;
};
SectionedListView.prototype._prepareCell = function (cell, indexPath) {
var cellHeight;
try {
this._preparingCell = true;
var view_1 = cell.view;
if (!view_1) {
view_1 = this._getItemTemplateContent(indexPath.row, indexPath.section);
}
var args = notifyForItemAtIndex(this, cell, view_1, ITEMLOADING, indexPath);
view_1 = args.view || this._getDefaultItemContent(indexPath.row);
if (!cell.view) {
cell.owner = new WeakRef(view_1);
}
else if (cell.view !== view_1) {
this._removeContainer(cell);
cell.view._nativeView.removeFromSuperview();
cell.owner = new WeakRef(view_1);
}
this._prepareItem(view_1, indexPath.row, indexPath.section);
this._map.set(cell, view_1);
if (view_1 && !view_1.parent && view_1._nativeView) {
cell.contentView.addSubview(view_1._nativeView);
this._addView(view_1);
}
cellHeight = this._layoutCell(view_1, indexPath);
}
finally {
this._preparingCell = false;
}
return cellHeight;
};
SectionedListView.prototype._prepareHeaderView = function (headerView, section) {
var view = headerView.view;
if (!view) {
view = this._getHeaderTemplateContent(section);
}
var args = notifyForHeaderAtSection(this, headerView, view, HEADERLOADING, section);
view = args.view;
if (!view) {
var defaultContent = this._getDefaultHeaderContent(section);
defaultContent.marginLeft = this.ios.separatorInset.left;
view = defaultContent;
}
if (!headerView.view) {
headerView.owner = new WeakRef(view);
}
else if (headerView.view !== view) {
this._removeContainer(headerView);
headerView.view._nativeView.removeFromSuperview();
headerView.owner = new WeakRef(view);
}
this._prepareHeader(view, section);
this._map.set(headerView, view);
if (view && !view.parent && view._nativeView) {
headerView.contentView.addSubview(view._nativeView);
this._addView(view);
}
};
SectionedListView.prototype._removeContainer = function (cell) {
this._removeView(cell.view);
this._map.delete(cell);
};
SectionedListView.prototype._getDefaultHeaderContent = function (row, section) {
if (section === void 0) { section = 0; }
var lbl = new label_1.Label();
var formattedString = new formatted_string_1.FormattedString();
var span = new span_1.Span();
span.fontSize = 16;
span.bind({
targetProperty: "text",
sourceProperty: "$value"
});
span.fontAttributes = enums_1.FontAttributes.Bold;
formattedString.spans.push(span);
lbl.formattedText = formattedString;
return lbl;
};
return SectionedListView;
}(common.SectionedListView));
exports.SectionedListView = SectionedListView;