Dashboard sipadu mbip
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

datatable-scroll.js 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739
  1. /*
  2. Copyright (c) 2010, Yahoo! Inc. All rights reserved.
  3. Code licensed under the BSD License:
  4. http://developer.yahoo.com/yui/license.html
  5. version: 3.4.0
  6. build: nightly
  7. */
  8. YUI.add('datatable-scroll', function(Y) {
  9. /**
  10. * Extends DataTable base to enable x,y, and xy scrolling.
  11. * @module datatable
  12. * @submodule datatable-scroll
  13. */
  14. var YNode = Y.Node,
  15. YLang = Y.Lang,
  16. YUA = Y.UA,
  17. YgetClassName = Y.ClassNameManager.getClassName,
  18. DATATABLE = "datatable",
  19. CLASS_HEADER = YgetClassName(DATATABLE, "hd"),
  20. CLASS_BODY = YgetClassName(DATATABLE, "bd"),
  21. CLASS_DATA = YgetClassName(DATATABLE, "data"),
  22. CLASS_LINER = YgetClassName(DATATABLE, "liner"),
  23. CLASS_SCROLLABLE = YgetClassName(DATATABLE, "scrollable"),
  24. CONTAINER_HEADER = '<div class="'+CLASS_HEADER+'"></div>',
  25. CONTAINER_BODY = '<div class="'+CLASS_BODY+'"></div>',
  26. TEMPLATE_TABLE = '<table></table>',
  27. scrollbarWidth = Y.cached(function () {
  28. var testNode = Y.one('body').appendChild('<div style="position:absolute;visibility:hidden;overflow:scroll;width:20px;"><p style="height:1px"/></div>'),
  29. width = testNode.get('offsetWidth') - testNode.get('clientWidth');
  30. testNode.remove(true);
  31. return width;
  32. });
  33. /**
  34. * Adds scrolling to DataTable.
  35. * @class DataTableScroll
  36. * @extends Plugin.Base
  37. */
  38. function DataTableScroll() {
  39. DataTableScroll.superclass.constructor.apply(this, arguments);
  40. }
  41. Y.mix(DataTableScroll, {
  42. NS: "scroll",
  43. NAME: "dataTableScroll",
  44. ATTRS: {
  45. /**
  46. * The width for the table. Set to a string (ex: "200px", "20em") if you want the table to scroll in the x direction.
  47. *
  48. * @attribute width
  49. * @public
  50. * @type string
  51. */
  52. width: {
  53. value: undefined,
  54. writeOnce: "initOnly"
  55. },
  56. /**
  57. * The height for the table. Set to a string (ex: "200px", "20em") if you want the table to scroll in the y-direction.
  58. *
  59. * @attribute height
  60. * @public
  61. * @type string
  62. */
  63. height: {
  64. value: undefined,
  65. writeOnce: "initOnly"
  66. },
  67. /**
  68. * The scrolling direction for the table.
  69. *
  70. * @attribute scroll
  71. * @private
  72. * @type string
  73. */
  74. _scroll: {
  75. //value: 'y',
  76. valueFn: function() {
  77. var w = this.get('width'),
  78. h = this.get('height');
  79. if (w && h) {
  80. return 'xy';
  81. }
  82. else if (w) {
  83. return 'x';
  84. }
  85. else if (h) {
  86. return 'y';
  87. }
  88. else {
  89. return null;
  90. }
  91. }
  92. },
  93. /**
  94. * The hexadecimal colour value to set on the top-right of the table if a scrollbar exists.
  95. *
  96. * @attribute COLOR_COLUMNFILLER
  97. * @public
  98. * @type string
  99. */
  100. COLOR_COLUMNFILLER: {
  101. value: '#f2f2f2',
  102. validator: YLang.isString,
  103. setter: function(param) {
  104. if (this._headerContainerNode) {
  105. this._headerContainerNode.setStyle('backgroundColor', param);
  106. }
  107. }
  108. }
  109. }
  110. });
  111. Y.extend(DataTableScroll, Y.Plugin.Base, {
  112. /**
  113. * The table node created in datatable-base
  114. *
  115. * @property _parentTableNode
  116. * @private
  117. * @type {Node}
  118. */
  119. _parentTableNode: null,
  120. /**
  121. * The THEAD node which resides within the table node created in datatable-base
  122. *
  123. * @property _parentTheadNode
  124. * @private
  125. * @type {Node}
  126. */
  127. _parentTheadNode: null,
  128. /**
  129. * The TBODY node which resides within the table node created in datatable-base
  130. *
  131. * @property _parentTbodyNode
  132. * @private
  133. * @type {Node}
  134. */
  135. _parentTbodyNode: null,
  136. /**
  137. * The TBODY Message node which resides within the table node created in datatable-base
  138. *
  139. * @property _parentMsgNode
  140. * @private
  141. * @type {Node}
  142. */
  143. _parentMsgNode: null,
  144. /**
  145. * The contentBox specified for the datatable in datatable-base
  146. *
  147. * @property _parentContainer
  148. * @private
  149. * @type {Node}
  150. */
  151. _parentContainer: null,
  152. /**
  153. * The DIV node that contains all the scrollable elements (a table with a tbody on it)
  154. *
  155. * @property _bodyContainerNode
  156. * @private
  157. * @type {Node}
  158. */
  159. _bodyContainerNode: null,
  160. /**
  161. * The DIV node that contains a table with a THEAD in it (which syncs its horizontal scroll with the _bodyContainerNode above)
  162. *
  163. * @property _headerContainerNode
  164. * @private
  165. * @type {Node}
  166. */
  167. _headerContainerNode: null,
  168. //--------------------------------------
  169. // Methods
  170. //--------------------------------------
  171. initializer: function(config) {
  172. var dt = this.get("host");
  173. this._parentContainer = dt.get('contentBox');
  174. this._parentContainer.addClass(CLASS_SCROLLABLE);
  175. this._setUpNodes();
  176. },
  177. /////////////////////////////////////////////////////////////////////////////
  178. //
  179. // Set up Table Nodes
  180. //
  181. /////////////////////////////////////////////////////////////////////////////
  182. /**
  183. * Set up methods to fire after host methods execute
  184. *
  185. * @method _setUpNodes
  186. * @private
  187. */
  188. _setUpNodes: function() {
  189. this.afterHostMethod("_addTableNode", this._setUpParentTableNode);
  190. this.afterHostMethod("_addTheadNode", this._setUpParentTheadNode);
  191. this.afterHostMethod("_addTbodyNode", this._setUpParentTbodyNode);
  192. this.afterHostMethod("_addMessageNode", this._setUpParentMessageNode);
  193. //this.beforeHostMethod('renderUI', this._removeCaptionNode);
  194. this.afterHostMethod("renderUI", this.renderUI);
  195. this.afterHostMethod("bindUI", this.bindUI);
  196. this.afterHostMethod("syncUI", this.syncUI);
  197. if (this.get('_scroll') !== 'x') {
  198. this.afterHostMethod('_attachTheadThNode', this._attachTheadThNode);
  199. this.afterHostMethod('_attachTbodyTdNode', this._attachTbodyTdNode);
  200. }
  201. },
  202. /**
  203. * Stores the main &lt;table&gt; node provided by the host as a private property
  204. *
  205. * @method _setUpParentTableNode
  206. * @private
  207. */
  208. _setUpParentTableNode: function() {
  209. this._parentTableNode = this.get('host')._tableNode;
  210. },
  211. /**
  212. * Stores the main &lt;thead&gt; node provided by the host as a private property
  213. *
  214. * @method _setUpParentTheadNode
  215. * @private
  216. */
  217. _setUpParentTheadNode: function() {
  218. this._parentTheadNode = this.get('host')._theadNode;
  219. },
  220. /**
  221. * Stores the main &lt;tbody&gt; node provided by the host as a private property
  222. *
  223. * @method _setUpParentTbodyNode
  224. * @private
  225. */
  226. _setUpParentTbodyNode: function() {
  227. this._parentTbodyNode = this.get('host')._tbodyNode;
  228. },
  229. /**
  230. * Stores the main &lt;tbody&gt; message node provided by the host as a private property
  231. *
  232. * @method _setUpParentMessageNode
  233. * @private
  234. */
  235. _setUpParentMessageNode: function() {
  236. this._parentMsgNode = this.get('host')._msgNode;
  237. },
  238. /////////////////////////////////////////////////////////////////////////////
  239. //
  240. // Renderer
  241. //
  242. /////////////////////////////////////////////////////////////////////////////
  243. /**
  244. * Primary rendering method that takes the datatable rendered in
  245. * the host, and splits it up into two separate &lt;divs&gt; each containing two
  246. * separate tables (one containing the head and one containing the body).
  247. * This method fires after renderUI is called on datatable-base.
  248. *
  249. * @method renderUI
  250. */
  251. renderUI: function() {
  252. //Y.Profiler.start('render');
  253. this._createBodyContainer();
  254. this._createHeaderContainer();
  255. this._setContentBoxDimensions();
  256. //Y.Profiler.stop('render');
  257. //console.log(Y.Profiler.getReport("render"));
  258. },
  259. /**
  260. Binds event subscriptions to keep the state and UI in sync
  261. @method bindUI
  262. **/
  263. bindUI: function () {
  264. // FIXME: I don't know why the string bind, but I don't want to break
  265. // stuff until I have time to rebuild it properly
  266. this._bodyContainerNode.on('scroll', Y.bind("_onScroll", this));
  267. this.afterHostEvent("recordsetChange", this.syncUI);
  268. this.afterHostEvent("recordset:recordsChange", this.syncUI);
  269. },
  270. /**
  271. * Post rendering method that is responsible for creating a column
  272. * filler, and performing width and scroll synchronization between the &lt;th&gt;
  273. * elements and the &lt;td&gt; elements.
  274. * This method fires after syncUI is called on datatable-base
  275. *
  276. * @method syncUI
  277. * @public
  278. */
  279. syncUI: function() {
  280. //Y.Profiler.start('sync');
  281. this._removeCaptionNode();
  282. this._syncWidths();
  283. this._syncScroll();
  284. //Y.Profiler.stop('sync');
  285. //console.log(Y.Profiler.getReport("sync"));
  286. },
  287. /**
  288. * Remove the caption created in base. Scrolling datatables dont support captions.
  289. *
  290. * @method _removeCaptionNode
  291. * @private
  292. */
  293. _removeCaptionNode: function() {
  294. this.get('host')._captionNode.remove();
  295. //Y.DataTable.Base.prototype.createCaption = function(v) {/*do nothing*/};
  296. //Y.DataTable.Base.prototype._uiSetCaption = function(v) {/*do nothing*/};
  297. },
  298. /**
  299. * Adjusts the width of the TH and the TDs to make sure that the two are in sync
  300. *
  301. * Implementation Details:
  302. * Compares the width of the TH liner div to the the width of the TD node.
  303. * The TD liner width is not actually used because the TD often stretches
  304. * past the liner if the parent DIV is very large. Measuring the TD width
  305. * is more accurate.
  306. *
  307. * Instead of measuring via .get('width'), 'clientWidth' is used, as it
  308. * returns a number, whereas 'width' returns a string, In IE6,
  309. * 'clientWidth' is not supported, so 'offsetWidth' is used. 'offsetWidth'
  310. * is not as accurate on Chrome,FF as 'clientWidth' - thus the need for
  311. * the fork.
  312. *
  313. * @method _syncWidths
  314. * @private
  315. */
  316. _syncWidths: function() {
  317. var headerTable = this._parentContainer.one('.' + CLASS_HEADER),
  318. bodyTable = this._parentContainer.one('.' + CLASS_BODY),
  319. // nodelist of all the THs
  320. headers = headerTable.all('thead .' + CLASS_LINER),
  321. // nodelist of the TDs in the first row
  322. firstRow = bodyTable.one('.' + CLASS_DATA + ' tr'),
  323. cells = firstRow && firstRow.all('.' + CLASS_LINER),
  324. // FIXME: Code smell
  325. widthProperty = (YUA.ie) ? 'offsetWidth' : 'clientWidth';
  326. //stylesheet = new YStyleSheet('columnsSheet'),
  327. //className;
  328. // If there are data rows, iterate each header and the cells of the
  329. // first row comparing cell widths. Assign the larger width to the
  330. // narrower node (header or cell).
  331. if (cells && cells.size()) {
  332. headers.each(function (header, i) {
  333. var cell = cells.item(i),
  334. headerWidth = header.get(widthProperty),
  335. cellWidth = cell.get(widthProperty),
  336. width = Math.max(headerWidth, cellWidth);
  337. width -= (parseInt(header.getComputedStyle('paddingLeft'),10)|0) +
  338. (parseInt(header.getComputedStyle('paddingRight'),10)|0);
  339. header.setStyle('width', width + 'px');
  340. cell.setStyle('width', width + 'px');
  341. });
  342. }
  343. /*
  344. // If browser is not IE - get the clientWidth of the Liner
  345. // div and the TD.
  346. // Note: We are not getting the width of the TDLiner, we
  347. // are getting the width of the actual cell. Why? Because
  348. // when the table is set to auto width, the cell will grow
  349. // to try to fit the table in its container. The liner
  350. // could potentially be much smaller than the cell width.
  351. // TODO: Explore if there is a better way using only LINERS
  352. // widths - I don't think this should be a problem, given
  353. // that the liner is a div, a block element and will
  354. // expand to width.
  355. if (!ie) {
  356. // TODO: this should actually be done with
  357. // getComputedStyle('width') but this messes up
  358. // columns. Explore this option.
  359. thWidth = thLiner.get('clientWidth');
  360. tdWidth = td.item(i).get('clientWidth');
  361. } else {
  362. // IE wasn't recognizing clientWidths, so we are using
  363. // offsetWidths.
  364. // TODO: should use getComputedStyle('width') because
  365. // offsetWidth will screw up when padding is changed.
  366. // TODO: for some reason, using
  367. // tdLiner.get('clientWidth') doesn't work - why not?
  368. thWidth = thLiner.get('offsetWidth');
  369. tdWidth = td.item(i).get('offsetWidth');
  370. //thWidth = parseFloat(thLiner.getComputedStyle('width').split('px')[0]);
  371. //tdWidth = parseFloat(td.item(i).getComputedStyle('width').split('px')[0]);
  372. }
  373. // expand the TH or the TD to match the wider
  374. if (thWidth > tdWidth) {
  375. tdLiner.setStyle('width', (thWidth - 20 + 'px'));
  376. //thLiner.setStyle('width', (tdWidth - 20 + 'px'));
  377. //stylesheet.set(className,{'width': (thWidth - 20 + 'px')});
  378. } else if (tdWidth > thWidth) {
  379. // if you don't set an explicit width here, when the width
  380. // is set in line 368, it will auto-shrink the widths of
  381. // the other cells (because they dont have an explicit
  382. // width)
  383. thLiner.setStyle('width', (tdWidth - 20 + 'px'));
  384. tdLiner.setStyle('width', (tdWidth - 20 + 'px'));
  385. //stylesheet.set(className,{'width': (tdWidth - 20 + 'px')});
  386. }
  387. //}
  388. }
  389. */
  390. //stylesheet.enable();
  391. },
  392. /**
  393. * Adds the approriate width to the liner divs of the TH nodes before they are appended To DoM
  394. *
  395. * @method _attachTheadThNode
  396. * @private
  397. */
  398. _attachTheadThNode: function(o) {
  399. var width = o.column.get('width');
  400. if (width) {
  401. o.th.one('.' + CLASS_LINER)
  402. .setStyles({
  403. width: width,
  404. overflow:'hidden'
  405. });
  406. }
  407. },
  408. /**
  409. * Adds the appropriate width to the liner divs of the TD nodes before they are appended To DoM
  410. *
  411. * @method _attachTbodyTdNode
  412. * @private
  413. */
  414. _attachTbodyTdNode: function(o) {
  415. var width = o.column.get('width');
  416. if (width) {
  417. o.td.one('.' + CLASS_LINER)
  418. .setStyles({
  419. width: width,
  420. overflow: 'hidden'
  421. });
  422. }
  423. },
  424. /**
  425. * Creates the body DIV that contains all the data.
  426. *
  427. * @method _createBodyContainer
  428. * @private
  429. */
  430. _createBodyContainer: function() {
  431. var bd = YNode.create(CONTAINER_BODY);
  432. this._bodyContainerNode = bd;
  433. this._setStylesForTbody();
  434. bd.appendChild(this._parentTableNode);
  435. this._parentContainer.appendChild(bd);
  436. },
  437. /**
  438. * Creates the DIV that contains a &lt;table&gt; with all the headers.
  439. *
  440. * @method _createHeaderContainer
  441. * @private
  442. */
  443. _createHeaderContainer: function() {
  444. var hd = YNode.create(CONTAINER_HEADER),
  445. tbl = YNode.create(TEMPLATE_TABLE);
  446. this._headerContainerNode = hd;
  447. //hd.setStyle('backgroundColor',this.get("COLOR_COLUMNFILLER"));
  448. this._setStylesForThead();
  449. tbl.appendChild(this._parentTheadNode);
  450. hd.appendChild(tbl);
  451. this._parentContainer.prepend(hd);
  452. },
  453. /**
  454. * Creates styles for the TBODY based on what type of table it is.
  455. *
  456. * @method _setStylesForTbody
  457. * @private
  458. */
  459. _setStylesForTbody: function() {
  460. var dir = this.get('_scroll'),
  461. w = this.get('width') || "",
  462. h = this.get('height') || "",
  463. el = this._bodyContainerNode,
  464. styles = {width:"", height:h};
  465. if (dir === 'x') {
  466. //X-Scrolling tables should not have a Y-Scrollbar so overflow-y is hidden. THe width on x-scrolling tables must be set by user.
  467. styles.overflowY = 'hidden';
  468. styles.width = w;
  469. } else if (dir === 'y') {
  470. //Y-Scrolling tables should not have a X-Scrollbar so overflow-x is hidden. The width isn't neccessary because it can be auto.
  471. styles.overflowX = 'hidden';
  472. } else if (dir === 'xy') {
  473. styles.width = w;
  474. } else {
  475. //scrolling is set to 'null' - ie: width and height are not set. Don't have any type of scrolling.
  476. styles.overflowX = 'hidden';
  477. styles.overflowY = 'hidden';
  478. styles.width = w;
  479. }
  480. el.setStyles(styles);
  481. return el;
  482. },
  483. /**
  484. * Creates styles for the THEAD based on what type of datatable it is.
  485. *
  486. * @method _setStylesForThead
  487. * @private
  488. */
  489. _setStylesForThead: function() {
  490. var w = this.get('width') || "",
  491. el = this._headerContainerNode;
  492. //if (dir !== 'y') {
  493. el.setStyles({'width': w, 'overflow': 'hidden'});
  494. // }
  495. },
  496. /**
  497. * Sets an auto width on the content box if it doesn't exist or if its a y-datatable.
  498. *
  499. * @method _setContentBoxDimensions
  500. * @private
  501. */
  502. _setContentBoxDimensions: function() {
  503. if (this.get('_scroll') === 'y' || (!this.get('width'))) {
  504. this._parentContainer.setStyle('width', 'auto');
  505. }
  506. },
  507. /////////////////////////////////////////////////////////////////////////////
  508. //
  509. // Scroll Syncing
  510. //
  511. /////////////////////////////////////////////////////////////////////////////
  512. /**
  513. * Ensures that scrolling is synced across the two tables
  514. *
  515. * @method _onScroll
  516. * @private
  517. */
  518. _onScroll: function() {
  519. this._headerContainerNode.set('scrollLeft', this._bodyContainerNode.get('scrollLeft'));
  520. },
  521. /**
  522. * Syncs padding around scrollable tables, including Column header right-padding
  523. * and container width and height.
  524. *
  525. * @method _syncScroll
  526. * @private
  527. */
  528. _syncScroll : function() {
  529. this._syncScrollX();
  530. this._syncScrollY();
  531. this._syncScrollOverhang();
  532. if (YUA.opera) {
  533. // Bug 1925874
  534. this._headerContainerNode.set('scrollLeft', this._bodyContainerNode.get('scrollLeft'));
  535. if(!this.get("width")) {
  536. // Bug 1926125
  537. document.body.style += '';
  538. }
  539. }
  540. },
  541. /**
  542. * Snaps container width for y-scrolling tables.
  543. *
  544. * @method _syncScrollY
  545. * @private
  546. */
  547. _syncScrollY : function() {
  548. var tBody = this._parentTbodyNode,
  549. tBodyContainer = this._bodyContainerNode,
  550. w;
  551. // X-scrolling not enabled
  552. if(!this.get("width")) {
  553. // Snap outer container width to content
  554. w = (tBodyContainer.get('scrollHeight') > tBodyContainer.get('clientHeight')) ?
  555. // but account for y-scrollbar since it is visible
  556. (tBody.get('parentNode').get('clientWidth') + scrollbarWidth()) + "px" :
  557. // no y-scrollbar, just borders
  558. (tBody.get('parentNode').get('clientWidth') + 2) + "px";
  559. this._parentContainer.setStyle('width', w);
  560. }
  561. },
  562. /**
  563. * Snaps container height for x-scrolling tables in IE. Syncs message TBODY width.
  564. * Taken from YUI2 ScrollingDataTable.js
  565. *
  566. * @method _syncScrollX
  567. * @private
  568. */
  569. _syncScrollX: function() {
  570. var tBody = this._parentTbodyNode,
  571. tBodyContainer = this._bodyContainerNode,
  572. w;
  573. this._headerContainerNode.set('scrollLeft',
  574. this._bodyContainerNode.get('scrollLeft'));
  575. if (!this.get('height') && (YUA.ie)) {
  576. w = (tBodyContainer.get('scrollWidth') > tBodyContainer.get('offsetWidth')) ?
  577. (tBody.get('parentNode').get('offsetHeight') + scrollbarWidth()) + "px" :
  578. tBody.get('parentNode').get('offsetHeight') + "px";
  579. tBodyContainer.setStyle('height', w);
  580. }
  581. if (tBody.get('rows').size()) {
  582. this._parentMsgNode.get('parentNode').setStyle('width', "");
  583. } else {
  584. this._parentMsgNode.get('parentNode').setStyle('width', this._parentTheadNode.get('parentNode').get('offsetWidth')+'px');
  585. }
  586. },
  587. /**
  588. * Adds/removes Column header overhang as necesary.
  589. * Taken from YUI2 ScrollingDataTable.js
  590. *
  591. * @method _syncScrollOverhang
  592. * @private
  593. */
  594. _syncScrollOverhang: function() {
  595. var tBodyContainer = this._bodyContainerNode,
  596. padding = 1;
  597. //when its both x and y scrolling
  598. if ((tBodyContainer.get('scrollHeight') > tBodyContainer.get('clientHeight')) || (tBodyContainer.get('scrollWidth') > tBodyContainer.get('clientWidth'))) {
  599. padding = 18;
  600. }
  601. this._setOverhangValue(padding);
  602. // After the widths have synced, there is a wrapping issue in the
  603. // headerContainer in IE6. The header does not span the full length of
  604. // the table (does not cover all of the y-scrollbar). By adding this
  605. // line in when there is a y-scroll, the header will span correctly.
  606. // TODO: this should not really occur on this.get('_scroll') === y - it
  607. // should occur when scrollHeight > clientHeight, but clientHeight is
  608. // not getting recognized in IE6?
  609. if (YUA.ie !== 0 && this.get('_scroll') === 'y' && this._bodyContainerNode.get('scrollHeight') > this._bodyContainerNode.get('offsetHeight'))
  610. {
  611. this._headerContainerNode.setStyle('width', this._parentContainer.get('width'));
  612. }
  613. },
  614. /**
  615. * Sets Column header overhang to given width.
  616. * Taken from YUI2 ScrollingDataTable.js with minor modifications
  617. *
  618. * @method _setOverhangValue
  619. * @param nBorderWidth {Number} Value of new border for overhang.
  620. * @private
  621. */
  622. _setOverhangValue: function(borderWidth) {
  623. var host = this.get('host'),
  624. cols = host.get('columnset').get('definitions'),
  625. //lastHeaders = cols[cols.length-1] || [],
  626. len = cols.length,
  627. value = borderWidth + "px solid " + this.get("COLOR_COLUMNFILLER"),
  628. children = YNode.all('#'+this._parentContainer.get('id')+ ' .' + CLASS_HEADER + ' table thead th');
  629. children.item(len-1).setStyle('borderRight', value);
  630. }
  631. });
  632. Y.namespace("Plugin").DataTableScroll = DataTableScroll;
  633. }, '3.4.0' ,{requires:['datatable-base','plugin']});