datatable-debug.js revision d64ab2267df9f30ae1ca6c13bc7f23cb552b86be
}
/**
* Class name.
*
* @property NAME
* @type String
* @static
* @final
* @value "record"
*/
/////////////////////////////////////////////////////////////////////////////
//
// Record Attributes
//
/////////////////////////////////////////////////////////////////////////////
id: {
valueFn: "_setId",
writeOnce: true
},
data : {
}
};
/* Record extends Base */
_setId: function() {
return Y.guid();
},
initializer: function() {
},
destructor: function() {
},
}
});
}
/**
* Class name.
*
* @property NAME
* @type String
* @static
* @final
* @value "recordset"
*/
/////////////////////////////////////////////////////////////////////////////
//
// Recordset Attributes
//
/////////////////////////////////////////////////////////////////////////////
records: {
value: null,
setter: "_setRecords"
},
length: {
value: 0,
readOnly:true
}
};
/* Recordset extends Base */
_setRecords: function(allData) {
var records = [];
function initRecord(oneData){
}
return records;
},
initializer: function() {
},
destructor: function() {
},
getRecord: function(i) {
return this.get("records")[i];
}
});
}
/**
* Class name.
*
* @property NAME
* @type String
* @static
* @final
* @value "column"
*/
/////////////////////////////////////////////////////////////////////////////
//
// Column Attributes
//
/////////////////////////////////////////////////////////////////////////////
id: {
valueFn: "_defaultId",
writeOnce: true
},
key: {
valueFn: "_defaultKey"
},
field: {
valueFn: "_defaultField"
},
label: {
valueFn: "_defaultLabel"
},
keyIndex: {
readOnly: true
},
parent: {
readOnly: true
},
children: {
},
colspan: {
readOnly: true
},
rowspan: {
readOnly: true
},
thNode: {
readOnly: true
},
thLinerNode: {
readOnly: true
},
thLabelNode: {
readOnly: true
},
abbr: {
value: null
},
className: {},
editor: {},
formatter: {},
// requires datatable-colresize
resizeable: {},
//requires datatable-sort
sortable: {},
hidden: {},
width: {},
minWidth: {},
maxAutoWidth: {}
};
/* Column extends Widget */
_defaultId: function() {
return Y.guid();
},
_defaultKey: function(key) {
},
_defaultField: function(field) {
},
_defaultLabel: function(label) {
},
initializer: function() {
},
destructor: function() {
},
syncUI: function() {
},
_afterAbbrChange: function (e) {
this._uiSetAbbr(e.newVal);
},
_uiSetAbbr: function(val) {
}
});
}
/**
* Class name.
*
* @property NAME
* @type String
* @static
* @final
* @value "columnset"
*/
/////////////////////////////////////////////////////////////////////////////
//
// Columnset Attributes
//
/////////////////////////////////////////////////////////////////////////////
columns: {
setter: "_setColumns"
},
// DOM tree representation of all Columns
tree: {
readOnly: true,
value: []
},
//TODO: is this necessary?
// Flat representation of all Columns
flat: {
readOnly: true,
value: []
},
// Hash of all Columns by ID
hash: {
readOnly: true,
value: {}
},
// Flat representation of only Columns that are meant to display data
keys: {
readOnly: true,
value: []
}
};
/* Columnset extends Base */
_setColumns: function(columns) {
},
initializer: function() {
// DOM tree representation of all Columns
var tree = [],
// Flat representation of all Columns
flat = [],
// Hash of all Columns by ID
hash = {},
// Flat representation of only Columns that are meant to display data
keys = [],
// Original definitions
self = this;
// Internal recursive function to define Column instances
var i=0,
// One level down
depth++;
// Create corresponding dom node if not already there for this depth
}
// Parse each node at this depth for attributes and any children
for(; i<len; ++i) {
currentNode = nodeList[i];
// Instantiate a new Column for each node
// Cross-reference Column ID back to the original object literal definition
// Add the new Column to the flat list
// Add the new Column to the hash
// Assign its parent as an attribute, if applicable
if(parent) {
}
// The Column has descendants
// The children themselves must also be parsed for Column instances
}
}
// This Column does not have any children
else {
}
// Add the Column to the top-down dom tree
}
depth--;
}
// Parse out Column instances from the array of object literals
// Save to the Columnset instance
this._setRowSpans();
this._setHeaders();
},
destructor: function() {
},
var i = 0,
// Cascade certain properties to children if not defined on their own
for(; i<len; ++i) {
child = currentChildren[i];
}
}
}
}
}
}
}
}
}
}
},
// Determine COLSPAN value for this Column
var terminalChildNodes = 0;
function countTerminalChildNodes(ancestor) {
i = 0,
// Drill down each branch and count terminal nodes
for(; i<len; ++i) {
// Keep drilling down
}
// Reached branch terminus
else {
}
}
}
},
_setRowSpans: function() {
// Determine ROWSPAN value for each Column in the dom tree
function parseDomTreeForRowspan(tree) {
var maxRowDepth = 1,
m,p;
// Calculate the max depth of descendants for this row
var i = 0,
col;
for(; i<len; ++i) {
// Column has children, so keep counting
tmpRowDepth++;
tmpRowDepth--;
}
// Column has children, so keep counting
tmpRowDepth++;
tmpRowDepth--;
}
// No children, is it the max depth?
else {
if(tmpRowDepth > maxRowDepth) {
}
}
}
}
// Count max row depth for each row
currentRow = tree[m];
// Assign the right ROWSPAN values to each Column in the row
currentColumn = currentRow[p];
}
else {
}
}
// Reset counter for next row
maxRowDepth = 1;
}
}
},
_setHeaders: function() {
//headers[i].push(oColumn.getSanitizedKey());
}
}
for(; i<len; ++i) {
headers = [];
}
},
getColumn: function() {
}
});
DATATABLE = "datatable",
TEMPLATE_TH = '<th id="{id}" rowspan="{rowspan}" colspan="{colspan}">{value}</th>',
TEMPLATE_TR = '<tr id="{id}"></tr>',
TEMPLATE_TD = '<td headers="{headers}">{value}</td>',
TEMPLATE_VALUE = '{value}';
}
/*
* Required NAME static field, to identify the Widget class and
* used as an event prefix, to generate class names etc. (set to the
* class name in camel case).
*/
/*
* The attribute configuration for the widget. This defines the core user facing state of the widget
*/
columnset: {
setter: "_setColumnset"
},
//@type Recordset or Array
recordset: {
setter: "_setRecordset"
},
state: {
readOnly: true
},
strings: {
valueFn: function() {
}
},
},
},
trTemplate: {
}
};
/*
* The HTML_PARSER static constant is used if the Widget supports progressive enhancement, and is
* used to populate the configuration for the DTBase instance from markup already on the page.
*/
DTBase.HTML_PARSER = {
// If progressive enhancement is to be supported, return the value of "attrA" based on the contents of the srcNode
}
};
/* DTBase extends the base Widget class */
// Properties
_theadNode: null,
_tbodyNode: null,
_msgNode: null,
// Attributes
_setColumnset: function(columns) {
},
_setRecordset: function(recordset) {
}
return recordset;
},
// Initialization
initializer: function() {
// This set of custom events pass through DOM event facades
//TODO: are the default functions necessary?
this.publish("theadCellClick", {emitFacade:false, defaultFn: BIND("_defTheadCellClickFn", this), queuable:true});
this.publish("theadRowClick", {emitFacade:false, defaultFn: BIND("_defTheadRowClickFn", this), queuable:true});
this.publish("theadClick", {emitFacade:false, defaultFn: BIND("_defTheadClickFn", this), queuable:true});
},
// Destruction
destructor: function() {
},
// UI
renderUI: function() {
// TABLE and CAPTION
var ok = this._createTableNode();
// COLGROUP
// THEAD
// Primary TBODY
// Message TBODY
// CAPTION
return ok;
},
_createTableNode: function() {
if (!this._tableNode) {
}
return this._tableNode;
},
_createColgroupNode: function(tableNode) {
// Add COLs to DOCUMENT FRAGMENT
i = 0,
allCols = ["<colgroup>"];
for(; i<len; ++i) {
}
// Create COLGROUP
this._colgroupNode = tableNode.insertBefore(NODE.create(allCols.join("")), tableNode.get("firstChild"));
return this._colgroupNode;
},
_createTheadNode: function(tableNode) {
if(tableNode) {
this._theadNode = tableNode.insertBefore(NODE.create("<thead class='"+CLASS_DATA+"'></thead>"), this._colgroupNode.next());
return this._theadNode;
}
},
_createTbodyNode: function(tableNode) {
return this._tbodyNode;
},
_createMessageNode: function(tableNode) {
this._msgNode = tableNode.insertBefore(NODE.create("<tbody class='"+CLASS_MSG+"'></tbody>"), this._tbodyNode);
return this._msgNode;
},
_createCaptionNode: function(tableNode) {
return this._captionNode;
},
// Events
bindUI: function() {
var theadNode = this._theadNode,
tbodyNode = this._tbodyNode,
/*
// Set up DOM events for THEAD
theadNode.on("focus", BIND("_onTheadFocus", this));
theadNode.on("keydown", BIND("_onTheadKeydown", this));
theadNode.on("mouseover", BIND("_onTableMouseover", this));
theadNode.on("mouseout", BIND("_onTableMouseout", this));
theadNode.on("mousedown", BIND("_onTableMousedown", this));
theadNode.on("mouseup", BIND("_onTableMouseup", this));
theadNode.on("click", BIND("_onTheadClick", this));
// Since we can't listen for click and dblclick on the same element...
// Attach dblclick separately to contentBox
// theadNode.on("dblclick", BIND("_onTableDblclick", this));
// Set up DOM events for TBODY
tbodyNode.on("focus", BIND("this._onTbodyFocus", this));
tbodyNode.on("mouseover", BIND("_onTableMouseover", this));
tbodyNode.on("mouseout", BIND("_onTableMouseout", this));
tbodyNode.on("mousedown", BIND("_onTableMousedown", this));
tbodyNode.on("mouseup", BIND("_onTableMouseup", this));
tbodyNode.on("keydown", BIND("_onTbodyKeydown", this));
tbodyNode.on("keypress", BIND("_onTableKeypress", this));
tbodyNode.on("click", BIND("_onTbodyClick", this));
// Since we can't listen for click and dblclick on the same element...
// Attach dblick separately to contentBox
// tbodyNode.on("dblclick", BIND("_onTableDblclick", this));
contentBox.on("focus", BIND("_onTableFocus", this));
contentBox.on("dblclick", BIND("_onTableDblclick", this));
// Set up DOM events for msg node
msgNode.on("focus", BIND("_onTbodyFocus", this));
msgNode.on("mouseover", BIND("_onTableMouseover", this));
msgNode.on("mouseout", BIND("_onTableMouseout", this));
msgNode.on("mousedown", BIND("_onTableMousedown", this));
msgNode.on("mouseup", BIND("_onTableMouseup", this));
msgNode.on("keydown", BIND("_onTbodyKeydown", this));
msgNode.on("keypress", BIND("_onTableKeypress", this));
msgNode.on("click", BIND("_onTbodyClick", this));
*/
},
_onTheadFocus: function() {
},
_onTheadKeydown: function() {
},
this.fire("theadCellClick", e);
this.fire("theadRowClick", e);
this.fire("theadClick", e);
},
_onTbodyFocus: function() {
},
_onTbodyKeydown: function() {
},
_onTbodyClick: function() {
},
_onTableMouseover: function() {
},
_onTableMouseout: function() {
},
_onTableMousedown: function() {
},
_onTableMouseup: function() {
},
_onTableKeypress: function() {
},
_onTableFocus: function() {
},
_onTableDblclick: function() {
},
_defTheadCellClickFn: function() {
},
syncUI: function() {
/*
* syncUI is intended to be used by the Widget subclass to
* update the UI to reflect the initial state of the widget,
* after renderUI. From there, the event listeners we bound above
* will take over.
*/
// STRINGS
// HEADER ROWS
// DATA RECORDS
},
/* Listeners, UI update methods */
/**
* Updates the UI if changes are made to any of the strings in the strings
* attribute.
*
* @method _afterStringsChange
* @param e {Event} Custom event for the attribute change
* @protected
*/
_afterStringsChange: function (e) {
this._uiSetStrings(e.newVal);
},
_uiSetStrings: function (strings) {
},
_uiSetSummary: function(val) {
},
_uiSetCaption: function(val) {
},
_afterColumnsetChange: function (e) {
this._uiSetColumnset(e.newVal);
},
_uiSetColumnset: function(cs) {
//TODO
// this._removeHeaderRows();
theadNode = this._theadNode,
tr,
i = 0,
// Iterate tree to add rows
for(; i<len; ++i) {
if(i === 0) {
}
if(i === (len-1)) {
}
}
//TODO
//this._setHeaderFirstLastClasses();
// Column helpers needs _theadNode to exist
//this._createColumnHelpers();
},
_createHeaderTr: function(record) {
return tr;
},
_getHeaderTrMarkup: function(record) {
},
var i = 0,
ths = [],
o;
for(; i<len; ++i) {
//column._set("thNode", thNode);
}
//TODO fire an event with node to append so that you can access the node via a listener
},
_getThNodeMarkup: function(o, column) {
//TODO o.classnames
//TODO o.abbr = column.get("abbr");
/*TODO
// Clear minWidth on hidden Columns
if(column.get("hidden")) {
//this._clearMinWidth(column);
}
*/
return Y.substitute(this.thTemplate, o);
},
_afterRecordsetChange: function (e) {
this._uiSetRecordset(e.newVal);
},
_uiSetRecordset: function(rs) {
var tbodyNode = this._tbodyNode,
i = 0,//TODOthis.get("state.offsetIndex"),
tr,
// Iterate recordset to use existing or add new tr
for(; i<len; ++i) {
}
},
_createBodyTr: function(record) {
this.fire("addDataTr", {record: record, tr: tr}); //on and after are the same state here bc there is no def fn
return tr;
},
_getDataTrMarkup: function(record) {
},
var i = 0,
tds = [];
for(; i<len; ++i) {
}
},
var o = {};
return Y.substitute(this.tdTemplate, o);
},
var o = {};
}
});
//TODO: break out into own component
var //getClassName = Y.ClassNameManager.getClassName,
//DATATABLE = "datatable",
ASC = "asc",
DESC = "desc",
//CLASS_ASC = getClassName(DATATABLE, "asc"),
//CLASS_DESC = getClassName(DATATABLE, "desc"),
//CLASS_SORTABLE = getClassName(DATATABLE, "sortable"),
TEMPLATE_TH_LINK = '<a class="{link_class}" title="{link_title}" href="{link_href}">{value}</a>';
}
Y.mix(RecordsetSort, {
NS: "sort",
NAME: "recordsetSort",
ATTRS: {
dt: {
},
if(sorted === 0) {
}
else {
return sorted;
}
}
}
}
});
initializer: function(config) {
},
destructor: function(config) {
},
_defSortFn: function(e) {
},
},
custom: function() {
alert("sort custom");
},
// force asc
asc: function() {
alert("sort asc");
},
// force desc
desc: function() {
alert("sort desc");
},
// force reverse
reverse: function() {
alert("sort reverse");
}
});
function DataTableSort() {
}
Y.mix(DataTableSort, {
NS: "sort",
NAME: "dataTableSort",
ATTRS: {
sortedBy: {
value: null
}
}
});
initializer: function(config) {
//this.doBefore("_getThNodeMarkup", this._beforeGetThNodeMarkup);
// Attach click handlers
// Attach UI hooks
});
alert('ok');
});
//TODO
//dt.after("recordset:mutation", function() {//reset sortedBy});
//TODO
//add Column sortFn ATTR
},
/*_beforeGetThNodeMarkup: function(o, column) {
if(column.get("sortable")) {
o.link_class = "foo";
o.link_title = "bar";
o.link_href = "bat";
o.value = Y.substitute(this.thLinkTemplate, o);
}
},*/
_onEventSortColumn: function(e) {
e.halt();
dir = (prevSortedBy &&
}
});
DATATABLE = "datatable",
//CLASS_RESIZEABLE = GETCLASSNAME(DATATABLE, "resizeable"),
function DataTableColResize() {
}
Y.mix(DataTableColResize, {
NS: "colresize",
NAME: "dataTableColResize",
ATTRS: {
}
});
initializer: function(config) {
this.get("host").thTemplate = Y.substitute(this.get("host").thTemplate, {value: this.thLinerTemplate});
this.get("host").tdTemplate = Y.substitute(this.get("host").tdTemplate, {value: this.tdLinerTemplate});
//TODO Set Column width...
/*if(oColumn.width) {
// Validate minWidth
var nWidth = (oColumn.minWidth && (oColumn.width < oColumn.minWidth)) ?
oColumn.minWidth : oColumn.width;
// ...for fallback cases
if(DT._bDynStylesFallback) {
elTh.firstChild.style.overflow = 'hidden';
elTh.firstChild.style.width = nWidth + 'px';
}
// ...for non fallback cases
else {
this._setColumnWidthDynStyles(oColumn, nWidth + 'px', 'hidden');
}
}*/
}
});
YUI.add('datatable', function(Y){}, '@VERSION@' ,{use:['record','recordset','column','columnset','datatable-base','datatable-sort','datatable-colresize']});