Ticket #2529975 (closed defect)

Reporter


Alberto Santini
Opened: 02/18/11
Last modified: 06/28/11
Status: closed
Type: defect
Resolution: duplicate
Duplicate of: #2529872

Owner


Luke Smith
Target Release: 3.4.0
Priority: P3 (normal)
Summary: DataSource and DataTableSort recordset.sort is undefined
Description:

In

datatable-sort.js -> _onEventSortColumn -> dt.get("recordset").sort.sort(field, dir === DESC, sorter)

it is displayed the following error:

dt.get("recordset").sort is undefined

Ref.: http://yuilibrary.com/forum/viewtopic.php?f=92&t=7180

Type: defect Observed in Version: 3.3.0
Component: DataTable Severity: S3 (normal)
Assigned To: Luke Smith Target Release: 3.4.0
Location: Library Code Priority: P3 (normal)
Tags: Relates To:
Browsers: N/A
URL:
Test Information:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>DataTable + DataSource + Scroll</title>
<style type="text/css">
/*margin and padding on body element
can introduce errors in determining
element position and are not recommended;
we turn them off as a foundation for YUI
CSS treatments. */
body {
margin:0;
padding:0;
}</style>
<link type="text/css" rel="stylesheet" href="http://yui.yahooapis.com/3.3.0/build/cssfonts/fonts-min.css" />
<script type="text/javascript" src="http://yui.yahooapis.com/3.3.0/build/yui/yui-min.js"></script>

<!--begin custom header content for this example-->
<style type="text/css">
/* custom styles for this example */
.dt-example {margin:1em;}
/* css to counter global site css */
.dt-example th {text-transform:none;}
.dt-example table {width:auto;}
.dt-example caption {display:table-caption;}
</style>
<!--end custom header content for this example-->
</head>
<body class="yui3-skin-sam yui-skin-sam">
<h1>DataTable + DataSource + Scroll</h1>
<!--BEGIN SOURCE CODE FOR EXAMPLE =============================== -->
<div id="pizza" class="dt-example"></div>

<script type="text/javascript">
YUI({
filter: 'raw'
}).use("datasource", "datatable", function (Y) {
var myData = {
"dummy": [
{
"field1": 10,
"field2": "y",
},
{
"field1": 9,
"field2": "n",
}
]
},
cols = [
{key: "field1", label: "FIELD1", sortable: true},
{key: "field2", label: "FIELD2", sortable: true}
],
ds, dt;

ds = new Y.DataSource.Local({source: myData});

ds.plug(Y.Plugin.DataSourceJSONSchema, {
schema: {
resultListLocator: "dummy",
resultFields: ["field1", "field2"]
}
});

dt = new Y.DataTable.Base({
columnset: cols,
}).plug(Y.Plugin.DataTableDataSource, {
datasource: ds
}).plug(Y.Plugin.DataTableSort, {
lastSortedBy: {
field: "field1",
dir: "asc"
}
}).render("#pizza");

dt.datasource.load();
});
</script>
<!--END SOURCE CODE FOR EXAMPLE =============================== -->


</body>
</html>

Change History

Alberto Santini

YUI Contributor

Posted: 02/18/11

It seems the recordset is correctly initialized in "initializer" method of datatable-scroll:

dt.get("recordset").plug(Y.Plugin.RecordsetSort, {dt: dt});

Then in _onEventSortColumn method it seems the recordset is another one and it has not "sort" property.

dt.get("recordset").sort.sort(field, dir === DESC, sorter);

(dt.get("recordset").sort --> undefined)

Maybe DataTableDataSource plugin overwrites the recordset in onDataReturnInitializeTable method.

Alberto Santini

YUI Contributor

Posted: 02/18/11

Workaround:


dt = new Y.DataTable.Base({
columnset: cols,
}).plug(Y.Plugin.DataTableDataSource, {
datasource: ds
}).render("#pizza");

dt.datasource.onDataReturnInitializeTable = function (e) {
this.get("host").set("recordset", new Y.Recordset({records: e.response.results}));
this.get("host").plug(Y.Plugin.DataTableSort, {
lastSortedBy: {
field: "field1",
dir: "asc"
}
});
}

Luke Smith

YUI Contributor

Posted: 02/18/11

Adrian Lanning

YUI Contributor

Posted: 02/19/11

This issue also occurs without using a DataSource when setting the datatable's recordset property if the base Y.RecordSet is used.

A workaround that I use is as follows:


// snippet from a MasterView widget that has a datatable

refresh : function() {
var index = this.selectedRecordIndex();

var dataArray = this.getData();
var set = new Y.Recordset({records: dataArray});

// otherwise sort plugin breaks on next column sort
set.plug(Y.Plugin.RecordsetSort, {dt: this._dataTable});
set.sort.addTarget(this._dataTable);

this._dataTable.set('recordset', set);

this.selectTR(index);
}

This is a kind of "multi-inheritance" problem and I can see how it would come up quite often with any plugin that modifies RecordSet. One suggestion would be to have the DataTable itself have a reference to a RecordSet constructor and then have plugins register new constructors as added. Then we can create new RecordSets of the appropriate type by using the DT field:
eg. var newSet = new myDT.RecordSetType({records: dataArray})

Would have to chain constructor calls so not sure what issues that would raise.

Luke Smith

YUI Contributor

Posted: 03/3/11
  • location changed to Library Code
  • milestone changed to 3.4.0
  • priority changed to P3 (normal)
  • status changed from assigned to accepted

Luke Smith

YUI Contributor

Posted: 03/3/11

Yeah, onDataReturnInitializeTable is creating a new RecordSet, which does not inherit the plugins assigned to its predecessor. Same goes for any invocation of table.set('recordset', new Y.RecordSet(...));

Luke Smith

YUI Contributor

Posted: 06/28/11
  • duplicate changed to 2529872
  • resolution changed to duplicate
  • status changed from accepted to closed

This ticket was marked as a duplicate of #2529872

nelson_menezes

Posted: 06/28/11

A possibly simpler workaround:

<code>
myDT.after("recordsetChange", function() { myDT.plug(Y.Plugin.DataTableSort); });
</code>

Luke Smith

YUI Contributor

Posted: 06/28/11

nelson_menezes,
That would only work for the specific case of sorting. The heart of the issue is that the Recordset is replaced instead of having the existing Recordset's data replaced.