+ DataTable and supporting modules were rebuilt in version 3.5.0. The + new architecture is not fully backward compatible with + versions 3.4.1 and prior. This guide is to help answer questions that + may come up when upgrading to the latest version. +
+ ++ This guide focuses on 3.4.1 API compatibility. It does not + describe new features added in 3.5.0 (there were a lot). + Refer to the updated DataTable user guide for + that. +
+ +
+ If you are unable to upgrade due to unresolvable issues, you can use the
+ datatable-deprecated
+ module suite, which is equivalent to the 3.4.1 implementation. But be
+ aware that these modules will be removed in a future version of YUI.
+
Overview of API changes from 3.4.1
+ ++ The architectural change resulted in the deprecation, replacement, or + removal of nearly all attributes and properties from the version 3.4.1 + implementation. Here is a quick list of the changes most likely to affect + your upgrade: +
+ +-
+
-
+
new Y.DataTable.Base(...)→ +new Y.DataTable({ ... })+
+ -
+ ++++
new Y.DataTable.Base({ + columnset: [ ... ], + recordset: [ ... ] +});+ +→
+++new Y.DataTable({ + columns: [ ... ], + data : [ ... ] +});+ +
+ -
+ (cells rendered as HTML by default) →
+
columns: [ { key: 'email', allowHTML: true }, ... ]+
+ -
+
table.plug(Y.Plugin.DataTableSort)→ (plugin not needed) + See below or read + the user guide +
+ -
+
table.plug(Y.Plugin.DataTableScroll, ...)→ + (plugin not needed) + See below or read + the user guide +
+ -
+
columnset: [ { formatter: function (o) { ... } } ]+ → + (formatter changes) + See below or read + the user guide +
+ -
+
record.getValue(fieldName)→ +record.get(fieldName)+
+
Instantiation and Instance Configuration Changes
+ +
+ As of 3.5.0, Y.DataTable is no longer just a namespace, but is now the
+ preferred constructor for DataTable instances.
+
var table = new Y.DataTable({
+ // Column configuration looks much the same except the attribute name
+ columns: [
+ { key: 'name', label: 'Name', sortable: true, width: '200px' },
+ {
+ key: 'birthdate',
+ label: 'Age',
+ sortable: true,
+ formatter: function (o) {
+ var now = new Date(),
+ years = now.getYear() - o.value.getYear();
+
+ now.setYear(o.value.getYear());
+
+ return years - (o.value < now);
+ }
+ }
+ ],
+ // Passing in row data looks much the same except the attribute name
+ data: [
+ { name: 'Tom Brokaw', birthdate: new Date(1940, 1, 6) },
+ { name: 'Peter Jennings', birthdate: new Date(1938, 6, 29) },
+ { name: 'Katie Couric', birthdate: new Date(1957, 1, 7) },
+ { name: 'Brian Williams', birthdate: new Date(1958, 4, 5) },
+ { name: 'Matt Lauer', birthdate: new Date(1957, 11, 30) }
+ ]
+}).render('#over-there');
+
+
+
+ The Y.DataTable.Base class still exists, but is useful primarily as a
+ superclass for extension. The attributes of Y.DataTable.Base are the
+ same as those of Y.DataTable, less any attributes added by class
+ extensions (see below).
+
+ Configuration attributes that have changed from 3.4.1 are: +
+ +| Attribute | +Change | +
|---|---|
columnset |
+
+ Deprecated. Use columns. columnset will
+ behave as an alias for columns for a short time, but will be
+ removed in future versions. See below.
+ |
+
recordset |
+
+ Deprecated. Use data. recordset will
+ behave as an alias for data for a short time, but will be
+ removed in future versions. See below.
+ |
+
tdValueTemplate |
+
+ Removed. Use column formatter, cellTemplate,
+ or override the Y.DataTable.BodyView instance's CELL_TEMPLATE.
+ |
+
thValueTemplate |
+
+ Removed. Use column label, headerTemplate,
+ or override the Y.DataTable.HeaderView instance's CELL_TEMPLATE.
+ |
+
trTemplate |
+
+ Removed. Use column nodeFormatter or override
+ the Y.DataTable.BodyView instance's ROW_TEMPLATE.
+ |
+
Table and Cell Formatting Changes
+ ++ The following changes apply to table and column cell formatting: +
+ +-
+
-
+ If cell values include HTML, add
allowHTML: trueto the column + configuration. HTML is escaped by default for security. +
+ -
+
o.classnamesin the formatter parameter is nowo.className. +
+ -
+
o.columnin the formatter parameter is now the + plain JavaScript object containing the column configurations rather + than aY.Columninstance. +
+ -
+
o.recordin the formatter parameter is now a Model + instance instead of aY.Recordinstance. +
+ -
+
this.createCell(o),o.td,o.tr, ando.tbodyno longer exist on + the parameter passed toformatterfunctions. Use +nodeFormatters. +
+ -
+
o.headersis now ato.column._headers, but is read-only for +formatterfunctions. If you need to change the cell's headers + attribute, add a {placeholder} for them to a customcellTemplatefor + the column, or use anodeFormatter. +
+ -
+ The table's
tdValueTemplate,thValueTemplate, andtrTemplateno + longer exist, nor do the DataTable instance propertiestdTemplateand +thTemplate. Useformatterstrings or functions to customize the + content of data cells in a column andlabelstrings to customize the + content of header cells. To modify the<td>or<th>entirely, set + the column configurationcellTemplateorheaderTemplate. +
+
3.4.1
+ +var table = new Y.DataTable.Base({
+ columnset: [
+ { key: "id",
+ emptyCellValue: "<em>new</em>" },
+ { key: "name" },
+ { key: "price", formatter: "${value}" },
+ { key: "price",
+ formatter: function (o) {
+ if (o.value > 4) {
+ o.classnames += "spendy";
+ }
+ return '$' + o.value.toFixed(2);
+ }
+ },
+ { key: "price",
+ formatter: function (o) {
+ var cell = this.createCell(o);
+
+ if (o.value > 4) {
+ cell.addClass('spendy');
+ }
+
+ cell.setHTML('$' + o.value);
+ }
+ }
+ ],
+ data: [
+ { id: 1, name: "Bread", price: 3.45 },
+ { id: 2, name: "Milk", price: 4.99 },
+ { id: 3, name: "Eggs", price: 2.75 }
+ ]
+}).render("#over-there");
+
+ 3.5.0
+ +var table = new Y.DataTable({
+ columns: [
+ { key: "id",
+ emptyCellValue: "<em>new</em>",
+ allowHTML: true },
+ { key: "name" },
+ { key: "price", formatter: "${value}" },
+ { key: "price",
+ formatter: function (o) {
+ if (o.value > 4) {
+ o.className += "spendy";
+ }
+ return '$' + o.value.toFixed(2);
+ }
+ },
+ { key: "price",
+ nodeFormatter: function (o) {
+ if (o.value > 4) {
+ o.cell.addClass('spendy');
+ }
+
+ o.cell.setHTML('$' + o.value);
+
+ return false;
+ }
+ }
+ ],
+ data: [
+ { id: 1, name: "Bread", price: 3.45 },
+ { id: 2, name: "Milk", price: 4.99 },
+ { id: 3, name: "Eggs", price: 2.75 }
+ ]
+}).render("#over-there");
+
+ + Read the Formatting Cell Data section in + the DataTable user guide for more details. +
+ +Column Configuration Changes
+ +
+ As of 3.5.0, the Y.Columnset and Y.Column classes have been deprecated.
+ The DataTable configuration attribute columnset has been deprecated in
+ favor of the columns attribute. The columnset attribute has been
+ retained for partial backward compatibility. Columns are now
+ stored as an array of simple JavaScript objects rather than class instances.
+
var table = new Y.DataTable({
+ columnset: [ 'name', 'age' ],
+ ...
+});
+
+// columnset passes through to columns
+var columns = table.get('columns'); // => Array, not Columnset instance
+
+table.set('columnset', [ ... (new column configurations) ... ]);
+
+// backward compatibility stops here
+var columnset = table.get('columnset'); // => Array, not Columnset instance
+
+
+
+ Strings passed into the column configuration will become objects with those
+ strings as the value of the key property.
+
+ See the Column configuration section in + the user guide for more details. +
+ +Row Data Configuration Changes
+ +
+ As of 3.5.0, DataTable uses Y.Model and Y.ModelList to store row data.
+ Y.Recordset and Y.Record haven't been deprecated, but may be in the
+ future. The recordset attribute has been retained for partial
+ backward compatibility. The data ModelList can be assigned to, but
+ retrieving the value of the attribute will return the ModelList, not
+ a Y.Recordset instance.
+
var table = new Y.DataTable({
+ columnset: [ ... ],
+ recordset: [
+ { name: 'Tom Brokaw', birthdate: new Date(1940, 1, 6) },
+ { name: 'Peter Jennings', birthdate: new Date(1938, 6, 29) },
+ { name: 'Katie Couric', birthdate: new Date(1957, 1, 7) },
+ ...
+ ]
+});
+
+// recordset passes through to data.
+var data = table.get('data'); // => ModelList instance
+
+table.set('recordset', [ ... (new data records) ... ]);
+
+// backward compatibility stops here
+var recordset = table.get('recordset'); // => ModelList, not Recordset
+
+
+
+ Y.Record stores all values in a single attribute named data, where Y.Model uses individual attributes for each value.
+
3.4.1
+ +// Y.Record
+var record = oldTable.get('recordset').item(0);
+
+record.getValue('birthdate'); // => Date(1940, 1, 6)
+record.get('data').birthdate; // => same
+
+ 3.5.0
+// Y.Model
+var model = newTable.getRecord(0);
+
+model.get('birthdate'); // => Date(1940, 1, 6)
+
+
+ This change breaks column/record keys that contain periods.
+ Attribute treats periods as subproperty indicators, so periods are no
+ longer allowed; use an alternate character. In the case of remote data
+ that is parsed by Y.Plugin.DataSourceJSONSchema, use the locator
+ configuration for fields to extract subproperty values. A benefit to doing
+ this is that you may not need to specify a column label.
+
3.4.1
+ +var table = new Y.DataTable.Base({
+ columnset: [
+ { key: "id" },
+ { key: "Product.Name", label: "Product" },
+ { key: "Product.Price", label: "Price" }
+ ],
+ caption: "Price List"
+}).plug(Y.Plugin.DataTableDataSource, {
+ datasource: new Y.DataSource.IO({
+ source: "/service/price-list"
+ }).plug(Y.Plugin.DataSourceJSONSchema, {
+ schema: {
+ resultListLocator: "items",
+ resultFields: [
+ { key: "id" },
+ { key: "Product.Name" },
+ { key: "Product.Price" }
+ ]
+ }
+ })
+});
+
+table.datasource.load(...);
+
+ 3.5.0
+ +var table = new Y.DataTable({
+ columns: [ "id", "Product", "Price" ],
+ caption: "Price List"
+}).plug(Y.Plugin.DataTableDataSource, {
+ datasource: new Y.DataSource.IO({
+ source: "/service/price-list"
+ }).plug(Y.Plugin.DataSourceJSONSchema, {
+ schema: {
+ resultListLocator: "items",
+ resultFields: [
+ { key: "id" },
+ { key: "Product",
+ locator: "Product.Name" },
+ { key: "Price",
+ locator: "Product.Price" }
+ ]
+ }
+ })
+});
+
+table.datasource.load(...);
+
+ + If you are using any Recordset plugins, your code will need to be modified. + Some loss of functionality may result. +
+ +-
+
Y.Plugin.RecordsetSort
+ -
+ This plugin was formerly applied by the
Y.Plugin.DataTableSortplugin + to the DataTable's Recordset instance. Sorting is now enabled + through a class extension. +
+
+ Y.Plugin.RecordsetFilter
+ -
+ The default ModelList implementation only supports a
filter(function)+ method. If you were relying on this plugin'sgreporreject+ methods or thefilter(key, value)functionality, you will need to + replace that functionality through custom code. +
+
+ Y.Plugin.RecordsetIndexer
+ -
+ The default ModelList implementation does not support multiple custom
+ indexes, though it does maintain an index for
id(or another, + assigned primary key attribute) andclientId. See + the Model user guide for more + information on customizing the primary index. If multiple custom + indexes are required, DataTable supports the use of + custom Model subclasses to store the record + data. +
+
+
+
+ See the Data Configuration section of the DataTable + user guide for more information. +
+ +Feature Configuration Changes
+ +
+ The two optional features available for DataTable in 3.4.1 were sorting and
+ scrolling. Both features exist in 3.5.0, but are implemented as class
+ extensions for Y.DataTable. Simply including the datatable-sort or
+ datatable-scroll module in your use(...) will enable the feature for
+ all new DataTables.
+
YUI().use('datatable-sort', 'datatable-scroll', function (Y) {
+
+ // Create a DataTable that is sortable by the "name" column, and is
+ // configured to scroll vertically within 300px. Because scrollable is
+ // set to "y", not "x" or "xy", it will not attempt to scroll horizontally.
+ // Instead the table width will be set to 100%.
+ var table = new Y.DataTable({
+ columns : [ { key: 'name', sortable: true }, ... ],
+ data : [ ... ],
+ scrollable: "y",
+ height : "300px",
+ width : "100%"
+ });
+
+ // No plugins necessary
+ table.render('#over-there');
+});
+
+
+Column Sorting Changes
+ +
+ Configuring sortable columns may be done as it was in 3.4.1, by setting the
+ column configuration property sortable: true, but may also be done by
+ setting the DataTable's sortable configuration to true or an array of
+ column names.
+
3.4.1
+ +// Assumes use('datatable-sort') or use('datatable')
+var table = new Y.DataTable.Base({
+ columnset: [
+ { key: "id" },
+ { key: "name", sortable: true },
+ { key: "price", sortable: true }
+ ],
+ recordset: [
+ { id: 1, name: "Bread", price: 3.45 },
+ { id: 2, name: "Milk", price: 4.99 },
+ { id: 3, name: "Eggs", price: 2.75 },
+ ...
+ ],
+ caption: "Price List"
+});
+
+table.plug(Y.Plugin.DataTableSort);
+
+table.render('#sort-demo');
+
+// Sorting API is on the Recordset's plugin
+table.get("recordset").sort.sort("name");
+
+ 3.5.0
+ +// Assumes use('datatable-sort') or use('datatable')
+var table = new Y.DataTable({
+ columns: [ "id", "name", "price" ],
+ data: [
+ { id: 1, name: "Bread", price: 3.45 },
+ { id: 2, name: "Milk", price: 4.99 },
+ { id: 3, name: "Eggs", price: 2.75 },
+ ...
+ ],
+ sortable: [ "name", "price" ]
+});
+
+table.render('#sort-demo');
+
+// Sort method is on the instance
+table.sort("name");
+
+//-------------------------------------------------
+// Alternate methods
+//-------------------------------------------------
+
+var table = new Y.DataTable({
+ columns: [ "id", "name", "price" ],
+ data: [ ... ],
+ sortable: true // makes all columns sortable
+});
+
+// OR the old way works, too
+var table = new Y.DataTable({
+ columns: [
+ { key: "id" },
+ { key: "name", sortable: true },
+ { key: "price", sortable: true }
+ ],
+ data: [ ... ]
+});
+
+
+ Since there is no plugin, the sort method is now on the DataTable instance
+ itself, as are the related attributes. In particular, the lastSortedBy
+ attribute from the plugin implementation has been replaced by the sortBy
+ attribute added by the class extension.
+
+ As of 3.5.0, DataTables configured with sortBy will have their rows
+ sorted automatically upon inserting into the table. You do not need to
+ presort data for the initial render.
+
+ The trigger attribute of the sorting plugin was not retained in
+ the 3.5.0 class extension. If you require an alternate triggering
+ event, detach and replace the table's _sortHandle property after
+ render().
+
var table = new Y.DataTable({ ... }).render("#over-there");
+
+table._sortHandle.detach();
+table._sortHandle = table.delegate(["dblclick", "keydown"],
+ table._onUITriggerSort, ".yui3-datatable-sortable-column", table);
+
+
++ See the Column Sorting section of the + user guide for details about the APIs and attributes. +
+ +Scrollable Table Changes
+ +
+ Like sorting, the scrolling functionality has been moved to a class
+ extension, making it unnecessary to plug the DataTable instance with the
+ (now deprecated) Y.Plugin.DataTableScroll plugin.
+
+ datatable-scroll is no longer included in the datatable
+ rollup, and must be explicitly included in your use() statement.
+
+ To enable scrolling in 3.5.0, set the table's scrollable attribute to "x",
+ "y", or "xy". The configured height and width for the DataTable are
+ used to bound the overall widget dimesions. Scrolling will only be applied
+ on the axis or axes specified in scrollable. However, if scrollable is
+ set to "y", but the height isn't set, it will not be made scrollable.
+ Likewise for "x" and width.
+
3.4.1
+ +// Assumes use("datatable-scroll") or use("datatable")
+var table = new Y.DataTable.Base({
+ columnset: ["id", "name", "price"],
+ recordset: [
+ { id: 1, name: "Bread", price: 3.45 },
+ { id: 2, name: "Milk", price: 4.99 },
+ { id: 3, name: "Eggs", price: 2.75 },
+ ...
+ ]
+});
+
+table.plug(Y.Plugin.DataTableScroll, {
+ height: "175px"
+});
+
+table.render("#over-there");
+
+ 3.5.0
+ +// Assumes use("datatable-scroll")
+var table = new Y.DataTable({
+ columns: ["id", "name", "price"],
+ data: [
+ { id: 1, name: "Bread", price: 3.45 },
+ { id: 2, name: "Milk", price: 4.99 },
+ { id: 3, name: "Eggs", price: 2.75 },
+ ...
+ ],
+ scrollable: "y",
+ height: "175px"
+}).render("#over-there");
+
+ Markup and CSS Changes
+ +
+ DataTable in 3.5.0 applies more CSS classes to Nodes, stamps fewer nodes
+ with guid ids, and does not render header and cell liner <div>s.
+
+ Below are examples of the same table rendered in 3.4.1 and 3.5.0. The 3.5.0 + table has comments indicating markup added by feature modules. +
+ +3.4.1
+<div id="(guid)" class="yui3-widget yui3-datatable"> + <div id="(guid)" class="yui3-datatable-content"> + <table> + + <caption> + Example table with simple columns + </caption> + + <colgroup> + <col> + <col> + <col> + </colgroup> + + <thead class="yui3-datatable-columns"> + <tr id="" class="yui3-datatable-first yui3-datatable-last"> + <th id="(guid)" rowspan="1" colspan="1" class="yui3-column-id" abbr=""> + <div class="yui3-datatable-liner"> + id + </div> + </th> + <th id="(guid)" rowspan="1" colspan="1" class="yui3-column-name" abbr=""> + <div class="yui3-datatable-liner"> + name + </div> + </th> + <th id="(guid)" rowspan="1" colspan="1" class="yui3-column-price" abbr=""> + <div class="yui3-datatable-liner"> + price + </div> + </th> + </tr> + </thead> + + <tbody class="yui3-datatable-msg"> + </tbody> + + <tbody class="yui3-datatable-data" id="(guid)"> + <tr id="(guid)" class="yui3-datatable-even"> + <td headers="(guid)" class="yui3-column-id"> + <div class="yui3-datatable-liner"> + 1 + </div> + </td> + <td headers="(guid)" class="yui3-column-name"> + <div class="yui3-datatable-liner"> + Bread + </div> + </td> + <td headers="(guid)" class="yui3-column-price"> + <div class="yui3-datatable-liner"> + 3.45 + </div> + </td> + </tr> + <tr id="(guid)" class="yui3-datatable-odd"> + <td headers="(guid)" class="yui3-column-id"> + <div class="yui3-datatable-liner"> + 2 + </div> + </td> + <td headers="(guid)" class="yui3-column-name"> + <div class="yui3-datatable-liner"> + Milk + </div> + </td> + <td headers="(guid)" class="yui3-column-price"> + <div class="yui3-datatable-liner"> + 4.99 + </div> + </td> + </tr> + <tr id="(guid)" class="yui3-datatable-even"> + <td headers="(guid)" class="yui3-column-id"> + <div class="yui3-datatable-liner"> + 3 + </div> + </td> + <td headers="(guid)" class="yui3-column-name"> + <div class="yui3-datatable-liner"> + Eggs + </div> + </td> + <td headers="(guid)" class="yui3-column-price"> + <div class="yui3-datatable-liner"> + 2.75 + </div> + </td> + </tr> + </tbody> + + </table> + </div> +</div>+ + +
3.5.0
+<div id="(guid)" class="yui3-widget yui3-datatable"> + <div id="(guid)" class="yui3-datatable-content"> + <table cellspacing="0" class="yui3-datatable-table" id="(guid)"> + + <caption class="yui3-datatable-caption"> + Price List + </caption> + + <!-- colgroup only renders if datatable-column-widths is use()d. + Note, datatable-column-widths is included in the datatable rollup --> + <colgroup id="(guid)"> + <col> + <col> + <col> + </colgroup> + + <thead class="yui3-datatable-columns" id="(guid)"> + <tr> + <th id="(guid)" colspan="1" rowspan="1" class="yui3-datatable-header yui3-datatable-first-header yui3-datatable-col-id" scope="col" data-yui3-col-id="id"> + id + </th> + <th id="(guid)" colspan="1" rowspan="1" class="yui3-datatable-header yui3-datatable-col-name" scope="col" data-yui3-col-id="name"> + name + </th> + <th id="(guid)" colspan="1" rowspan="1" class="yui3-datatable-header yui3-datatable-col-price" scope="col" data-yui3-col-id="price"> + price + </th> + </tr> + </thead> + + <!-- The message tbody only renders if datatable-message is use()d. + Note, datatable-message is included in the datatable rollup --> + <tbody class="yui3-datatable-message" id="(guid)"> + <tr> + <td class="yui3-datatable-message-content" colspan="3"> + No data to display + </td> + </tr> + </tbody> + + <tbody class="yui3-datatable-data"> + <tr id="(guid)" data-yui3-record="record_1" class="yui3-datatable-even"> + <td class="yui3-datatable-col-id yui3-datatable-cell"> + 1 + </td> + <td class="yui3-datatable-col-name yui3-datatable-cell"> + Bread + </td> + <td class="yui3-datatable-col-price yui3-datatable-cell"> + 3.45 + </td> + </tr> + <tr id="(guid)" data-yui3-record="record_2" class="yui3-datatable-odd"> + <td class="yui3-datatable-col-id yui3-datatable-cell"> + 2</td> + <td class="yui3-datatable-col-name yui3-datatable-cell"> + Milk + </td> + <td class="yui3-datatable-col-price yui3-datatable-cell"> + 4.99 + </td> + </tr> + <tr id="(guid)" data-yui3-record="record_3" class="yui3-datatable-even"> + <td class="yui3-datatable-col-id yui3-datatable-cell"> + 3 + </td> + <td class="yui3-datatable-col-name yui3-datatable-cell"> + Eggs + </td> + <td class="yui3-datatable-col-price yui3-datatable-cell"> + 2.75 + </td> + </tr> + </tbody> + + </table> + </div> +</div>+ + +
What Did I Miss?
+ ++ Obviously, there were a lot of changes to DataTable from 3.4.1 to 3.5.0. + It's entirely likely that I have missed something here. If you experience + trouble with your upgrade and find this migration guide is missing + something important, please file a + ticket and I'll update it as soon as possible. +
+ ++ Additional resources to help with the upgrade include the + forums, and the #yui IRC channel on freenode.net. +
+