datatable-scroll-debug.js revision 2a1f854e8f78b51e015bf8758bb439d55b171900
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke SmithAdds the ability to make the table rows scrollable while preserving the header
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke SmithThere are two types of scrolling, horizontal (x) and vertical (y). Horizontal
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smithscrolling is achieved by wrapping the entire table in a scrollable container.
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke SmithVertical scrolling is achieved by splitting the table headers and data into two
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smithseparate tables, the latter of which is wrapped in a vertically scrolling
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smithcontainer. In this case, column widths of header cells and data cells are kept
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smithin sync programmatically.
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke SmithSince the split table synchronization can be costly at runtime, the split is only done if the data in the table stretches beyond the configured `height` value.
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke SmithTo activate or deactivate scrolling, set the `scrollable` attribute to one of
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smiththe following values:
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith * `false` - (default) Scrolling is disabled.
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith * `true` or 'xy' - If `height` is set, vertical scrolling will be activated, if
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith `width` is set, horizontal scrolling will be activated.
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith * 'x' - Activate horizontal scrolling only. Requires the `width` attribute is
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith * 'y' - Activate vertical scrolling only. Requires the `height` attribute is
593ff3cc08bc8ba9b661227f7c88a51055169d8fLuke Smith @module datatable-scroll
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @class DataTable.Scrollable
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @for DataTable
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith// Returns the numeric value portion of the computed style, defaulting to 0
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith return parseInt(node.getComputedStyle(style), 10) | 0;
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke SmithY.DataTable.Scrollable = Scrollable = function () {};
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith Activates or deactivates scrolling in the table. Acceptable values are:
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith * `false` - (default) Scrolling is disabled.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith * `true` or 'xy' - If `height` is set, vertical scrolling will be
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith activated, if `width` is set, horizontal scrolling will be activated.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith * 'x' - Activate horizontal scrolling only. Requires the `width` attribute
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith is also set.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith * 'y' - Activate vertical scrolling only. Requires the `height` attribute
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith is also set.
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @attribute scrollable
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @type {String|Boolean}
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @value false
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith Scrolls a given row or cell into view if the table is scrolling. Pass the
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith `clientId` of a Model from the DataTable's `data` ModelList or its row
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith index to scroll to a row or a [row index, column index] array to scroll to
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith a cell. Alternately, to scroll to any element contained within the table's
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith scrolling areas, pass its ID, or the Node itself (though you could just as
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith well call `node.scrollIntoView()` yourself, but hey, whatever).
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @method scrollTo
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @param {String|Number|Number[]|Node} id A row clientId, row index, cell
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith coordinate array, id string, or Node
186b3579b2d4dfe441df1f5b7a4a7ddc98d6e524Luke Smith @return {DataTable}
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith if (id && this._tbodyNode && (this._yScrollNode || this._xScrollNode)) {
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith // TODO: ancestor(yScrollNode, xScrollNode)
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith id.ancestor('.yui3-datatable') === this.get('boundingBox')) {
186b3579b2d4dfe441df1f5b7a4a7ddc98d6e524Luke Smith return this;
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith //--------------------------------------------------------------------------
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith // Protected properties and methods
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith //--------------------------------------------------------------------------
fdeb2f42dceda6bd364a652e78595963e2a70c9eLuke Smith Template for the `<table>` that is used to fix the caption in place when
fdeb2f42dceda6bd364a652e78595963e2a70c9eLuke Smith the table is horizontally scrolling.
fdeb2f42dceda6bd364a652e78595963e2a70c9eLuke Smith @property _CAPTION_TABLE_TEMPLATE
fdeb2f42dceda6bd364a652e78595963e2a70c9eLuke Smith @type {HTML}
55468c0b0feefa0f7cf0bfd96efc5a84b17995e5Luke Smith @value '<table class="{className}" role="presentation"></table>'
55468c0b0feefa0f7cf0bfd96efc5a84b17995e5Luke Smith _CAPTION_TABLE_TEMPLATE: '<table class="{className}" role="presentation"></table>',
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Template used to create sizable element liners around header content to
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith synchronize fixed header column widths.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @property _SCROLL_LINER_TEMPLATE
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @type {HTML}
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @value '<div class="{className}"></div>'
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith _SCROLL_LINER_TEMPLATE: '<div class="{className}"></div>',
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Template for the virtual scrollbar needed in "y" and "xy" scrolling setups.
fdeb2f42dceda6bd364a652e78595963e2a70c9eLuke Smith @property _SCROLLBAR_TEMPLATE
fdeb2f42dceda6bd364a652e78595963e2a70c9eLuke Smith @type {HTML}
fdeb2f42dceda6bd364a652e78595963e2a70c9eLuke Smith @value '<div class="{className}"><div></div></div>'
fdeb2f42dceda6bd364a652e78595963e2a70c9eLuke Smith _SCROLLBAR_TEMPLATE: '<div class="{className}"><div></div></div>',
fdeb2f42dceda6bd364a652e78595963e2a70c9eLuke Smith Template for the `<div>` that is used to contain the table when the table is
fdeb2f42dceda6bd364a652e78595963e2a70c9eLuke Smith horizontally scrolling.
fdeb2f42dceda6bd364a652e78595963e2a70c9eLuke Smith @property _X_SCROLLER_TEMPLATE
fdeb2f42dceda6bd364a652e78595963e2a70c9eLuke Smith @type {HTML}
fdeb2f42dceda6bd364a652e78595963e2a70c9eLuke Smith @value '<div class="{className}"></div>'
fdeb2f42dceda6bd364a652e78595963e2a70c9eLuke Smith _X_SCROLLER_TEMPLATE: '<div class="{className}"></div>',
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Template for the `<table>` used to contain the fixed column headers for
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith vertically scrolling tables.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @property _Y_SCROLL_HEADER_TEMPLATE
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @type {HTML}
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @value '<table cellspacing="0" role="presentation" aria-hidden="true" class="{className}"></table>'
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith _Y_SCROLL_HEADER_TEMPLATE: '<table cellspacing="0" role="presentation" aria-hidden="true" class="{className}"></table>',
fdeb2f42dceda6bd364a652e78595963e2a70c9eLuke Smith Template for the `<div>` that is used to contain the rows when the table is
fdeb2f42dceda6bd364a652e78595963e2a70c9eLuke Smith vertically scrolling.
fdeb2f42dceda6bd364a652e78595963e2a70c9eLuke Smith @property _Y_SCROLLER_TEMPLATE
fdeb2f42dceda6bd364a652e78595963e2a70c9eLuke Smith @type {HTML}
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @value '<div class="{className}"><div class="{scrollerClassName}"></div></div>'
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith _Y_SCROLLER_TEMPLATE: '<div class="{className}"><div class="{scrollerClassName}"></div></div>',
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Adds padding to the last cells in the fixed header for vertically scrolling
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith tables. This padding is equal in width to the scrollbar, so can't be
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith relegated to a stylesheet.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _addScrollbarPadding
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith scrollbarWidth = Y.DOM.getScrollbarWidth() + 'px';
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith for (i = 0, len = rows.size(); i < len; i += +header.get('rowSpan')) {
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Reacts to changes in the `scrollable` attribute by updating the `_xScroll`
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith and `_yScroll` properties and syncing the scrolling structure accordingly.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _afterScrollableChange
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @param {EventFacade} e The relevant change event (ignored)
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith } else if (!this._yScroll && this._yScrollNode) {
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Reacts to changes in the `caption` attribute by adding, removing, or
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith syncing the caption table when the table is set to scroll.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _afterScrollCaptionChange
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @param {EventFacade} e The relevant change event (ignored)
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Reacts to changes in the `columns` attribute of vertically scrolling tables
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith by refreshing the fixed headers, scroll container, and virtual scrollbar
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _afterScrollColumnsChange
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @param {EventFacade} e The relevant change event (ignored)
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Reacts to changes in vertically scrolling table's `data` ModelList by
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith synchronizing the fixed column header widths and virtual scrollbar height.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _afterScrollDataChange
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @param {EventFacade} e The relevant change event (ignored)
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Reacts to changes in the `height` attribute of vertically scrolling tables
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith by updating the height of the `<div>` wrapping the data table and the
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith virtual scrollbar. If `scrollable` was set to "y" or "xy" but lacking a
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith declared `height` until the received change, `_syncScrollUI` is called to
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith create the fixed headers etc.
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @method _afterScrollHeightChange
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @param {EventFacade} e The relevant change event (ignored)
2a1f854e8f78b51e015bf8758bb439d55b171900Luke Smith /* (not an API doc comment on purpose)
2a1f854e8f78b51e015bf8758bb439d55b171900Luke Smith Reacts to the sort event (if the table is also sortable) by updating the
2a1f854e8f78b51e015bf8758bb439d55b171900Luke Smith fixed header classes to match the data table's headers.
2a1f854e8f78b51e015bf8758bb439d55b171900Luke Smith THIS IS A HACK that will be removed immediately after the 3.5.0 release.
2a1f854e8f78b51e015bf8758bb439d55b171900Luke Smith If you're reading this and the current version is greater than 3.5.0, I
2a1f854e8f78b51e015bf8758bb439d55b171900Luke Smith should be publicly scolded.
2a1f854e8f78b51e015bf8758bb439d55b171900Luke Smith _afterScrollSort: function (e) {
2a1f854e8f78b51e015bf8758bb439d55b171900Luke Smith this._yScrollHeader.all(headerClass).each(function (header, i) {
2a1f854e8f78b51e015bf8758bb439d55b171900Luke Smith header.set('className', headers.item(i).get('className'));
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Reacts to changes in the width of scrolling tables by expanding the width of
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith the `<div>` wrapping the data table for horizontally scrolling tables or
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith upding the position of the virtual scrollbar for vertically scrolling
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _afterScrollWidthChange
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @param {EventFacade} e The relevant change event (ignored)
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Binds virtual scrollbar interaction to the `_yScrollNode`'s `scrollTop` and
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _bindScrollbar
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith _bindScrollbar: function () {
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith if (scrollbar && scroller && !this._scrollbarEventHandle) {
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith this._scrollbarEventHandle = new Y.Event.Handle([
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith scrollbar.on('scroll', this._syncScrollPosition, this, 'virtual'),
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith scroller.on('scroll', this._syncScrollPosition, this)
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Binds to the window resize event to update the vertical scrolling table
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith headers and wrapper `<div>` dimensions.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _bindScrollResize
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // TODO: sync header widths and scrollbar position. If the height
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // of the headers has changed, update the scrollbar dims as well.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith this._syncScrollUI, null, this);
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith Attaches internal subscriptions to keep the scrolling structure up to date
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith with changes in the table's `data`, `columns`, `caption`, or `height`. The
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith `width` is taken care of already.
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith This executes after the table's native `bindUI` method.
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @method _bindScrollUI
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith _bindScrollUI: function () {
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith columnsChange: Y.bind('_afterScrollColumnsChange', this),
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith heightChange : Y.bind('_afterScrollHeightChange', this),
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith widthChange : Y.bind('_afterScrollWidthChange', this),
2a1f854e8f78b51e015bf8758bb439d55b171900Luke Smith captionChange: Y.bind('_afterScrollCaptionChange', this),
2a1f854e8f78b51e015bf8758bb439d55b171900Luke Smith // FIXME: this is a last minute hack to work around the fact that
2a1f854e8f78b51e015bf8758bb439d55b171900Luke Smith // DT doesn't use a tableView to render table content that can be
2a1f854e8f78b51e015bf8758bb439d55b171900Luke Smith // replaced with a scrolling table view. This must be removed asap!
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith this.after(['dataChange', '*:add', '*:remove', '*:reset', '*:change'],
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Clears the lock and timer used to manage synchronizing the scroll position
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith between the vertical scroll container and the virtual scrollbar.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _clearScrollLock
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Creates a virtual scrollbar from the `_SCROLLBAR_TEMPLATE`, assigning it to
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith the `_scrollbarNode` property.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _createScrollbar
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @return {Node} The created Node
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith scrollbar.setStyle('width', Y.DOM.getScrollbarWidth() + 'px');
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Creates a separate table to contain the caption when the table is
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith configured to scroll vertically or horizontally.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _createScrollCaptionTable
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @return {Node} The created Node
9f61355243edf6ed98ab0e2994fb132ffd47dd66Luke Smith Populates the `_xScrollNode` property by creating the `<div>` Node described
fdeb2f42dceda6bd364a652e78595963e2a70c9eLuke Smith by the `_X_SCROLLER_TEMPLATE`.
9f61355243edf6ed98ab0e2994fb132ffd47dd66Luke Smith @method _createXScrollNode
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @return {Node} The created Node
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Populates the `_yScrollHeader` property by creating the `<table>` Node
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith described by the `_Y_SCROLL_HEADER_TEMPLATE`.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _createYScrollHeader
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @return {Node} The created Node
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith fixedHeader = this._yScrollHeader = Y.Node.create(
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // Needed for IE which creates an empty <tbody> in the table
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith Populates the `_yScrollNode` property by creating the `<div>` Node described
fdeb2f42dceda6bd364a652e78595963e2a70c9eLuke Smith by the `_Y_SCROLLER_TEMPLATE`.
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @method _createYScrollNode
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @return {Node} The created Node
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith scrollerClass = this.getClassName('y', 'scroller');
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith className: this.getClassName('y','scroller','container'),
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Removes the nodes used to create horizontal and vertical scrolling and
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith rejoins the caption to the main table if needed.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _disableScrolling
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Removes the nodes used to allow horizontal scrolling.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _disableXScrolling
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Removes the nodes used to allow vertical scrolling.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _disableYScrolling
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Cleans up external event subscriptions.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method destructor
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith destructor: function () {
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith Sets up event handlers and AOP advice methods to bind the DataTable's natural
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith behaviors with the scrolling APIs and state.
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @method initializer
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @param {Object} config The config object passed to the constructor (ignored)
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith initializer: function () {
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith this.after(['scrollableChange', 'heightChange', 'widthChange'],
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Removes the table used to house the caption when the table is scrolling.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _removeScrollCaptionTable
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Removes the `<div>` wrapper used to contain the data table when the table
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith is horizontally scrolling.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _removeXScrollNode
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith scroller.replace(scroller.get('childNodes').toFrag());
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Removes the `<table>` used to contain the fixed column headers when the
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith table is vertically scrolling.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _removeYScrollHeader
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Removes the `<div>` wrapper used to contain the data table when the table
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith is vertically scrolling.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _removeYScrollNode
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Removes the virtual scrollbar used by scrolling tables.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _removeScrollbar
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith Accepts (case insensitive) values "x", "y", "xy", `true`, and `false`.
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith `true` is translated to "xy" and upper case values are converted to lower
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith case. All other values are invalid.
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @method _setScrollable
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @param {String|Boolea} val Incoming value for the `scrollable` attribute
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @return {String}
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith if (val === true) {
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith return (val === false || val === 'y' || val === 'x' || val === 'xy') ?
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith Assigns the `_xScroll` and `_yScroll` properties to true if an
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith appropriate value is set in the `scrollable` attribute and the `height`
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith and/or `width` is set.
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @method _setScrollProperties
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith this._xScroll = width && scrollable.indexOf('x') > -1;
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith this._yScroll = height && scrollable.indexOf('y') > -1;
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Keeps the virtual scrollbar and the scrolling `<div>` wrapper around the
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith data table in vertically scrolling tables in sync.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _syncScrollPosition
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @param {DOMEventFacade} e The scroll event
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @param {String} [source] The string "virtual" if the event originated from
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith the virtual scrollbar
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith if (this._scrollLock && this._scrollLock.source !== source) {
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith this._scrollLock = Y.later(300, this, this._clearScrollLock);
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith scroller.set('scrollTop', scrollbar.get('scrollTop'));
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith scrollbar.set('scrollTop', scroller.get('scrollTop'));
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Splits the caption from the data `<table>` if the table is configured to
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith scroll. If not, rejoins the caption to the data `<table>` if it needs to
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _syncScrollCaptionUI
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith if (!caption.get('parentNode').compareTo(captionTable)) {
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Assigns widths to the fixed header columns to match the columns in the data
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _syncScrollColumnWidths
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // Capture dims and assign widths in two passes to avoid reflows for
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // each access of clientWidth/getComputedStyle
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith this._theadNode.all('.' + this.getClassName('header'))
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // FIXME: IE returns the col.style.width from
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // getComputedStyle even if the column has been
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // compressed below that width, so it must use
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // clientWidth. FF requires getComputedStyle because it
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // uses fractional widths that round up to an overall
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // cell/table width 1px greater than the data table's
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // cell/table width, resulting in misaligned columns or
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // fixed header bleed through. I can't think of a
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // *reasonable* way to capture the correct width without
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // a sniff. Math.min(cW - p, getCS(w)) was imperfect
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // and punished all browsers, anyway.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith this._yScrollHeader.all('.' + this.getClassName('scroll', 'liner'))
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Creates matching headers in the fixed header table for vertically scrolling
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith tables and synchronizes the column widths.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _syncScrollHeaders
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith linerClass = this.getClassName('scroll', 'liner');
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // Prevent duplicate IDs and assign ARIA attributes to hide
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // from screen readers
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith fixedHeader.all('.' + this.getClassName('header'))
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith var liner = Y.Node.create(Y.Lang.sub(linerTemplate, {
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith liner.appendChild(header.get('childNodes').toFrag());
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Wraps the table for X and Y scrolling, if necessary, if the `scrollable`
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith attribute is set. Synchronizes dimensions and DOM placement of all
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith scrolling related nodes.
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @method _syncScrollUI
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith _syncScrollUI: function () {
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith var x = this._xScroll,
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // TODO: Probably should split this up into syncX, syncY, and syncXY
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith if (x || y) {
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith if ((this.get('width') || '').slice(-1) === '%') {
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Wraps the table in a scrolling `<div>` of the configured width for "x"
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _syncXScrollUI
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @param {Boolean} xy True if the table is configured with scrollable ="xy"
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith bbWidth = this.get('boundingBox').get('offsetWidth'),
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // Not using table.wrap() because IE went all crazy, wrapping the
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // table in the last td in the table itself.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // Can't use offsetHeight - clientHeight because IE6 returns
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // clientHeight of 0 intially.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith borderWidth = styleDim(scroller, 'borderLeftWidth') +
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // Lock the table's unconstrained width to avoid configured column
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // widths being ignored
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // Have to assign a style and trigger a reflow to allow the
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // subsequent clearing of width + reflow to expand the table to
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // natural width in IE 6
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // Can't use 100% width because the borders add additional width
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // TODO: Cache the border widths, though it won't prevent a reflow
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith scroller.setStyle('width', (bbWidth - borderWidth) + 'px');
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // expand the table to fill the assigned width if it doesn't
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // already overflow the configured width
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith if ((scroller.get('offsetWidth') - borderWidth) > tableWidth) {
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // Assumes the wrapped table doesn't have borders
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith table.setStyle('width', (scroller.get('offsetWidth') -
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Wraps the table in a scrolling `<div>` of the configured height (accounting
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith for the caption if there is one) if "y" scrolling is enabled. Otherwise,
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith unwraps the table if necessary.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _syncYScrollUI
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @param {Boolean} xy True if the table is configured with scrollable = "xy"
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // Set the scroller height
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // Account for the horizontal scrollbar in the overall height
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // because IE6 is returning clientHeight 0 initially
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith styleDim(outerScroller, 'borderBottomWidth')) + 'px');
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // Set the scroller width
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // For xy scrolling tables, the table should expand freely within
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // the x scroller
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith (table.get('offsetWidth') + scrollbarWidth) + 'px');
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith captionTable.setStyle('width', yScroller.get('offsetWidth') + 'px');
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // Allow headerless scrolling
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // This might need to come back if FF has issues
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith //fixedHeader.setStyle('width', '100%');
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith //(yScroller.get('clientWidth') + scrollbarWidth) + 'px');
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith Assigns the appropriate class to the `boundingBox` to identify the DataTable
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith as horizontally scrolling, vertically scrolling, or both (adds both classes).
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith Classes added are "yui3-datatable-scrollable-x" or "...-y"
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @method _uiSetScrollable
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith .toggleClass(this.getClassName('scrollable','x'), this._xScroll)
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith .toggleClass(this.getClassName('scrollable','y'), this._yScroll);
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Updates the virtual scrollbar's height to avoid overlapping with the fixed
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _uiSetScrollbarHeight
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith (parseFloat(scroller.getComputedStyle('height')) -
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith parseFloat(fixedHeader.getComputedStyle('height'))) + 'px');
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Updates the virtual scrollbar's placement to avoid overlapping the fixed
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith headers or the data table.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _uiSetScrollbarPosition
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @param {Node} scroller Reference node to position the scrollbar over
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // Using getCS instead of offsetHeight because FF uses
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // fractional values, but reports ints to offsetHeight, so
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // offsetHeight is unreliable. It is probably fine to use
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // offsetHeight in this case but this was left in place after
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // fixing an off-by-1px issue in FF 10- by fixing the caption
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // font style so FF picked it up.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith top: (parseFloat(fixedHeader.getComputedStyle('height')) +
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Assigns the width of the `<div>` wrapping the data table in vertically
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith scrolling tables.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith If the table can't compress to the specified width, the container is
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith expanded accordingly.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _uiSetYScrollWidth
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @param {String} width The CSS width to attempt to set
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith tableWidth, borderWidth, scrollerWidth, scrollbarWidth;
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // Assumes no table border
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // The table's rendered width might be greater than the
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // configured width
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // Have to subtract the border width from the configured width
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // because the scroller's width will need to be reduced by the
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // border width as well during the width reassignment below.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith scrollerWidth = scroller.get('clientWidth') - borderWidth;
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // Assumes no table borders
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // Expand the scroll node width if the table can't fit.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // Otherwise, reassign the scroller a pixel width that
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // accounts for the borders.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith // Allow the table to expand naturally
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith (table.get('offsetWidth') + scrollbarWidth) + 'px');
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Detaches the scroll event subscriptions used to maintain scroll position
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith parity between the scrollable `<div>` wrapper around the data table and the
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith virtual scrollbar for vertically scrolling tables.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _unbindScrollbar
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Detaches the resize event subscription used to maintain column parity for
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith vertically scrolling tables with percentage widths.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @method _unbindScrollResize
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith Indicates horizontal table scrolling is enabled.
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @property _xScroll
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @type {Boolean}
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @default undefined (not initially set)
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith //_xScroll: null,
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith Indicates vertical table scrolling is enabled.
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @property _yScroll
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @type {Boolean}
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @default undefined (not initially set)
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith //_yScroll: null,
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith Fixed column header `<table>` Node for vertical scrolling tables.
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @property _yScrollHeader
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @type {Node}
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith @default undefined (not initially set)
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith //_yScrollHeader: null,
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith Overflow Node used to contain the data rows in a vertically scrolling table.
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @property _yScrollNode
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @type {Node}
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith @default undefined (not initially set)
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith //_yScrollNode: null,
a93bd7ce6b9c5c28eca45f622a2e8863aa01006aLuke Smith Overflow Node used to contain the table headers and data in a horizontally
a93bd7ce6b9c5c28eca45f622a2e8863aa01006aLuke Smith scrolling table.
a93bd7ce6b9c5c28eca45f622a2e8863aa01006aLuke Smith @property _xScrollNode
a93bd7ce6b9c5c28eca45f622a2e8863aa01006aLuke Smith @type {Node}
a93bd7ce6b9c5c28eca45f622a2e8863aa01006aLuke Smith @default undefined (not initially set)
ca2e7dd1e36a560ce69fb437e66b6cc909e5907eLuke Smith //_xScrollNode: null
820d7f2eab2a78412c9803335bb10a2974e7fbf5Luke Smith}, '@VERSION@' ,{skinnable:true, requires:['datatable-base', 'dom-screen']});