| 1 | efrain | 1 | YUI.add('datatable-column-widths', function (Y, NAME) {
 | 
        
           |  |  | 2 |   | 
        
           |  |  | 3 | /**
 | 
        
           |  |  | 4 | Adds basic, programmatic column width support to DataTable via column
 | 
        
           |  |  | 5 | configuration property `width` and method `table.setColumnWidth(id, width);`.
 | 
        
           |  |  | 6 |   | 
        
           |  |  | 7 | @module datatable
 | 
        
           |  |  | 8 | @submodule datatable-column-widths
 | 
        
           |  |  | 9 | @since 3.5.0
 | 
        
           |  |  | 10 | **/
 | 
        
           |  |  | 11 | var isNumber = Y.Lang.isNumber,
 | 
        
           |  |  | 12 |     arrayIndex = Y.Array.indexOf;
 | 
        
           |  |  | 13 |   | 
        
           |  |  | 14 | Y.Features.add('table', 'badColWidth', {
 | 
        
           |  |  | 15 |     test: function () {
 | 
        
           |  |  | 16 |         var body = Y.one('body'),
 | 
        
           |  |  | 17 |             node, broken;
 | 
        
           |  |  | 18 |   | 
        
           |  |  | 19 |         if (body) {
 | 
        
           |  |  | 20 |             // In modern browsers, <col style="width:X"> will make columns,
 | 
        
           |  |  | 21 |             // *including padding and borders* X wide. The cell content width
 | 
        
           |  |  | 22 |             // is reduced.  In old browsers and all Opera versions to date, the
 | 
        
           |  |  | 23 |             // col's width style is passed to the cells, which causes cell
 | 
        
           |  |  | 24 |             // padding/border to bloat the rendered width.
 | 
        
           |  |  | 25 |             node = body.insertBefore(
 | 
        
           |  |  | 26 |                 '<table style="position:absolute;visibility:hidden;border:0 none">' +
 | 
        
           |  |  | 27 |                     '<colgroup><col style="width:9px"></colgroup>' +
 | 
        
           |  |  | 28 |                     '<tbody><tr>' +
 | 
        
           |  |  | 29 |                         '<td style="' +
 | 
        
           |  |  | 30 |                             'padding:0 4px;' +
 | 
        
           |  |  | 31 |                             'font:normal 2px/2px arial;' +
 | 
        
           |  |  | 32 |                             'border:0 none">' +
 | 
        
           |  |  | 33 |                         '.' + // Just something to give the cell dimension
 | 
        
           |  |  | 34 |                     '</td></tr></tbody>' +
 | 
        
           |  |  | 35 |                 '</table>',
 | 
        
           |  |  | 36 |                 body.get('firstChild'));
 | 
        
           |  |  | 37 |   | 
        
           |  |  | 38 |             broken = node.one('td').getComputedStyle('width') !== '1px';
 | 
        
           |  |  | 39 |   | 
        
           |  |  | 40 |             node.remove(true);
 | 
        
           |  |  | 41 |         }
 | 
        
           |  |  | 42 |   | 
        
           |  |  | 43 |         return broken;
 | 
        
           |  |  | 44 |     }
 | 
        
           |  |  | 45 | });
 | 
        
           |  |  | 46 |   | 
        
           |  |  | 47 | /**
 | 
        
           |  |  | 48 | _API docs for this extension are included in the DataTable class._
 | 
        
           |  |  | 49 |   | 
        
           |  |  | 50 | Adds basic, programmatic column width support to DataTable. Note, this does not
 | 
        
           |  |  | 51 | add support for truncated columns.  Due to the way HTML tables render, column
 | 
        
           |  |  | 52 | width is more like a "recommended width".  Column content wider than the
 | 
        
           |  |  | 53 | assigned width will cause the column to expand, despite the configured width.
 | 
        
           |  |  | 54 | Similarly if the table is too narrow to fit the column with the configured
 | 
        
           |  |  | 55 | column width, the column width will be reduced.
 | 
        
           |  |  | 56 |   | 
        
           |  |  | 57 | To set a column width, either add a `width` value to the column configuration
 | 
        
           |  |  | 58 | or call the `setColumnWidth(id, width)` method.
 | 
        
           |  |  | 59 |   | 
        
           |  |  | 60 | Note, assigning column widths is possible without this module, as each cell is
 | 
        
           |  |  | 61 | decorated with a class appropriate for that column which you can statically
 | 
        
           |  |  | 62 | target in your site's CSS.
 | 
        
           |  |  | 63 |   | 
        
           |  |  | 64 | To achieve absolute column widths, with content truncation, you can either:
 | 
        
           |  |  | 65 |   | 
        
           |  |  | 66 | 1. Use this module, configure *all* columns to have `width`s, then add
 | 
        
           |  |  | 67 |    `table-layout: fixed;` to your CSS for the appropriate `<table>`, or
 | 
        
           |  |  | 68 | 2. Wrap the contents of all cells in the column with a `<div>` (using a
 | 
        
           |  |  | 69 |    `cellTemplate` or `formatter`), assign the div's style `width`, then assign
 | 
        
           |  |  | 70 |    the column `width` or add a CSS `width` to the column class created by
 | 
        
           |  |  | 71 |    DataTable.
 | 
        
           |  |  | 72 |   | 
        
           |  |  | 73 | <pre><code>.yui3-datatable .yui3-datatable-col-foo {
 | 
        
           |  |  | 74 |     padding: 0;
 | 
        
           |  |  | 75 |     width: 125px;
 | 
        
           |  |  | 76 | }
 | 
        
           |  |  | 77 | .yui3-datatable .yui3-datatable-col-foo .yui3-datatable-liner {
 | 
        
           |  |  | 78 |     overflow: hidden;
 | 
        
           |  |  | 79 |     padding: 4px 10px;
 | 
        
           |  |  | 80 |     width: 125px;
 | 
        
           |  |  | 81 | }
 | 
        
           |  |  | 82 | </pre></code>
 | 
        
           |  |  | 83 |   | 
        
           |  |  | 84 | <pre><code>var table = new Y.DataTable({
 | 
        
           |  |  | 85 |     columns: [
 | 
        
           |  |  | 86 |         {
 | 
        
           |  |  | 87 |             key: 'foo',
 | 
        
           |  |  | 88 |             cellTemplate:
 | 
        
           |  |  | 89 |                 '<td class="{className}">' +
 | 
        
           |  |  | 90 |                     '<div class="yui3-datatable-liner">{content}</div>' +
 | 
        
           |  |  | 91 |                 '</td>'
 | 
        
           |  |  | 92 |         },
 | 
        
           |  |  | 93 |         ...
 | 
        
           |  |  | 94 |     ],
 | 
        
           |  |  | 95 |     ...
 | 
        
           |  |  | 96 | });
 | 
        
           |  |  | 97 | </code></pre>
 | 
        
           |  |  | 98 |   | 
        
           |  |  | 99 | To add a liner to all columns, either provide a custom `bodyView` to the
 | 
        
           |  |  | 100 | DataTable constructor or update the default `bodyView`'s `CELL_TEMPLATE` like
 | 
        
           |  |  | 101 | so:
 | 
        
           |  |  | 102 |   | 
        
           |  |  | 103 | <pre><code>table.on('table:renderBody', function (e) {
 | 
        
           |  |  | 104 |     e.view.CELL_TEMPLATE = e.view.CELL_TEMPLATE.replace(/\{content\}/,
 | 
        
           |  |  | 105 |             '<div class="yui3-datatable-liner">{content}</div>');
 | 
        
           |  |  | 106 | });
 | 
        
           |  |  | 107 | </code></pre>
 | 
        
           |  |  | 108 |   | 
        
           |  |  | 109 | Keep in mind that DataTable skins apply cell `padding`, so assign your CSS
 | 
        
           |  |  | 110 | `width`s accordingly or override the `padding` style for that column's `<td>`s
 | 
        
           |  |  | 111 | to 0, and add `padding` to the liner `<div>`'s styles as shown above.
 | 
        
           |  |  | 112 |   | 
        
           |  |  | 113 | @class DataTable.ColumnWidths
 | 
        
           |  |  | 114 | @for DataTable
 | 
        
           |  |  | 115 | @since 3.5.0
 | 
        
           |  |  | 116 | **/
 | 
        
           |  |  | 117 | function ColumnWidths() {}
 | 
        
           |  |  | 118 |   | 
        
           |  |  | 119 | Y.mix(ColumnWidths.prototype, {
 | 
        
           |  |  | 120 |     /**
 | 
        
           |  |  | 121 |     The HTML template used to create the table's `<col>`s.
 | 
        
           |  |  | 122 |   | 
        
           |  |  | 123 |     @property COL_TEMPLATE
 | 
        
           |  |  | 124 |     @type {String}
 | 
        
           |  |  | 125 |     @default '<col/>'
 | 
        
           |  |  | 126 |     @since 3.5.0
 | 
        
           |  |  | 127 |     **/
 | 
        
           |  |  | 128 |     COL_TEMPLATE: '<col/>',
 | 
        
           |  |  | 129 |   | 
        
           |  |  | 130 |     /**
 | 
        
           |  |  | 131 |     The HTML template used to create the table's `<colgroup>`.
 | 
        
           |  |  | 132 |   | 
        
           |  |  | 133 |     @property COLGROUP_TEMPLATE
 | 
        
           |  |  | 134 |     @type {String}
 | 
        
           |  |  | 135 |     @default '<colgroup/>'
 | 
        
           |  |  | 136 |     @since 3.5.0
 | 
        
           |  |  | 137 |     **/
 | 
        
           |  |  | 138 |     COLGROUP_TEMPLATE: '<colgroup/>',
 | 
        
           |  |  | 139 |   | 
        
           |  |  | 140 |     /**
 | 
        
           |  |  | 141 |     Assigns the style width of the `<col>` representing the column identifed by
 | 
        
           |  |  | 142 |     `id` and updates the column configuration.
 | 
        
           |  |  | 143 |   | 
        
           |  |  | 144 |     Pass the empty string for `width` to return a column to auto sizing.
 | 
        
           |  |  | 145 |   | 
        
           |  |  | 146 |     This does not trigger a `columnsChange` event today, but I can be convinced
 | 
        
           |  |  | 147 |     that it should.
 | 
        
           |  |  | 148 |   | 
        
           |  |  | 149 |     @method setColumnWidth
 | 
        
           |  |  | 150 |     @param {Number|String|Object} id The column config object or key, name, or
 | 
        
           |  |  | 151 |             index of a column in the host's `_displayColumns` array.
 | 
        
           |  |  | 152 |     @param {Number|String} width CSS width value. Numbers are treated as pixels
 | 
        
           |  |  | 153 |     @return {DataTable}
 | 
        
           |  |  | 154 |     @chainable
 | 
        
           |  |  | 155 |     @since 3.5.0
 | 
        
           |  |  | 156 |     **/
 | 
        
           |  |  | 157 |     setColumnWidth: function (id, width) {
 | 
        
           |  |  | 158 |         var col = this.getColumn(id),
 | 
        
           |  |  | 159 |             index = col && arrayIndex(this._displayColumns, col);
 | 
        
           |  |  | 160 |   | 
        
           |  |  | 161 |         if (index > -1) {
 | 
        
           |  |  | 162 |             if (isNumber(width)) {
 | 
        
           |  |  | 163 |                 width += 'px';
 | 
        
           |  |  | 164 |             }
 | 
        
           |  |  | 165 |   | 
        
           |  |  | 166 |             col.width = width;
 | 
        
           |  |  | 167 |   | 
        
           |  |  | 168 |             this._setColumnWidth(index, width);
 | 
        
           |  |  | 169 |         }
 | 
        
           |  |  | 170 |   | 
        
           |  |  | 171 |         return this;
 | 
        
           |  |  | 172 |     },
 | 
        
           |  |  | 173 |   | 
        
           |  |  | 174 |     //--------------------------------------------------------------------------
 | 
        
           |  |  | 175 |     // Protected properties and methods
 | 
        
           |  |  | 176 |     //--------------------------------------------------------------------------
 | 
        
           |  |  | 177 |     /**
 | 
        
           |  |  | 178 |     Renders the table's `<colgroup>` and populates the `_colgroupNode` property.
 | 
        
           |  |  | 179 |   | 
        
           |  |  | 180 |     @method _createColumnGroup
 | 
        
           |  |  | 181 |     @protected
 | 
        
           |  |  | 182 |     @since 3.5.0
 | 
        
           |  |  | 183 |     **/
 | 
        
           |  |  | 184 |     _createColumnGroup: function () {
 | 
        
           |  |  | 185 |         return Y.Node.create(this.COLGROUP_TEMPLATE);
 | 
        
           |  |  | 186 |     },
 | 
        
           |  |  | 187 |   | 
        
           |  |  | 188 |     /**
 | 
        
           |  |  | 189 |     Hooks up to the rendering lifecycle to also render the `<colgroup>` and
 | 
        
           |  |  | 190 |     subscribe to `columnChange` events.
 | 
        
           |  |  | 191 |   | 
        
           |  |  | 192 |     @method initializer
 | 
        
           |  |  | 193 |     @protected
 | 
        
           |  |  | 194 |     @since 3.5.0
 | 
        
           |  |  | 195 |     **/
 | 
        
           |  |  | 196 |     initializer: function () {
 | 
        
           |  |  | 197 |         this.after(['renderView', 'columnsChange'], this._uiSetColumnWidths);
 | 
        
           |  |  | 198 |     },
 | 
        
           |  |  | 199 |   | 
        
           |  |  | 200 |     /**
 | 
        
           |  |  | 201 |     Sets a columns's `<col>` element width style. This is needed to get around
 | 
        
           |  |  | 202 |     browser rendering differences.
 | 
        
           |  |  | 203 |   | 
        
           |  |  | 204 |     The colIndex corresponds to the item index of the `<col>` in the table's
 | 
        
           |  |  | 205 |     `<colgroup>`.
 | 
        
           |  |  | 206 |   | 
        
           |  |  | 207 |     To unset the width, pass a falsy value for the `width`.
 | 
        
           |  |  | 208 |   | 
        
           |  |  | 209 |     @method _setColumnWidth
 | 
        
           |  |  | 210 |     @param {Number} colIndex The display column index
 | 
        
           |  |  | 211 |     @param {Number|String} width The desired width
 | 
        
           |  |  | 212 |     @protected
 | 
        
           |  |  | 213 |     @since 3.5.0
 | 
        
           |  |  | 214 |     **/
 | 
        
           |  |  | 215 |     // TODO: move this to a conditional module
 | 
        
           |  |  | 216 |     _setColumnWidth: function (colIndex, width) {
 | 
        
           |  |  | 217 |         // Opera (including Opera Next circa 1/13/2012) and IE7- pass on the
 | 
        
           |  |  | 218 |         // width style to the cells directly, allowing padding and borders to
 | 
        
           |  |  | 219 |         // expand the rendered width.  Chrome 16, Safari 5.1.1, and FF 3.6+ all
 | 
        
           |  |  | 220 |         // make the rendered width equal the col's style width, reducing the
 | 
        
           |  |  | 221 |         // cells' calculated width.
 | 
        
           |  |  | 222 |         var colgroup  = this._colgroupNode,
 | 
        
           |  |  | 223 |             col       = colgroup && colgroup.all('col').item(colIndex),
 | 
        
           |  |  | 224 |             cell, getCStyle;
 | 
        
           |  |  | 225 |   | 
        
           |  |  | 226 |         if (col) {
 | 
        
           |  |  | 227 |             if (width && isNumber(width)) {
 | 
        
           |  |  | 228 |                 width += 'px';
 | 
        
           |  |  | 229 |             }
 | 
        
           |  |  | 230 |   | 
        
           |  |  | 231 |             col.setStyle('width', width);
 | 
        
           |  |  | 232 |   | 
        
           |  |  | 233 |             // Adjust the width for browsers that make
 | 
        
           |  |  | 234 |             // td.style.width === col.style.width
 | 
        
           |  |  | 235 |             if  (width && Y.Features.test('table', 'badColWidth')) {
 | 
        
           |  |  | 236 |                 cell = this.getCell([0, colIndex]);
 | 
        
           |  |  | 237 |   | 
        
           |  |  | 238 |                 if (cell) {
 | 
        
           |  |  | 239 |                     getCStyle = function (prop) {
 | 
        
           |  |  | 240 |                         return parseInt(cell.getComputedStyle(prop), 10)||0;
 | 
        
           |  |  | 241 |                     };
 | 
        
           |  |  | 242 |   | 
        
           |  |  | 243 |                     col.setStyle('width',
 | 
        
           |  |  | 244 |                         // I hate this
 | 
        
           |  |  | 245 |                         parseInt(width, 10) -
 | 
        
           |  |  | 246 |                         getCStyle('paddingLeft') -
 | 
        
           |  |  | 247 |                         getCStyle('paddingRight') -
 | 
        
           |  |  | 248 |                         getCStyle('borderLeftWidth') -
 | 
        
           |  |  | 249 |                         getCStyle('borderRightWidth') + 'px');
 | 
        
           |  |  | 250 |   | 
        
           |  |  | 251 |                 }
 | 
        
           |  |  | 252 |             }
 | 
        
           |  |  | 253 |         }
 | 
        
           |  |  | 254 |     },
 | 
        
           |  |  | 255 |   | 
        
           |  |  | 256 |     /**
 | 
        
           |  |  | 257 |     Populates the table's `<colgroup>` with a `<col>` per item in the `columns`
 | 
        
           |  |  | 258 |     attribute without children.  It is assumed that these are the columns that
 | 
        
           |  |  | 259 |     have data cells renderered for them.
 | 
        
           |  |  | 260 |   | 
        
           |  |  | 261 |     @method _uiSetColumnWidths
 | 
        
           |  |  | 262 |     @protected
 | 
        
           |  |  | 263 |     @since 3.5.0
 | 
        
           |  |  | 264 |     **/
 | 
        
           |  |  | 265 |     _uiSetColumnWidths: function () {
 | 
        
           |  |  | 266 |         if (!this.view) {
 | 
        
           |  |  | 267 |             return;
 | 
        
           |  |  | 268 |         }
 | 
        
           |  |  | 269 |   | 
        
           |  |  | 270 |         var template = this.COL_TEMPLATE,
 | 
        
           |  |  | 271 |             colgroup = this._colgroupNode,
 | 
        
           |  |  | 272 |             columns  = this._displayColumns,
 | 
        
           |  |  | 273 |             i, len;
 | 
        
           |  |  | 274 |   | 
        
           |  |  | 275 |         if (!colgroup) {
 | 
        
           |  |  | 276 |             colgroup = this._colgroupNode = this._createColumnGroup();
 | 
        
           |  |  | 277 |   | 
        
           |  |  | 278 |             this._tableNode.insertBefore(
 | 
        
           |  |  | 279 |                 colgroup,
 | 
        
           |  |  | 280 |                 this._tableNode.one('> thead, > tfoot, > tbody'));
 | 
        
           |  |  | 281 |         } else {
 | 
        
           |  |  | 282 |             colgroup.empty();
 | 
        
           |  |  | 283 |         }
 | 
        
           |  |  | 284 |   | 
        
           |  |  | 285 |         for (i = 0, len = columns.length; i < len; ++i) {
 | 
        
           |  |  | 286 |   | 
        
           |  |  | 287 |             colgroup.append(template);
 | 
        
           |  |  | 288 |   | 
        
           |  |  | 289 |             this._setColumnWidth(i, columns[i].width);
 | 
        
           |  |  | 290 |         }
 | 
        
           |  |  | 291 |     }
 | 
        
           |  |  | 292 | }, true);
 | 
        
           |  |  | 293 |   | 
        
           |  |  | 294 | Y.DataTable.ColumnWidths = ColumnWidths;
 | 
        
           |  |  | 295 |   | 
        
           |  |  | 296 | Y.Base.mix(Y.DataTable, [ColumnWidths]);
 | 
        
           |  |  | 297 | /**
 | 
        
           |  |  | 298 | Adds a style `width` setting to an associated `<col>`
 | 
        
           |  |  | 299 | element for the column.
 | 
        
           |  |  | 300 |   | 
        
           |  |  | 301 | Note, the assigned width will not truncate cell content, and
 | 
        
           |  |  | 302 | it will not preserve the configured width if doing so would
 | 
        
           |  |  | 303 | compromise either the instance's `width` configuration or
 | 
        
           |  |  | 304 | the natural width of the table's containing DOM elements.
 | 
        
           |  |  | 305 |   | 
        
           |  |  | 306 | If absolute widths are required, it can be accomplished with
 | 
        
           |  |  | 307 | some custom CSS and the use of a `cellTemplate`, or
 | 
        
           |  |  | 308 | `formatter`.
 | 
        
           |  |  | 309 |   | 
        
           |  |  | 310 | See the description of
 | 
        
           |  |  | 311 | [datatable-column-widths](DataTable.ColumnWidths.html)
 | 
        
           |  |  | 312 | for an example of how to do this.
 | 
        
           |  |  | 313 |   | 
        
           |  |  | 314 |     { key: 'a', width: '400px' },
 | 
        
           |  |  | 315 |     { key: 'b', width: '10em' }
 | 
        
           |  |  | 316 |   | 
        
           |  |  | 317 | @property width
 | 
        
           |  |  | 318 | @type String
 | 
        
           |  |  | 319 | @for DataTable.Column
 | 
        
           |  |  | 320 |  */
 | 
        
           |  |  | 321 |   | 
        
           |  |  | 322 |   | 
        
           |  |  | 323 | }, '3.18.1', {"requires": ["datatable-base"]});
 |