2 YUI 3.13.0 (build 508226d)
3 Copyright 2013 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
8 YUI.add('datatable-column-widths', function (Y, NAME) {
11 Adds basic, programmatic column width support to DataTable via column
12 configuration property `width` and method `table.setColumnWidth(id, width);`.
15 @submodule datatable-column-widths
18 var isNumber = Y.Lang.isNumber,
19 arrayIndex = Y.Array.indexOf;
21 Y.Features.add('table', 'badColWidth', {
23 var body = Y.one('body'),
27 // In modern browsers, <col style="width:X"> will make columns,
28 // *including padding and borders* X wide. The cell content width
29 // is reduced. In old browsers and all Opera versions to date, the
30 // col's width style is passed to the cells, which causes cell
31 // padding/border to bloat the rendered width.
32 node = body.insertBefore(
33 '<table style="position:absolute;visibility:hidden;border:0 none">' +
34 '<colgroup><col style="width:9px"></colgroup>' +
38 'font:normal 2px/2px arial;' +
40 '.' + // Just something to give the cell dimension
41 '</td></tr></tbody>' +
43 body.get('firstChild'));
45 broken = node.one('td').getComputedStyle('width') !== '1px';
55 _API docs for this extension are included in the DataTable class._
57 Adds basic, programmatic column width support to DataTable. Note, this does not
58 add support for truncated columns. Due to the way HTML tables render, column
59 width is more like a "recommended width". Column content wider than the
60 assigned width will cause the column to expand, despite the configured width.
61 Similarly if the table is too narrow to fit the column with the configured
62 column width, the column width will be reduced.
64 To set a column width, either add a `width` value to the column configuration
65 or call the `setColumnWidth(id, width)` method.
67 Note, assigning column widths is possible without this module, as each cell is
68 decorated with a class appropriate for that column which you can statically
69 target in your site's CSS.
71 To achieve absolute column widths, with content truncation, you can either:
73 1. Use this module, configure *all* columns to have `width`s, then add
74 `table-layout: fixed;` to your CSS for the appropriate `<table>`, or
75 2. Wrap the contents of all cells in the column with a `<div>` (using a
76 `cellTemplate` or `formatter`), assign the div's style `width`, then assign
77 the column `width` or add a CSS `width` to the column class created by
80 <pre><code>.yui3-datatable .yui3-datatable-col-foo {
84 .yui3-datatable .yui3-datatable-col-foo .yui3-datatable-liner {
91 <pre><code>var table = new Y.DataTable({
96 '<td class="{className}">' +
97 '<div class="yui3-datatable-liner">{content}</div>' +
106 To add a liner to all columns, either provide a custom `bodyView` to the
107 DataTable constructor or update the default `bodyView`'s `CELL_TEMPLATE` like
110 <pre><code>table.on('table:renderBody', function (e) {
111 e.view.CELL_TEMPLATE = e.view.CELL_TEMPLATE.replace(/\{content\}/,
112 '<div class="yui3-datatable-liner">{content}</div>');
116 Keep in mind that DataTable skins apply cell `padding`, so assign your CSS
117 `width`s accordingly or override the `padding` style for that column's `<td>`s
118 to 0, and add `padding` to the liner `<div>`'s styles as shown above.
120 @class DataTable.ColumnWidths
124 function ColumnWidths() {}
126 Y.mix(ColumnWidths.prototype, {
128 The HTML template used to create the table's `<col>`s.
130 @property COL_TEMPLATE
135 COL_TEMPLATE: '<col/>',
138 The HTML template used to create the table's `<colgroup>`.
140 @property COLGROUP_TEMPLATE
142 @default '<colgroup/>'
145 COLGROUP_TEMPLATE: '<colgroup/>',
148 Assigns the style width of the `<col>` representing the column identifed by
149 `id` and updates the column configuration.
151 Pass the empty string for `width` to return a column to auto sizing.
153 This does not trigger a `columnsChange` event today, but I can be convinced
156 @method setColumnWidth
157 @param {Number|String|Object} id The column config object or key, name, or
158 index of a column in the host's `_displayColumns` array.
159 @param {Number|String} width CSS width value. Numbers are treated as pixels
164 setColumnWidth: function (id, width) {
165 var col = this.getColumn(id),
166 index = col && arrayIndex(this._displayColumns, col);
169 if (isNumber(width)) {
175 this._setColumnWidth(index, width);
181 //--------------------------------------------------------------------------
182 // Protected properties and methods
183 //--------------------------------------------------------------------------
185 Renders the table's `<colgroup>` and populates the `_colgroupNode` property.
187 @method _createColumnGroup
191 _createColumnGroup: function () {
192 return Y.Node.create(this.COLGROUP_TEMPLATE);
196 Hooks up to the rendering lifecycle to also render the `<colgroup>` and
197 subscribe to `columnChange` events.
203 initializer: function () {
204 this.after(['renderView', 'columnsChange'], this._uiSetColumnWidths);
208 Sets a columns's `<col>` element width style. This is needed to get around
209 browser rendering differences.
211 The colIndex corresponds to the item index of the `<col>` in the table's
214 To unset the width, pass a falsy value for the `width`.
216 @method _setColumnWidth
217 @param {Number} colIndex The display column index
218 @param {Number|String} width The desired width
222 // TODO: move this to a conditional module
223 _setColumnWidth: function (colIndex, width) {
224 // Opera (including Opera Next circa 1/13/2012) and IE7- pass on the
225 // width style to the cells directly, allowing padding and borders to
226 // expand the rendered width. Chrome 16, Safari 5.1.1, and FF 3.6+ all
227 // make the rendered width equal the col's style width, reducing the
228 // cells' calculated width.
229 var colgroup = this._colgroupNode,
230 col = colgroup && colgroup.all('col').item(colIndex),
234 if (width && isNumber(width)) {
238 col.setStyle('width', width);
240 // Adjust the width for browsers that make
241 // td.style.width === col.style.width
242 if (width && Y.Features.test('table', 'badColWidth')) {
243 cell = this.getCell([0, colIndex]);
246 getCStyle = function (prop) {
247 return parseInt(cell.getComputedStyle(prop), 10)||0;
250 col.setStyle('width',
252 parseInt(width, 10) -
253 getCStyle('paddingLeft') -
254 getCStyle('paddingRight') -
255 getCStyle('borderLeftWidth') -
256 getCStyle('borderRightWidth') + 'px');
264 Populates the table's `<colgroup>` with a `<col>` per item in the `columns`
265 attribute without children. It is assumed that these are the columns that
266 have data cells renderered for them.
268 @method _uiSetColumnWidths
272 _uiSetColumnWidths: function () {
277 var template = this.COL_TEMPLATE,
278 colgroup = this._colgroupNode,
279 columns = this._displayColumns,
283 colgroup = this._colgroupNode = this._createColumnGroup();
285 this._tableNode.insertBefore(
287 this._tableNode.one('> thead, > tfoot, > tbody'));
292 for (i = 0, len = columns.length; i < len; ++i) {
294 colgroup.append(template);
296 this._setColumnWidth(i, columns[i].width);
301 Y.DataTable.ColumnWidths = ColumnWidths;
303 Y.Base.mix(Y.DataTable, [ColumnWidths]);
305 Adds a style `width` setting to an associated `<col>`
306 element for the column.
308 Note, the assigned width will not truncate cell content, and
309 it will not preserve the configured width if doing so would
310 compromise either the instance's `width` configuration or
311 the natural width of the table's containing DOM elements.
313 If absolute widths are required, it can be accomplished with
314 some custom CSS and the use of a `cellTemplate`, or
317 See the description of
318 [datatable-column-widths](DataTable.ColumnWidths.html)
319 for an example of how to do this.
321 { key: 'a', width: '400px' },
322 { key: 'b', width: '10em' }
326 @for DataTable.Column
330 }, '3.13.0', {"requires": ["datatable-base"]});