/*
Copyright (c) 2007, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
version: 2.3.0
*/
/**
* The DataTable widget provides a progressively enhanced DHTML control for
* displaying tabular data across A-grade browsers.
*
* @module datatable
* @requires yahoo, dom, event, datasource
* @optional dragdrop
* @title DataTable Widget
* @beta
*/
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
/**
* DataTable class for the YUI DataTable widget.
*
* @namespace YAHOO.widget
* @class DataTable
* @uses YAHOO.util.EventProvider
* @constructor
* @param elContainer {HTMLElement} Container element for the TABLE.
* @param aColumnDefs {Object[]} Array of object literal Column definitions.
* @param oDataSource {YAHOO.util.DataSource} DataSource instance.
* @param oConfigs {object} (optional) Object literal of configuration values.
*/
// Internal vars
// Initialize container element
this._initContainerEl(elContainer);
if(!this._elContainer) {
return;
}
// Initialize configs
this._initConfigs(oConfigs);
// Initialize ColumnSet
this._initColumnSet(aColumnDefs);
if(!this._oColumnSet) {
return;
}
// Initialize RecordSet
this._initRecordSet();
if(!this._oRecordSet) {
return;
}
// Initialize DataSource
this._initDataSource(oDataSource);
if(!this._oDataSource) {
return;
}
// Progressive enhancement special case
}
else {
// Initialize DOM elements
this._initTableEl();
return;
}
// Call Element's constructor after DOM elements are created
// but *before* table is populated with data
//HACK: Set the Paginator values here via updatePaginator
}
// Send out for data in an asynchronous request
}
// Initialize inline Cell editing
this._initCellEditorEl();
// Initialize Column sort
this._initColumnSort();
// Initialize DOM event listeners
this._initDomEvents();
};
}
else {
}
/////////////////////////////////////////////////////////////////////////////
//
// Superclass methods
//
/////////////////////////////////////////////////////////////////////////////
/**
* Implementation of Element's abstract method. Sets up config values.
*
* @method initAttributes
* @param oConfigs {Object} (Optional) Object literal definition of configuration values.
* @private
*/
/**
* @config summary
* @description Value for the SUMMARY attribute.
* @type String
*/
this.setAttributeConfig("summary", {
value: null,
}
});
/**
* @config selectionMode
* @description Specifies row or cell selection mode. Accepts the following strings:
* <dl>
* <dt>"standard"</dt>
* <dd>Standard row selection with support for modifier keys to enable
* multiple selections.</dd>
*
* <dt>"single"</dt>
* <dd>Row selection with modifier keys disabled to not allow
* multiple selections.</dd>
*
* <dt>"singlecell"</dt>
* <dd>Cell selection with modifier keys disabled to not allow
* multiple selections.</dd>
*
* <dt>"cellblock"</dt>
* <dd>Cell selection with support for modifier keys to enable multiple
* selections in a block-fashion, like a spreadsheet.</dd>
*
* <dt>"cellrange"</dt>
* <dd>Cell selection with support for modifier keys to enable multiple
* selections in a range-fashion, like a calendar.</dd>
* </dl>
*
* @default "standard"
* @type String
*/
this.setAttributeConfig("selectionMode", {
value: "standard",
});
/**
* @config initialRequest
* @description Defines the initial request that gets sent to the DataSource.
* @type String
*/
this.setAttributeConfig("initialRequest", {
value: "",
});
/**
* @config sortedBy
* @description Object literal provides metadata for initial sort values if
* data will arrive pre-sorted:
* <dl>
* <dt>sortedBy.key</dt>
* <dd>Key of sorted Column</dd>
* <dt>sortedBy.dir</dt>
* <dd>Initial sort direction, either "asc" or "desc"</dd>
* </dl>
* @type Object
*/
this.setAttributeConfig("sortedBy", {
value: null,
// TODO: accepted array for nested sorts
validator: function(oNewSortedBy) {
},
method: function(oNewSortedBy) {
}
var column = (oNewSortedBy.column) ? oNewSortedBy.column : this._oColumnSet.getColumn(oNewSortedBy.key);
if(column) {
}
}
});
/**
* @config paginator
* @description Object literal of pagination values.
* @default <br>
* { containers:[], // UI container elements <br>
* rowsPerPage:500, // 500 rows <br>
* currentPage:1, // page one <br>
* pageLinks:0, // show all links <br>
* pageLinksStart:1, // first link is page 1 <br>
* dropdownOptions:null, // no dropdown <br>
* links: [], // links elements <br>
* dropdowns: [] } //dropdown elements
*
* @type Object
*/
this.setAttributeConfig("paginator", {
value: {
dropdownOptions: null, //no dropdown
containers:[], // Paginator container element references
dropdowns: [], //dropdown element references,
links: [] // links elements
},
validator: function(oNewPaginator) {
// Check for incomplete set of values
// Validate each value
return true;
}
}
}
return false;
}
});
/**
* @config paginated
* @description True if built-in client-side pagination is enabled
* @default false
* @type Boolean
*/
this.setAttributeConfig("paginated", {
value: false,
// Paginator is enabled
if(oParam) {
// No containers found, create two from scratch
// One before TABLE
// One after TABLE
// Add containers directly to tracker
}
else {
// Show each container
}
}
// Links are enabled
// No links containers found, create from scratch
// Create one links container per Paginator container
// Add event listener
//TODO: anon fnc
// Add directly to tracker
}
}
}
// Show these options in the dropdown
// Create one SELECT element per Paginator container
// Add event listener
//TODO: anon fnc
// Add DOM reference directly to tracker
// Hide dropdown
if(!oPaginator.dropdownOptions) {
}
}
//TODO: fire paginatorDisabledEvent & add to api doc
}
// Pagination is disabled
else {
// Containers found
// Destroy or just hide?
// Hide each container
}
/*TODO?
// Destroy each container
for(i=0; i<aContainerEls.length; i++) {
YAHOO.util.Event.purgeElement(aContainerEls[i], true);
aContainerEls.innerHTML = null;
//TODO: remove container?
// aContainerEls[i].parentNode.removeChild(aContainerEls[i]);
}
*/
}
//TODO: fire paginatorDisabledEvent & add to api doc
}
}
});
/**
* @config caption
* @description Value for the CAPTION element.
* @type String
*/
this.setAttributeConfig("caption", {
value: null,
// Create CAPTION element
if(!this._elCaption) {
if(!this._elTable.firstChild) {
}
else {
this._elCaption = this._elTable.insertBefore(document.createElement("caption"), this._elTable.firstChild);
}
}
// Set CAPTION value
}
});
/**
* @config scrollable
* @description True if primary TBODY should scroll while THEAD remains fixed.
* When enabling this feature, captions cannot be used, and the following
* features are not recommended: inline editing, resizeable columns.
* @default false
* @type Boolean
*/
this.setAttributeConfig("scrollable", {
value: false,
//TODO: validate agnst resizeable
// Not compatible with caption
},
if(oParam) {
//TODO: conf height
}
else {
}
}
});
};
/////////////////////////////////////////////////////////////////////////////
//
// Public constants
//
/////////////////////////////////////////////////////////////////////////////
/**
* Class name assigned to TABLE element.
*
* @property DataTable.CLASS_TABLE
* @type String
* @static
* @final
* @default "yui-dt-table"
*/
/**
* Class name assigned to header container elements within each TH element.
*
* @property DataTable.CLASS_HEADER
* @type String
* @static
* @final
* @default "yui-dt-header"
*/
/**
* Class name assigned to the primary TBODY element.
*
* @property DataTable.CLASS_BODY
* @type String
* @static
* @final
* @default "yui-dt-body"
*/
/**
* Class name assigned to the scrolling TBODY element of a fixed scrolling DataTable.
*
* @property DataTable.CLASS_SCROLLBODY
* @type String
* @static
* @final
* @default "yui-dt-scrollbody"
*/
/**
* Class name assigned to display label elements.
*
* @property DataTable.CLASS_LABEL
* @type String
* @static
* @final
* @default "yui-dt-label"
*/
/**
* Class name assigned to resizer handle elements.
*
* @property DataTable.CLASS_RESIZER
* @type String
* @static
* @final
* @default "yui-dt-resizer"
*/
/**
* Class name assigned to Editor container elements.
*
* @property DataTable.CLASS_EDITOR
* @type String
* @static
* @final
* @default "yui-dt-editor"
*/
/**
* Class name assigned to paginator container elements.
*
* @property DataTable.CLASS_PAGINATOR
* @type String
* @static
* @final
* @default "yui-dt-paginator"
*/
/**
* Class name assigned to page number indicators.
*
* @property DataTable.CLASS_PAGE
* @type String
* @static
* @final
* @default "yui-dt-page"
*/
/**
* Class name assigned to default indicators.
*
* @property DataTable.CLASS_DEFAULT
* @type String
* @static
* @final
* @default "yui-dt-default"
*/
/**
* Class name assigned to previous indicators.
*
* @property DataTable.CLASS_PREVIOUS
* @type String
* @static
* @final
* @default "yui-dt-previous"
*/
/**
* Class name assigned next indicators.
*
* @property DataTable.CLASS_NEXT
* @type String
* @static
* @final
* @default "yui-dt-next"
*/
/**
* Class name assigned to first elements.
*
* @property DataTable.CLASS_FIRST
* @type String
* @static
* @final
* @default "yui-dt-first"
*/
/**
* Class name assigned to last elements.
*
* @property DataTable.CLASS_LAST
* @type String
* @static
* @final
* @default "yui-dt-last"
*/
/**
* Class name assigned to even elements.
*
* @property DataTable.CLASS_EVEN
* @type String
* @static
* @final
* @default "yui-dt-even"
*/
/**
* Class name assigned to odd elements.
*
* @property DataTable.CLASS_ODD
* @type String
* @static
* @final
* @default "yui-dt-odd"
*/
/**
* Class name assigned to selected elements.
*
* @property DataTable.CLASS_SELECTED
* @type String
* @static
* @final
* @default "yui-dt-selected"
*/
/**
* Class name assigned to highlighted elements.
*
* @property DataTable.CLASS_HIGHLIGHTED
* @type String
* @static
* @final
* @default "yui-dt-highlighted"
*/
/**
* Class name assigned to disabled elements.
*
* @property DataTable.CLASS_DISABLED
* @type String
* @static
* @final
* @default "yui-dt-disabled"
*/
/**
* Class name assigned to empty indicators.
*
* @property DataTable.CLASS_EMPTY
* @type String
* @static
* @final
* @default "yui-dt-empty"
*/
/**
* Class name assigned to loading indicatorx.
*
* @property DataTable.CLASS_LOADING
* @type String
* @static
* @final
* @default "yui-dt-loading"
*/
/**
* Class name assigned to error indicators.
*
* @property DataTable.CLASS_ERROR
* @type String
* @static
* @final
* @default "yui-dt-error"
*/
/**
* Class name assigned to editable elements.
*
* @property DataTable.CLASS_EDITABLE
* @type String
* @static
* @final
* @default "yui-dt-editable"
*/
/**
* Class name assigned to scrollable elements.
*
* @property DataTable.CLASS_SCROLLABLE
* @type String
* @static
* @final
* @default "yui-dt-scrollable"
*/
/**
* Class name assigned to sortable elements.
*
* @property DataTable.CLASS_SORTABLE
* @type String
* @static
* @final
* @default "yui-dt-sortable"
*/
/**
* Class name assigned to ascending elements.
*
* @property DataTable.CLASS_ASC
* @type String
* @static
* @final
* @default "yui-dt-asc"
*/
/**
* Class name assigned to descending elements.
*
* @property DataTable.CLASS_DESC
* @type String
* @static
* @final
* @default "yui-dt-desc"
*/
/**
* Class name assigned to BUTTON container elements.
*
* @property DataTable.CLASS_BUTTON
* @type String
* @static
* @final
* @default "yui-dt-button"
*/
/**
* Class name assigned to SELECT container elements.
*
* @property DataTable.CLASS_DROPDOWN
* @type String
* @static
* @final
* @default "yui-dt-dropdown"
*/
/**
* Class name assigned to INPUT TYPE=CHECKBOX container elements.
*
* @property DataTable.CLASS_CHECKBOX
* @type String
* @static
* @final
* @default "yui-dt-checkbox"
*/
/**
* Message to display if DataTable has no data.
*
* @property DataTable.MSG_EMPTY
* @type String
* @static
* @final
* @default "No records found."
*/
/**
* Message to display while DataTable is loading data.
*
* @property DataTable.MSG_LOADING
* @type String
* @static
* @final
* @default "Loading data..."
*/
/**
* Message to display while DataTable has data error.
*
* @property DataTable.MSG_ERROR
* @type String
* @static
* @final
* @default "Data error."
*/
/////////////////////////////////////////////////////////////////////////////
//
// Private member variables
//
/////////////////////////////////////////////////////////////////////////////
/**
* Internal class variable for indexing multiple DataTable instances.
*
* @property DataTable._nCount
* @type Number
* @private
* @static
*/
/**
* Index assigned to instance.
*
* @property _nIndex
* @type Number
* @private
*/
/**
* Counter for IDs assigned to TR elements.
*
* @property _nTrCount
* @type Number
* @private
*/
/**
* Unique name assigned to instance.
*
* @property _sName
* @type String
* @private
*/
/**
* DOM reference to the container element for the DataTable instance into which
* the TABLE element gets created.
*
* @property _elContainer
* @type HTMLElement
* @private
*/
/**
* DOM reference to the CAPTION element for the DataTable instance.
*
* @property _elCaption
* @type HTMLElement
* @private
*/
/**
* DOM reference to the TABLE element for the DataTable instance.
*
* @property _elTable
* @type HTMLElement
* @private
*/
/**
* DOM reference to the THEAD element for the DataTable instance.
*
* @property _elThead
* @type HTMLElement
* @private
*/
/**
* DOM reference to the primary TBODY element for the DataTable instance.
*
* @property _elTbody
* @type HTMLElement
* @private
*/
/**
* DOM reference to the secondary TBODY element used to display DataTable messages.
*
* @property _elMsgTbody
* @type HTMLElement
* @private
*/
/**
* DOM reference to the secondary TBODY element's single TR element used to display DataTable messages.
*
* @property _elMsgTbodyRow
* @type HTMLElement
* @private
*/
/**
* DOM reference to the secondary TBODY element's single TD element used to display DataTable messages.
*
* @property _elMsgTbodyCell
* @type HTMLElement
* @private
*/
/**
* DataSource instance for the DataTable instance.
*
* @property _oDataSource
* @type YAHOO.util.DataSource
* @private
*/
/**
* ColumnSet instance for the DataTable instance.
*
* @property _oColumnSet
* @type YAHOO.widget.ColumnSet
* @private
*/
/**
* RecordSet instance for the DataTable instance.
*
* @property _oRecordSet
* @type YAHOO.widget.RecordSet
* @private
*/
/**
* ID string of first label link element of the current DataTable page, if any.
* Used for focusing sortable Columns with TAB.
*
* @property _sFirstLabelLinkId
* @type String
* @private
*/
/**
* ID string of first TR element of the current DataTable page.
*
* @property _sFirstTrId
* @type String
* @private
*/
/**
* ID string of the last TR element of the current DataTable page.
*
* @property _sLastTrId
* @type String
* @private
*/
/////////////////////////////////////////////////////////////////////////////
//
// Private methods
//
/////////////////////////////////////////////////////////////////////////////
/**
* Sets focus on the given element.
*
* @method _focusEl
* @param el {HTMLElement} Element.
* @private
*/
// The timeout is necessary in both IE and Firefox 1.5, to prevent scripts from doing
// strange unexpected things as the user clicks on buttons and other controls.
};
// INIT FUNCTIONS
/**
* Initializes container element.
*
* @method _initContainerEl
* @param elContainer {HTMLElement | String} HTML DIV element by reference or ID.
* @private
*/
this._elContainer = null;
this._elContainer = elContainer;
}
};
/**
* Initializes object literal of config values.
*
* @method _initConfigs
* @param oConfig {Object} Object literal of config values.
* @private
*/
if(oConfigs) {
if(oConfigs.constructor != Object) {
oConfigs = null;
}
// Backward compatibility
}
}
};
/**
* Initializes ColumnSet.
*
* @method _initColumnSet
* @param aColumnDefs {Object[]} Array of object literal Column definitions.
* @private
*/
this._oColumnSet = null;
}
// Backward compatibility
this._oColumnSet = aColumnDefs;
}
};
/**
* Initializes DataSource.
*
* @method _initDataSource
* @param oDataSource {YAHOO.util.DataSource} DataSource instance.
* @private
*/
this._oDataSource = null;
this._oDataSource = oDataSource;
}
// Backward compatibility
else {
var tmpTable = null;
var tmpContainer = this._elContainer;
// Peek in container child nodes to see if TABLE already exists
if(tmpContainer.hasChildNodes()) {
tmpTable = tmpChildren[i];
break;
}
}
if(tmpTable) {
var tmpFieldsArray = [];
}
}
}
}
};
/**
* Initializes RecordSet.
*
* @method _initRecordSet
* @private
*/
if(this._oRecordSet) {
this._oRecordSet.reset();
}
else {
}
};
/**
* Creates HTML markup for TABLE, THEAD and TBODY elements.
*
* @method _initTableEl
* @private
*/
// Clear the container
// Create TABLE
// Create THEAD
// Create TBODY for messages
// Create TBODY for data
};
/**
* Populates THEAD element with TH cells as defined by ColumnSet.
*
* @method _initTheadEl
* @private
*/
var oColumnSet = this._oColumnSet;
this._sFirstLabelLinkId = null;
// Create THEAD
// Iterate through each row of Column headers...
var elTheadCell;
// ...and create THEAD cells
}
if(i === 0) {
}
}
}
YAHOO.util.Dom.addClass(YAHOO.util.Dom.get(this.id+"-col"+aFirstHeaders[i]), YAHOO.widget.DataTable.CLASS_FIRST);
}
YAHOO.util.Dom.addClass(YAHOO.util.Dom.get(this.id+"-col"+aLastHeaders[i]), YAHOO.widget.DataTable.CLASS_LAST);
}
// Add Resizer only after DOM has been updated
var needDD = false;
if(oColumn.resizeable) {
if(foundDD) {
//TODO: fix fixed width tables
// Skip the last column for fixed-width tables
if(!this.fixedWidth || (this.fixedWidth &&
// TODO: better way to get elTheadContainer
var elThContainer = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_HEADER,"div",elTheadCellId)[0];
var cancelClick = function(e) {
};
}
if(this.fixedWidth) {
//TODO: fix fixedWidth
//elThContainer.style.overflow = "hidden";
//TODO: better way to get elTheadText
var elThLabel = (YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_LABEL,"span",elTheadCellId))[0];
}
}
else {
needDD = true;
}
}
}
if(needDD) {
}
};
/**
* Populates TH cell as defined by Column.
*
* @method _initThEl
* @param elTheadCell {HTMLElement} TH cell element reference.
* @param oColumn {YAHOO.widget.Column} Column object.
* @param row {number} Row index.
* @param col {number} Column index.
* @private
*/
// Clear out the cell of prior content
// TODO: purgeListeners and other validation-related things
}
}
var aCustomClasses;
}
}
if(aCustomClasses) {
}
}
//TODO: Make sortLink customizeable
//TODO: Make title configurable
//TODO: Separate label from an accessibility link that says
// "Click to sort ascending" and push it offscreen
elTheadLabel.innerHTML = "<a id=\"" + sLabelLinkId + "\" href=\"" + sortLink + "\" title=\"Click to sort\" class=\"" + YAHOO.widget.DataTable.CLASS_SORTABLE + "\">" + sLabel + "</a>";
if(!this._sFirstLabelLinkId) {
this._sFirstLabelLinkId = sLabelLinkId;
}
}
else {
}
};
/**
* Creates HTML markup for Cell Editor.
*
* @method _initCellEditorEl
* @private
*/
// Attach Cell Editor container element to body
// Internal tracker of Cell Editor values
var oCellEditor = {};
oCellEditor.value = null;
oCellEditor.isActive = false;
this._oCellEditor = oCellEditor;
// Handle ESC key
// ESC hides Cell Editor
if((e.keyCode == 27)) {
this.cancelCellEditor();
}
});
};
/**
* Initializes Column sorting.
*
* @method _initColumnSort
* @private
*/
};
/**
* Initializes DOM event listeners.
*
* @method _initDomEvents
* @private
*/
var elContainer = this._elContainer;
// Since we can't listen for click and dblclick on the same element...
};
// DOM MUTATION FUNCTIONS
/**
* Adds a TR element to the primary TBODY at the page row index if given, otherwise
* at the end of the page. Formats TD elements within the TR element using data
* from the given Record.
*
* @method _addTrEl
* @param oRecord {YAHOO.widget.Record} Record instance.
* @param index {Number} (optional) The page row index at which to add the TR
* element.
* @return {String} ID of the added TR element, or null.
* @private
*/
this.hideTableMessage();
// It's an append if no index provided, or index is negative or too big
var oColumnSet = this._oColumnSet;
var oRecordSet = this._oRecordSet;
var sortedColKeyIndex = null;
if(isSortedBy) {
}
this._nTrCount++;
// Create TD cells
// For SF2 cellIndex bug: http://www.webreference.com/programming/javascript/ppk2/3.html
elCell.yuiCellIndex = j;
// Update UI
if (j === 0) {
}
}
if(j === sortedColKeyIndex) {
}
/*p.abx {word-wrap:break-word;}
ought to solve the problem for Safari (the long words will wrap in your
tds, instead of overflowing to the next td.
(this is supported by IE win as well, so hide it if needed).
One thing, though: it doesn't work in combination with
'white-space:nowrap'.*/
// need a div wrapper for safari?
//TODO: fix fixedWidth
if(this.fixedWidth) {
//elCell.style.width = "20px";
}
}
};
/**
* Formats all TD elements of given TR element with data from the given Record.
*
* @method _updateTrEl
* @param elRow {HTMLElement} The TR element to update.
* @param oRecord {YAHOO.widget.Record} The associated Record instance.
* @return {String} ID of the updated TR element, or null.
* @private
*/
this.hideTableMessage();
var sortedColKeyIndex = null;
if(isSortedBy) {
}
// Update TD elements with new data
if(j === sortedColKeyIndex) {
}
}
// Update Record ID
};
/**
* Deletes TR element by DOM reference or by DataTable page row index.
*
* @method _deleteTrEl
* @param row {HTMLElement | Number} TR element reference or Datatable page row index.
* @return {Boolean} Returns true if successful, else returns false.
* @private
*/
var rowIndex;
// Get page row index for the element
}
else {
}
return true;
}
else {
return false;
}
};
/**
* Assigns the class YAHOO.widget.DataTable.CLASS_FIRST to the first TR element
* of the DataTable page and updates internal tracker.
*
* @method _setFirstRow
* @private
*/
var rowEl = this.getFirstTrEl();
if(rowEl) {
// Remove FIRST
if(this._sFirstTrId) {
}
// Set FIRST
}
else {
this._sFirstTrId = null;
}
};
/**
* Assigns the class YAHOO.widget.DataTable.CLASS_LAST to the last TR element
* of the DataTable page and updates internal tracker.
*
* @method _setLastRow
* @private
*/
var rowEl = this.getLastTrEl();
if(rowEl) {
// Unassign previous class
if(this._sLastTrId) {
}
// Assign class
}
else {
this._sLastTrId = null;
}
};
/**
* Assigns the classes YAHOO.widget.DataTable.CLASS_EVEN and
* YAHOO.widget.DataTable.CLASS_ODD to alternating TR elements of the DataTable
* page. For performance, a subset of rows may be specified.
*
* @method _setRowStripes
* @param row {HTMLElement | String | Number} (optional) HTML TR element reference
* or string ID, or page row index of where to start striping.
* @param range {Number} (optional) If given, how many rows to stripe, otherwise
* stripe all the rows until the end.
* @private
*/
// Default values stripe all rows
var nStartIndex = 0;
// Stripe a subset
// Validate given start row
if(elStartRow) {
// Validate given range
}
}
}
for(var i=nStartIndex; i<nEndIndex; i++) {
if(i%2) {
}
else {
}
}
};
/////////////////////////////////////////////////////////////////////////////
//
// Private DOM Event Handlers
//
/////////////////////////////////////////////////////////////////////////////
/**
* Handles scroll events on the CONTAINER (for IE) and TBODY elements (for everyone else).
*
* @method _onScroll
* @param e {HTMLEvent} The scroll event.
* @param oSelf {YAHOO.widget.DataTable} DataTable instance.
* @private
*/
}
};
/**
* Handles click events on the DOCUMENT.
*
* @method _onDocumentClick
* @param e {HTMLEvent} The click event.
* @param oSelf {YAHOO.widget.DataTable} DataTable instance.
* @private
*/
// Fires editorBlurEvent when click is not within the TABLE.
// For cases when click is within the TABLE, due to timing issues,
// the editorBlurEvent needs to get fired by the lower-level DOM click
// handlers below rather than by the TABLE click handler directly.
// Only if the click was not within the Cell Editor container
}
}
}
};
/**
* Handles keydown events on the DOCUMENT.
*
* @method _onDocumentKeydown
* @param e {HTMLEvent} The keydown event.
* @param oSelf {YAHOO.widget.DataTable} DataTable instance.
* @private
*/
}
};
/**
* Handles focus events on the TABLE element.
*
* @method _onTableFocus
* @param e {HTMLEvent} The focus event.
* @param oSelf {YAHOO.widget.DataTable} DataTable instance.
* @private
*/
};
/**
* Handles mouseover events on the TABLE element.
*
* @method _onTableMouseover
* @param e {HTMLEvent} The mouseover event.
* @param oSelf {YAHOO.widget.DataTable} DataTable instance.
* @private
*/
switch(elTag) {
case "body":
break;
case "a":
break;
case "td":
break;
case "span":
}
break;
case "th":
break;
case "tr":
}
else {
}
break;
default:
break;
}
if(elTarget) {
}
}
};
/**
* Handles mouseout events on the TABLE element.
*
* @method _onTableMouseout
* @param e {HTMLEvent} The mouseout event.
* @param oSelf {YAHOO.widget.DataTable} DataTable instance.
* @private
*/
switch(elTag) {
case "body":
break;
case "a":
break;
case "td":
break;
case "span":
}
break;
case "th":
break;
case "tr":
}
else {
}
break;
default:
break;
}
if(elTarget) {
}
}
};
/**
* Handles mousedown events on the TABLE element.
*
* @method _onTableMousedown
* @param e {HTMLEvent} The mousedown event.
* @param oSelf {YAHOO.widget.DataTable} DataTable instance.
* @private
*/
switch(elTag) {
case "body":
break;
case "a":
break;
case "td":
break;
case "span":
}
break;
case "th":
break;
case "tr":
}
else {
}
break;
default:
break;
}
if(elTarget) {
}
}
};
/**
* Handles dblclick events on the TABLE element.
*
* @method _onTableDblclick
* @param e {HTMLEvent} The dblclick event.
* @param oSelf {YAHOO.widget.DataTable} DataTable instance.
* @private
*/
switch(elTag) {
case "body":
break;
case "td":
break;
case "span":
}
break;
case "th":
break;
case "tr":
}
else {
}
break;
default:
break;
}
if(elTarget) {
}
}
};
/**
* Handles keydown events on the TABLE element. Handles arrow selection.
*
* @method _onTableKeydown
* @param e {HTMLEvent} The key event.
* @param oSelf {YAHOO.widget.DataTable} DataTable instance.
* @private
*/
// Ignore actions in the THEAD
return;
}
// TAB to first label link if any
if(oSelf._sFirstLabelLinkId) {
}
return;
}
// Something is currently selected
//TODO: handle tab, backspace, delete
// Handle arrow selection
}
else {
return;
}
////////////////////////////////////////////////////////////////////////
//
// SHIFT cell block selection
//
////////////////////////////////////////////////////////////////////////
// Arrow DOWN
if(nKey == 40) {
// Is the anchor cell above, below, or same row
anchorPos = 1;
}
anchorPos = -1;
}
else {
anchorPos = 0;
}
// Is the anchor cell left or right
// Selecting away from anchor cell
if(anchorPos <= 0) {
// Select the horiz block on the next row
for(i=startIndex; i<=endIndex; i++) {
}
}
}
// Unselecting towards anchor cell
else {
// Unselect the horiz block on this row towards the next row
for(i=startIndex; i<=endIndex; i++) {
}
}
}
// Arrow up
else if(nKey == 38) {
// Is the anchor cell above, below, or same row
anchorPos = 1;
}
anchorPos = -1;
}
else {
anchorPos = 0;
}
// Is the anchor cell left or right?
// Selecting away from anchor cell
if(anchorPos >= 0) {
// Select the horiz block on the previous row
if(trIndex > 0) {
for(i=startIndex; i<=endIndex; i++) {
}
}
}
// Unselecting towards anchor cell
else {
// Unselect the horiz block on this row towards the previous row
for(i=startIndex; i<=endIndex; i++) {
}
}
}
// Arrow right
else if(nKey == 39) {
// Is the anchor cell left, right, or same column
anchorPos = 1;
}
anchorPos = -1;
}
else {
anchorPos = 0;
}
// Selecting away from anchor cell
if(anchorPos <= 0) {
//Select the next vert block to the right
for(i=startIndex; i<=endIndex; i++) {
}
}
}
// Unselecting towards anchor cell
else {
// Unselect the vert block on this column towards the right
for(i=startIndex; i<=endIndex; i++) {
}
}
}
// Arrow left
else if(nKey == 37) {
// Is the anchor cell left, right, or same column
anchorPos = 1;
}
anchorPos = -1;
}
else {
anchorPos = 0;
}
// Selecting away from anchor cell
if(anchorPos >= 0) {
//Select the previous vert block to the left
if(tdIndex > 0) {
for(i=startIndex; i<=endIndex; i++) {
}
}
}
// Unselecting towards anchor cell
else {
// Unselect the vert block on this column towards the left
for(i=startIndex; i<=endIndex; i++) {
}
}
}
}
////////////////////////////////////////////////////////////////////////
//
// SHIFT cell range selection
//
////////////////////////////////////////////////////////////////////////
// Is the anchor cell above, below, or same row
anchorPos = 1;
}
anchorPos = -1;
}
else {
anchorPos = 0;
}
// Arrow down
if(nKey == 40) {
// Selecting away from anchor cell
if(anchorPos <= 0) {
// Select all cells to the end of this row
}
// Select some of the cells on the next row down
for(i=0; i<=tdIndex; i++){
}
}
}
// Unselecting towards anchor cell
else {
// Unselect all cells to the end of this row
}
// Unselect some of the cells on the next row down
for(i=0; i<tdIndex; i++){
}
}
}
// Arrow up
else if(nKey == 38) {
// Selecting away from anchor cell
if(anchorPos >= 0) {
// Select all the cells to the beginning of this row
}
// Select some of the cells from the end of the previous row
if(trIndex > 0) {
}
}
}
// Unselecting towards anchor cell
else {
// Unselect all the cells to the beginning of this row
for(i=tdIndex; i>-1; i--){
}
// Unselect some of the cells from the end of the previous row
}
}
}
// Arrow right
else if(nKey == 39) {
// Selecting away from anchor cell
if(anchorPos < 0) {
// Select the next cell to the right
}
// Select the first cell of the next row
}
}
// Unselecting towards anchor cell
else if(anchorPos > 0) {
// Unselect this cell towards the right
}
// Unselect this cells towards the first cell of the next row
else {
}
}
// Anchor is on this row
else {
// Selecting away from anchor
// Select the next cell to the right
}
// Select the first cell on the next row
}
}
// Unselecting towards anchor
else {
// Unselect this cell towards the right
}
}
}
// Arrow left
else if(nKey == 37) {
// Unselecting towards the anchor
if(anchorPos < 0) {
// Unselect this cell towards the left
if(tdIndex > 0) {
}
// Unselect this cell towards the last cell of the previous row
else {
}
}
// Selecting towards the anchor
else if(anchorPos > 0) {
// Select the next cell to the left
if(tdIndex > 0) {
}
// Select the last cell of the previous row
else if(trIndex > 0){
}
}
// Anchor is on this row
else {
// Selecting away from anchor cell
// Select the next cell to the left
if(tdIndex > 0) {
}
// Select the last cell of the previous row
else if(trIndex > 0){
}
}
// Unselecting towards anchor cell
else {
// Unselect this cell towards the left
if(tdIndex > 0) {
}
// Unselect this cell towards the last cell of the previous row
else {
}
}
}
}
}
////////////////////////////////////////////////////////////////////////
//
// Simple single cell selection
//
////////////////////////////////////////////////////////////////////////
// Arrow down
if(nKey == 40) {
// Select the next cell down
}
// Select only the bottom cell
else {
}
}
// Arrow up
else if(nKey == 38) {
// Select the next cell up
if(trIndex > 0) {
}
// Select only the top cell
else {
}
}
// Arrow right
else if(nKey == 39) {
// Select the next cell to the right
}
// Select only the right cell
else {
}
}
// Arrow left
else if(nKey == 37) {
// Select the next cell to the left
if(tdIndex > 0) {
}
// Select only the left cell
else {
}
}
}
////////////////////////////////////////////////////////////////////////
//
// SHIFT row selection
//
////////////////////////////////////////////////////////////////////////
anchorPos = 1;
}
anchorPos = -1;
}
else {
anchorPos = 0;
}
// Arrow down
if(nKey == 40) {
// Selecting away from anchor row
if(anchorPos <= 0) {
// Select the next row down
}
}
// Unselecting toward anchor row
else {
// Unselect this row towards the anchor row down
}
}
// Arrow up
else if(nKey == 38) {
// Selecting away from anchor row
if(anchorPos >= 0) {
// Select the next row up
if(trIndex > 0) {
}
}
// Unselect this row towards the anchor row up
else {
}
}
// Arrow right
else if(nKey == 39) {
// Do nothing
}
// Arrow left
else if(nKey == 37) {
// Do nothing
}
}
////////////////////////////////////////////////////////////////////////
//
// Simple single row selection
//
////////////////////////////////////////////////////////////////////////
else {
// Arrow down
if(nKey == 40) {
// Select the next row
}
// Select only the last row
else {
}
}
// Arrow up
else if(nKey == 38) {
// Select the previous row
if(trIndex > 0) {
}
// Select only the first row
else {
}
}
// Arrow right
else if(nKey == 39) {
// Do nothing
}
// Arrow left
else if(nKey == 37) {
// Do nothing
}
}
}
};
/**
* Handles keypress events on the TABLE. Mainly to support stopEvent on Mac.
*
* @method _onTableKeypress
* @param e {HTMLEvent} The key event.
* @param oSelf {YAHOO.widget.DataTable} DataTable instance.
* @private
*/
if(isMac) {
// arrow down
if(nKey == 40) {
}
// arrow up
else if(nKey == 38) {
}
}
};
/**
* Handles click events on the THEAD element.
*
* @method _onTheadClick
* @param e {HTMLEvent} The click event.
* @param oSelf {YAHOO.widget.DataTable} DataTable instance.
* @private
*/
}
switch(elTag) {
case "body":
break;
case "span":
}
break;
case "th":
break;
case "tr":
break;
default:
break;
}
if(elTarget) {
}
}
};
/**
* Handles click events on the primary TBODY element.
*
* @method _onTbodyClick
* @param e {HTMLEvent} The click event.
* @param oSelf {YAHOO.widget.DataTable} DataTable instance.
* @private
*/
}
switch(elTag) {
case "body":
break;
case "input":
}
}
break;
case "a":
break;
case "button":
break;
case "td":
break;
case "tr":
break;
default:
break;
}
if(elTarget) {
}
}
};
/*TODO: delete
* Handles keyup events on the TBODY. Executes deletion.
*
* @method _onTbodyKeyup
* @param e {HTMLEvent} The key event.
* @param oSelf {YAHOO.widget.DataTable} DataTable instance.
* @private
*/
/*YAHOO.widget.DataTable.prototype._onTbodyKeyup = function(e, oSelf) {
var nKey = YAHOO.util.Event.getCharCode(e);
// delete
if(nKey == 46) {//TODO: if something is selected
//TODO: delete row
}
};*/
/**
* Handles click events on paginator links.
*
* @method _onPaginatorLinkClick
* @param e {HTMLEvent} The click event.
* @param oSelf {YAHOO.widget.DataTable} DataTable instance.
* @private
*/
}
switch(elTag) {
case "body":
return;
case "a":
//TODO: after the showPage call, figure out which link
//TODO: was clicked and reset focus to the new version of it
return;
return;
return;
return;
return;
}
break;
default:
return;
}
if(elTarget) {
}
else {
return;
}
}
};
/**
* Handles change events on paginator SELECT element.
*
* @method _onPaginatorDropdownChange
* @param e {HTMLEvent} The change event.
* @param oSelf {YAHOO.widget.DataTable} DataTable instance.
* @private
*/
if(newRowsPerPage !== null) {
oSelf.refreshView();
}
else {
}
};
/**
* Handles change events on SELECT elements within DataTable.
*
* @method _onDropdownChange
* @param e {HTMLEvent} The change event.
* @param oSelf {YAHOO.widget.DataTable} DataTable instance.
* @private
*/
//TODO: pass what args?
//var value = elTarget[elTarget.selectedIndex].value;
};
/////////////////////////////////////////////////////////////////////////////
//
// Public member variables
//
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
// Public methods
//
/////////////////////////////////////////////////////////////////////////////
// OBJECT ACCESSORS
/**
* Public accessor to the unique name of the DataSource instance.
*
* @method toString
* @return {String} Unique name of the DataSource instance.
*/
return "DataTable " + this._sName;
};
/**
* Returns the DataTable instance's DataSource instance.
*
* @method getDataSource
* @return {YAHOO.util.DataSource} DataSource instance.
*/
return this._oDataSource;
};
/**
* Returns the DataTable instance's ColumnSet instance.
*
* @method getColumnSet
* @return {YAHOO.widget.ColumnSet} ColumnSet instance.
*/
return this._oColumnSet;
};
/**
* Returns the DataTable instance's RecordSet instance.
*
* @method getRecordSet
* @return {YAHOO.widget.RecordSet} RecordSet instance.
*/
return this._oRecordSet;
};
/**
* Returns the DataTable instance's Cell Editor as an object literal with the
* following properties:
* <dl>
* <dt>cell</dt>
* <dd>Cell element being edited</dd>
*
* <dt>column</dt>
* <dd>Associated Column instance</dd>
*
* <dt>container</dt>
* <dd>Reference to editor's container DIV element</dd>
*
* <dt>isActive</dt>
* <dd>True if cell is currently being edited</dd>
*
* <dt>record</dt>
* <dd>Associated Record instance</dd>
*
* <dt>validator</dt>
* <dd>Associated validator function</dd>
*
* <dt>value</dt>
* <dd>Current input value</dd>
* </dl>
*
*
*
*
*
*
* @method getCellEditor
* @return {Object} Cell Editor object literal values.
*/
return this._oCellEditor;
};
// DOM ACCESSORS
/**
* Returns DOM reference to the DataTable's TABLE element.
*
* @method getTableEl
* @return {HTMLElement} Reference to TABLE element.
*/
return this._elTable;
};
/**
* Returns DOM reference to the DataTable's THEAD element.
*
* @method getTheadEl
* @return {HTMLElement} Reference to THEAD element.
*/
return this._elThead;
};
/**
* Returns DOM reference to the DataTable's primary TBODY element.
*
* @method getTbodyEl
* @return {HTMLElement} Reference to TBODY element.
*/
return this._elTbody;
};
// Backward compatibility
return this.getTbodyEl();
};
/**
* Returns DOM reference to the DataTable's secondary TBODY element that is
* used to display messages.
*
* @method getMsgTbodyEl
* @return {HTMLElement} Reference to TBODY element.
*/
return this._elMsgTbody;
};
/**
* Returns DOM reference to the TD element within the secondary TBODY that is
* used to display messages.
*
* @method getMsgTdEl
* @return {HTMLElement} Reference to TD element.
*/
return this._elMsgTd;
};
/**
* Returns the corresponding TR reference for a given DOM element, ID string or
* directly page row index. If the given identifier is a child of a TR element,
* then DOM tree is traversed until a parent TR element is returned, otherwise
* null.
*
* @method getTrEl
* @param row {HTMLElement | String | Number | YAHOO.widget.Record} Which row to
* get: by element reference, ID string, page row index, or Record.
* @return {HTMLElement} Reference to TR element, or null.
*/
// By Record
}
// By page row index
}
// By ID string or element reference
else {
var elRow;
// Validate HTML element
// Validate TR element
// Traverse up the DOM to find the corresponding TR element
}
else {
}
// Make sure the TR is in this TBODY
// Now we can return the TR element
return elRow;
}
}
}
return null;
};
// Backward compatibility
};
/**
* Returns DOM reference to the first TR element in the DataTable page, or null.
*
* @method getFirstTrEl
* @return {HTMLElement} Reference to TR element.
*/
};
/**
* Returns DOM reference to the last TR element in the DataTable page, or null.
*
* @method getLastTrEl
* @return {HTMLElement} Reference to last TR element.
*/
}
};
/**
* Returns DOM reference to the given TD element.
*
* @method getTdEl
* @param cell {HTMLElement | String} DOM element reference or string ID.
* @return {HTMLElement} Reference to TD element.
*/
var elCell;
// Validate HTML element
// Validate TD element
// Traverse up the DOM to find the corresponding TR element
}
else {
}
// Make sure the TD is in this TBODY
// Now we can return the TD element
return elCell;
}
}
return null;
};
/**
* Returns DOM reference to the TH element at given DataTable page coordinates, or null.
*
* @method getThEl
* @param header {HTMLElement | String | YAHOO.widget.Column} DOM element
* reference or string ID, or Column instance.
* @return {HTMLElement} Reference to TH element.
*/
var elHeader;
// Validate Column instance
if(elHeader) {
return elHeader;
}
}
// Validate HTML element
else {
// Validate TH element
// Traverse up the DOM to find the corresponding TR element
}
else {
}
// Make sure the TH is in this THEAD
// Now we can return the TD element
return elHeader;
}
}
}
return null;
};
/**
* Returns the page row index of given row. Returns null if the row is not in
* view on the current DataTable page.
*
* @method getTrIndex
* @param row {HTMLElement | String | YAHOO.widget.Record | Number} DOM or ID
* string reference to an element within the DataTable page, a Record instance,
* or a Record's RecordSet index.
* @return {Number} Page row index, or null if row does not exist or is not in view.
*/
var nRecordIndex;
// By Record
}
// Calculate page row index from Record index
nRecordIndex = row;
}
// DataTable is paginated
if(this.get("paginated")) {
// Get the first and last Record on this page
// This Record is in view
return nRecordIndex - startRecordIndex;
}
// This Record is not in view
else {
return null;
}
}
// Not paginated, just return the Record index
else {
return nRecordIndex;
}
}
// By element reference or ID string
else {
// Validate TR element
return elRow.sectionRowIndex;
}
}
return null;
};
// TABLE FUNCTIONS
/**
* Resets a RecordSet with the given data and populates the page view
* with the new data. Any previous data and selection states are cleared.
* However, sort states are not cleared, so if the given data is in a particular
* sort order, implementers should take care to reset the sortedBy property. If
* pagination is enabled, the currentPage is shown and Paginator UI updated,
* otherwise all rows are displayed as a single page. For performance, existing
* DOM elements are reused when possible.
*
* @method initializeTable
* @param oData {Object | Object[]} An object literal of data or an array of
* object literals containing data.
*/
// Clear the RecordSet
this._oRecordSet.reset();
// Add data to RecordSet
// Clear selections
this._unselectAllTrEls();
this._unselectAllTdEls();
this._aSelections = null;
this._sLastSelectedId = null;
this._sSelectionAnchorId = null;
// Refresh the view
this.refreshView();
this.fireEvent("initEvent");
};
/**
* Refreshes the view with existing Records from the RecordSet while
* maintaining sort, pagination, and selection states. For performance, reuses
* existing DOM elements when possible while deleting extraneous elements.
*
* @method refreshView
*/
var i, j, k, l, aRecords;
var oPaginator = this.updatePaginator();
// Paginator is enabled, show a subset of Records and update Paginator UI
if(this.get("paginated")) {
this.formatPaginators();
}
// Show all records
else {
}
// Has rows
this.hideTableMessage();
// Keep track of selected rows
var aSelectedRows = this.getSelectedRows();
// Keep track of selected cells
var aSelectedCells = this.getSelectedCells();
// Anything to reinstate?
// Remove extra rows from the bottom so as to preserve ID order
}
// Unselect all TR and TD elements in the UI
if(bReselect) {
this._unselectAllTrEls();
this._unselectAllTdEls();
}
// From the top, update in-place existing rows
}
// Add TR elements as necessary
}
// Reinstate selected and sorted classes
if(bReselect) {
// Loop over each row
// Set SELECTED
}
}
}
}
else {
// Loop over each cell
// Set SELECTED
}
}
}
}
}
}
}
this._setFirstRow();
this._setLastRow();
this._setRowStripes();
this.fireEvent("refreshEvent");
}
// Empty
else {
// Remove all rows
while(elTbody.hasChildNodes()) {
}
}
};
/**
* Nulls out the entire DataTable instance and related objects, removes attached
* event listeners, and clears out DOM elements inside the container. After
* calling this method, the instance reference should be expliclitly nulled by
* implementer, as in myDataTable = null. Use with caution!
*
* @method destroy
*/
// Destroy Cell Editor
var instanceName = this.toString();
var elContainer = this._elContainer;
// Unhook custom events
this._oRecordSet.unsubscribeAll();
this.unsubscribeAll();
// Unhook DOM events
// Remove DOM elements
// Null out objects
for(var param in this) {
if(this.hasOwnProperty(param)) {
this[param] = null;
}
}
};
/**
* Displays message within secondary TBODY.
*
* @method showTableMessage
* @param sHTML {String} (optional) Value for innerHTML.
* @param sClassName {String} (optional) Classname.
*/
}
}
};
/**
* Hides secondary TBODY.
*
* @method hideTableMessage
*/
this.fireEvent("tableMsgHideEvent");
}
};
/**
* Brings focus to DataTable instance.
*
* @method focus
*/
};
// RECORDSET FUNCTIONS
/**
* Returns Record index for given TR element or page row index.
*
* @method getRecordIndex
* @param row {YAHOO.widget.Record | HTMLElement | Number} Record instance, TR
* element reference or page row index.
* @return {Number} Record's RecordSet index, or null.
*/
var nTrIndex;
// By Record
}
// By element reference
else {
// Find the TR element
if(el) {
}
}
}
// By page row index
else {
}
if(this.get("paginated")) {
}
else {
return nTrIndex;
}
}
return null;
};
/**
* For the given identifier, returns the associated Record instance.
*
* @method getRecord
* @param row {HTMLElement | String | Number} RecordSet position index, DOM
* reference or ID string to an element within the DataTable page.
* @return {YAHOO.widget.Record} Record instance.
*/
var nRecordIndex = row;
// By element reference or ID string
// Validate TR element
if(elRow) {
}
}
// By Record index
}
return null;
};
// COLUMN FUNCTIONS
/**
* For the given identifier, returns the associated Column instance.
*
* @method getColumn
* @param column {HTMLElement | String | Number} ColumnSet.keys position index, DOM
* reference or ID string to an element within the DataTable page.
* @return {YAHOO.widget.Column} Column instance.
*/
var nColumnIndex = column;
// By element reference or ID string
// Validate TD element
if(elCell) {
}
// Validate TH element
else {
if(elCell) {
}
}
}
// By Column index
}
return null;
};
/**
* Sorts given Column.
*
* @method sortColumn
* @param oColumn {YAHOO.widget.Column} Column instance.
*/
if(!oColumn) {
return;
}
//TODO: accept the TH or TH.key
//TODO: Get the column based on TH.yuiColumnId
return;
}
// What is the default sort direction?
var sortDir = (oColumn.sortOptions && oColumn.sortOptions.defaultOrder) ? oColumn.sortOptions.defaultOrder : "asc";
// Already sorted?
}
else {
}
}
// Is there a custom sort handler function defined?
if(sorted === 0) {
}
else {
return sorted;
}
};
// Do the actual sort
// Update sortedBy tracker
// Reset to first page
//TODO: Keep selection in view
// Update the UI
this.refreshView();
}
else {
//TODO
}
};
// ROW FUNCTIONS
/**
* Adds one new Record of data into the RecordSet at the index if given,
* otherwise at the end. If the new Record is in page view, the
* corresponding DOM elements are also updated.
*
* @method addRow
* @param oData {Object} Object literal of data for the row.
* @param index {Number} (optional) RecordSet position index at which to add data.
*/
if(oRecord) {
// Row is in view
// Paginated so just refresh the view to keep pagination state
if(this.get("paginated")) {
this.refreshView();
}
// Add the TR element
else {
if(newTrId) {
// Is this an insert or an append?
// Stripe the one new row
if(append) {
}
else {
}
}
// Restripe all the rows after the new one
else {
this._setRowStripes(nTrIndex);
}
// If new row is at the bottom
if(append) {
this._setLastRow();
}
// If new row is at the top
this._setFirstRow();
}
}
}
}
// Record is not in view so just update pagination UI
else {
this.updatePaginator();
}
// TODO: what args to pass?
// For log message
return;
}
}
};
/**
* Convenience method to add multiple rows.
*
* @method addRows
* @param aData {Object[]} Array of object literal data for the rows.
* @param index {Number} (optional) RecordSet position index at which to add data.
*/
var i;
}
}
else {
}
}
}
else {
}
};
/**
* For the given row, updates the associated Record with the given data. If the
* row is in view, the corresponding DOM elements are also updated.
*
* @method updateRow
* @param row {YAHOO.widget.Record | Number | HTMLElement | String}
* Which row to update: By Record instance, by Record's RecordSet
* position index, by HTMLElement reference to the TR element, or by ID string
* of the TR element.
* @param oData {Object} Object literal of data for the row.
*/
// Get the Record directly
// Get the Record directly
// Is this row in view?
}
// Get the Record by TR element
else {
if(elRow) {
}
}
// Update the Record
if(oldRecord) {
// Copy data from the Record for the event that gets fired later
var oldData = {};
for(var param in oRecordData) {
}
}
else {
return;
}
// Update the TR only if row is in view
if(elRow) {
}
};
/**
* Deletes the given row's Record from the RecordSet. If the row is in view, the
* corresponding DOM elements are also deleted.
*
* @method deleteRow
* @param row {HTMLElement | String | Number} DOM element reference or ID string
* to DataTable page element or RecordSet index.
*/
// Get the Record index...
var nRecordIndex = null;
// ...by Record index
nRecordIndex = row;
}
// ...by element reference
else {
if(elRow) {
}
}
if(nRecordIndex !== null) {
if(oRecord) {
// Remove from selection tracker if there
var tracker = this._aSelections || [];
}
}
// Copy data from the Record for the event that gets fired later
var oData = {};
for(var param in oRecordData) {
}
// Delete Record from RecordSet
// If row is in view, delete the TR element
true : false;
this._deleteTrEl(nTrIndex);
// Empty body
}
// Update UI
else {
if(nTrIndex === 0) {
this._setFirstRow();
}
if(isLast) {
this._setLastRow();
}
this._setRowStripes(nTrIndex);
}
}
}
}
}
else {
}
};
/**
* Convenience method to delete multiple rows.
*
* @method deleteRows
* @param row {HTMLElement | String | Number} DOM element reference or ID string
* to DataTable page element or RecordSet index.
* @param count {Number} (optional) How many rows to delete. A negative value
* will delete towards the beginning.
*/
// Get the Record index...
var nRecordIndex = null;
// ...by Record index
nRecordIndex = row;
}
// ...by element reference
else {
if(elRow) {
}
}
if(nRecordIndex !== null) {
// Start with highest index and work down
this.deleteRow(i);
}
}
else {
this.deleteRow(nRecordIndex);
}
}
else {
}
};
// CELL FUNCTIONS
/**
* Outputs markup into the given TD based on given Record.
*
* @method formatCell
* @param elCell {HTMLElement} TD Element.
* @param oRecord {YAHOO.widget.Record} (Optional) Record instance.
* @param oColumn {YAHOO.widget.Column} (Optional) Column instance.
* @return {HTML} Markup.
*/
}
}
var fnFormatter;
case "button":
break;
case "checkbox":
break;
case "currency":
break;
case "date":
break;
case "dropdown":
break;
case "email":
break;
case "link":
break;
case "number":
break;
case "radio":
break;
case "text":
break;
case "textarea":
break;
case "textbox":
break;
case "html":
// This is the default
break;
default:
fnFormatter = null;
}
}
}
// Apply special formatter
if(fnFormatter) {
}
else {
}
// Add custom classNames
var aCustomClasses = null;
}
}
if(aCustomClasses) {
}
}
// Is editable?
}
}
else {
}
};
/**
* Formats a BUTTON element.
*
* @method DataTable.formatButton
* @param el {HTMLElement} The element to format with markup.
* @param oRecord {YAHOO.widget.Record} Record instance.
* @param oColumn {YAHOO.widget.Column} Column instance.
* @param oData {Object | Boolean} Data value for the cell. By default, the value
* is what gets written to the BUTTON.
* @static
*/
//TODO: support YAHOO.widget.Button
//if(YAHOO.widget.Button) {
//}
//else {
//}
};
/**
* Formats a CHECKBOX element.
*
* @method DataTable.formatCheckbox
* @param el {HTMLElement} The element to format with markup.
* @param oRecord {YAHOO.widget.Record} Record instance.
* @param oColumn {YAHOO.widget.Column} Column instance.
* @param oData {Object | Boolean} Data value for the cell. Can be a simple
* Boolean to indicate whether checkbox is checked or not. Can be object literal
* {checked:bBoolean, label:sLabel}. Other forms of oData require a custom
* formatter.
* @static
*/
};
/**
* Formats currency. Default unit is USD.
*
* @method DataTable.formatCurrency
* @param el {HTMLElement} The element to format with markup.
* @param oRecord {YAHOO.widget.Record} Record instance.
* @param oColumn {YAHOO.widget.Column} Column instance.
* @param oData {Number} Data value for the cell.
* @static
*/
var markup;
// Round to the penny
// Default currency is USD
// Normalize digits
if(dotIndex < 0) {
markup += ".00";
}
else {
markup += "0";
}
}
}
else {
}
};
/**
* Formats JavaScript Dates.
*
* @method DataTable.formatDate
* @param el {HTMLElement} The element to format with markup.
* @param oRecord {YAHOO.widget.Record} Record instance.
* @param oColumn {YAHOO.widget.Column} Column instance.
* @param oData {Object} Data value for the cell, or null.
* @static
*/
if(oDate instanceof Date) {
}
else {
}
};
/**
* Formats SELECT elements.
*
* @method DataTable.formatDropdown
* @param el {HTMLElement} The element to format with markup.
* @param oRecord {YAHOO.widget.Record} Record instance.
* @param oColumn {YAHOO.widget.Column} Column instance.
* @param oData {Object} Data value for the cell, or null.
* @static
*/
oColumn.dropdownOptions : null;
var selectEl;
// Create the form element only once, so we can attach the onChange listener
// Create SELECT element
// Add event listener
//TODO: static method doesn't have access to the datatable instance...
}
// Update the form element
if(selectEl) {
// Clear out previous options
// We have options to populate
if(options) {
// Create OPTION elements
}
}
// Selected value is our only option
else {
}
}
else {
}
};
/**
* Formats emails.
*
* @method DataTable.formatEmail
* @param el {HTMLElement} The element to format with markup.
* @param oRecord {YAHOO.widget.Record} Record instance.
* @param oColumn {YAHOO.widget.Column} Column instance.
* @param oData {Object} Data value for the cell, or null.
* @static
*/
}
else {
}
};
/**
* Formats links.
*
* @method DataTable.formatLink
* @param el {HTMLElement} The element to format with markup.
* @param oRecord {YAHOO.widget.Record} Record instance.
* @param oColumn {YAHOO.widget.Column} Column instance.
* @param oData {Object} Data value for the cell, or null.
* @static
*/
}
else {
}
};
/**
* Formats numbers.
*
* @method DataTable.formatNumber
* @param el {HTMLElement} The element to format with markup.
* @param oRecord {YAHOO.widget.Record} Record instance.
* @param oColumn {YAHOO.widget.Column} Column instance.
* @param oData {Object} Data value for the cell, or null.
* @static
*/
}
else {
}
};
/**
* Formats INPUT TYPE=RADIO elements.
*
* @method DataTable.formatRadio
* @param el {HTMLElement} The element to format with markup.
* @param oRecord {YAHOO.widget.Record} Record instance.
* @param oColumn {YAHOO.widget.Column} Column instance.
* @param oData {Object} (Optional) Data value for the cell.
* @static
*/
};
/**
* Formats text strings.
*
* @method DataTable.formatText
* @param el {HTMLElement} The element to format with markup.
* @param oRecord {YAHOO.widget.Record} Record instance.
* @param oColumn {YAHOO.widget.Column} Column instance.
* @param oData {Object} (Optional) Data value for the cell.
* @static
*/
//TODO: move to util function
el.innerHTML = value.toString().replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
};
/**
* Formats TEXTAREA elements.
*
* @method DataTable.formatTextarea
* @param el {HTMLElement} The element to format with markup.
* @param oRecord {YAHOO.widget.Record} Record instance.
* @param oColumn {YAHOO.widget.Column} Column instance.
* @param oData {Object} (Optional) Data value for the cell.
* @static
*/
};
/**
* Formats INPUT TYPE=TEXT elements.
*
* @method DataTable.formatTextbox
* @param el {HTMLElement} The element to format with markup.
* @param oRecord {YAHOO.widget.Record} Record instance.
* @param oColumn {YAHOO.widget.Column} Column instance.
* @param oData {Object} (Optional) Data value for the cell.
* @static
*/
};
// PAGINATION
/**
* Pass in all, a subset, or no values.
*
* @method updatePaginator
* @param oNewValues {Object} (Optional) Object literal of Paginator values, or
* a subset of Paginator values.
* @param {Object} Object literal of all Paginator values.
*/
// Complete the set
for(var param in oNewValues) {
}
}
oValidPaginator.totalPages = Math.ceil(oValidPaginator.totalRecords / oValidPaginator.rowsThisPage);
}
return this.get("paginator");
};
/**
* Displays given page of a paginated DataTable.
*
* @method showPage
* @param nPage {Number} Which page.
*/
// Validate input
nPage = 1;
}
this.refreshView();
};
/**
* Updates Paginator containers with markup. Override this method to customize pagination UI.
*
* @method formatPaginators
*/
// For Opera workaround
var dropdownEnabled = false;
// Links are enabled
this.formatPaginatorLinks(pag.links[i], pag.currentPage, pag.pageLinksStart, pag.pageLinks, pag.totalPages);
}
}
// Dropdown is enabled
if(pag.dropdownOptions) {
dropdownEnabled = true;
}
else {
}
}
// For Opera artifacting in dropdowns
}
};
/**
* Updates Paginator dropdown. If dropdown doesn't exist, the markup is created.
* Sets dropdown elements's "selected" value.
*
* @method formatPaginatorDropdown
* @param elDropdown {HTMLElement} The SELECT element.
* @param dropdownOptions {Object[]} OPTION values for display in the SELECT element.
*/
// Clear OPTION elements
while (elDropdown.firstChild) {
}
// Create OPTION elements
var dropdownOption = dropdownOptions[j];
}
// Update dropdown's "selected" value
}
}
}
// Show the dropdown
return;
}
};
/**
* Updates Paginator links container with markup.
*
* @method formatPaginatorLinks
* @param elContainer {HTMLElement} The link container element.
* @param nCurrentPage {Number} Current page.
* @param nPageLinksStart {Number} First page link to display.
* @param nPageLinksLength {Number} How many page links to display.
* @param nTotalPages {Number} Total number of pages.
*/
YAHOO.widget.DataTable.prototype.formatPaginatorLinks = function(elContainer, nCurrentPage, nPageLinksStart, nPageLinksLength, nTotalPages) {
var sFirstLinkMarkup = (bIsFirstPage) ?
var sPrevLinkMarkup = (bIsFirstPage) ?
var sNextLinkMarkup = (bIsLastPage) ?
var sLastLinkMarkup = (bIsLastPage) ?
// Start with first and previous
// Ok to show all links
var nMaxLinks = nTotalPages;
var nFirstLink = 1;
var nLastLink = nTotalPages;
if(nPageLinksLength > 0) {
// Calculate how many links to show
// Try to keep the current page in the middle
nFirstLink = (nCurrentPage - Math.floor(nMaxLinks/2) > 0) ? nCurrentPage - Math.floor(nMaxLinks/2) : 1;
nLastLink = (nCurrentPage + Math.floor(nMaxLinks/2) <= nTotalPages) ? nCurrentPage + Math.floor(nMaxLinks/2) : nTotalPages;
// Keep the last link in range
if(nFirstLink === 1) {
}
// Keep the first link in range
else if(nLastLink === nTotalPages) {
}
// An even number of links can get funky
nLastLink--;
}
}
// Generate markup for each page
for(var i=nFirstLink; i<=nLastLink; i++) {
if(i != nCurrentPage) {
}
else {
}
}
return;
}
};
/**
* ID string of last highlighted cell element
*
* @property _sLastHighlightedCellId
* @type String
* @private
*/
/**
* ID string of last highlighted row element
*
* @property _sLastHighlightedRowId
* @type String
* @private
*/
/**
* Array of selections: {recordId:nRecordId, cellIndex:nCellIndex}
*
* @property _aSelections
* @type Object[]
* @private
*/
/**
* ID string of last selected element
*
* @property _sLastSelectedId
* @type String
* @private
*/
/**
* ID string of the selection anchor element.
*
* @property _sSelectionAnchorId
* @type String
* @private
*/
/**
* Convenience method to remove the class YAHOO.widget.DataTable.CLASS_SELECTED
* from all TR elements on the page.
*
* @method _unselectAllTrEls
* @private
*/
var selectedRows = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_SELECTED,"tr",this._elTbody);
};
/**
* Returns array of selected TR elements on the page.
*
* @method getSelectedTrEls
* @return {HTMLElement[]} Array of selected TR elements.
*/
return YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_SELECTED,"tr",this._elTbody);
};
/**
* Sets given row to the selected state.
*
* @method selectRow
* @param row {HTMLElement | String} HTML element reference or ID.
*/
// Validate the row
if(elRow) {
if(oRecord) {
// Get Record ID
var tracker = this._aSelections || [];
// Remove if already there
// Use Array.indexOf if available...
}
// ...or do it the old-fashioned way
else {
}
}
}
// Add to the end
// Update trackers
if(!this._sSelectionAnchorId) {
}
this._aSelections = tracker;
// Update UI
return;
}
}
};
// Backward compatibility
}
}
};
/**
* Sets given row to the unselected state.
*
* @method unselectRow
* @param row {HTMLElement | String} HTML TR element reference or ID.
*/
// Validate the row
if(elRow) {
if(oRecord) {
// Get Record ID
var tracker = this._aSelections || [];
// Remove if there
var bFound = false;
// Use Array.indexOf if available...
bFound = true;
}
// ...or do it the old-fashioned way
else {
bFound = true;
}
}
}
if(bFound) {
// Update tracker
this._aSelections = tracker;
// Update the UI
return;
}
}
}
};
/**
* Clears out all row selections.
*
* @method unselectAllRows
*/
// Remove from tracker
var tracker = this._aSelections || [];
}
}
// Update tracker
this._aSelections = tracker;
// Update UI
this._unselectAllTrEls();
//TODO: send an array of [{el:el,record:record}]
//TODO: or convert this to an unselectRows method
//TODO: that takes an array of rows or unselects all if none given
this.fireEvent("unselectAllRowsEvent");
};
/**
* Convenience method to remove the class YAHOO.widget.DataTable.CLASS_SELECTED
* from all TD elements in the internal tracker.
*
* @method _unselectAllTdEls
* @private
*/
var selectedCells = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_SELECTED,"td",this._elTbody);
};
/**
* Returns array of selected TD elements on the page.
*
* @method getSelectedTdEls
* @return {HTMLElement[]} Array of selected TD elements.
*/
return YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_SELECTED,"td",this._elTbody);
};
/**
* Sets given cell to the selected state.
*
* @method selectCell
* @param cell {HTMLElement | String} DOM element reference or ID string
* to DataTable page element or RecordSet index.
*/
if(elCell) {
// Get Record ID
var tracker = this._aSelections || [];
// Remove if there
}
}
// Add to the end
// Update trackers
this._aSelections = tracker;
if(!this._sSelectionAnchorId) {
}
// Update the UI
return;
}
}
};
/**
* Sets given cell to the unselected state.
*
* @method unselectCell
* @param cell {HTMLElement | String} DOM element reference or ID string
* to DataTable page element or RecordSet index.
*/
if(elCell) {
// Get Record ID
var tracker = this._aSelections || [];
// Is it selected?
// Remove from tracker
// Update tracker
this._aSelections = tracker;
// Update the UI
return;
}
}
}
}
};
/**
* Clears out all cell selections.
*
* @method unselectAllCells
*/
// Remove from tracker
var tracker = this._aSelections || [];
if(tracker[j].constructor == Object){
}
}
// Update tracker
this._aSelections = tracker;
// Update UI
this._unselectAllTdEls();
//TODO: send data
//TODO: or fire individual cellUnselectEvent
this.fireEvent("unselectAllCellsEvent");
};
/**
* Returns true if given TR or TD element is select, false otherwise.
*
* @method isSelected
* @param el {HTMLElement} HTML element reference or ID of a TR or TD.
* @return {Boolean} True if element is selected.
*/
};
/**
* Returns selected rows as an array of Record IDs.
*
* @method getSelectedRows
* @return {HTMLElement[]} Array of selected rows by Record ID.
*/
var aSelectedRows = [];
var tracker = this._aSelections || [];
}
}
return aSelectedRows;
};
/**
* Returns selected cells as an array of object literals:
* {recordId:nRecordID, columnId:nColumnId}.
*
* @method getSelectedCells
* @return {HTMLElement[]} Array of selected cells by Record and Column IDs.
*/
var aSelectedCells = [];
var tracker = this._aSelections || [];
}
}
return aSelectedCells;
};
/**
* Assigns the class YAHOO.widget.DataTable.CLASS_HIGHLIGHTED to the given row.
*
* @method highlightRow
* @param row {HTMLElement | String} DOM element reference or ID string.
*/
if(elRow) {
// Make sure previous row is unhighlighted
if(this._sLastHighlightedRowId) {
}
return;
}
};
/**
* Removes the class YAHOO.widget.DataTable.CLASS_HIGHLIGHTED from the given row.
*
* @method unhighlightRow
* @param row {HTMLElement | String} DOM element reference or ID string.
*/
if(elRow) {
return;
}
};
/**
* Assigns the class YAHOO.widget.DataTable.CLASS_HIGHLIGHTED to the given cell.
*
* @method highlightCell
* @param cell {HTMLElement | String} DOM element reference or ID string.
*/
if(elCell) {
// Make sure previous cell is unhighlighted
if(this._sLastHighlightedCellId) {
}
return;
}
};
/**
* Removes the class YAHOO.widget.DataTable.CLASS_HIGHLIGHTED from the given cell.
*
* @method unhighlightCell
* @param cell {HTMLElement | String} DOM element reference or ID string.
*/
if(elCell) {
return;
}
};
// INLINE EDITING
/*TODO: for TAB handling
* Shows Cell Editor for next cell.
*
* @method editNextCell
* @param elCell {HTMLElement} Cell element from which to edit next cell.
*/
//YAHOO.widget.DataTable.prototype.editNextCell = function(elCell) {
//};
/**
* Shows Cell Editor for given cell.
*
* @method showCellEditor
* @param elCell {HTMLElement | String} Cell element to edit.
* @param oRecord {YAHOO.widget.Record} (Optional) Record instance.
* @param oColumn {YAHOO.widget.Column} (Optional) Column instance.
*/
}
}
var oCellEditor = this._oCellEditor;
// Clear previous Editor
if(oCellEditor.isActive) {
this.cancelCellEditor();
}
// Editor not defined
return;
}
// Update Editor values
// Move Editor
// SF doesn't get xy for cells in scrolling table
// when tbody display is set to block
}
// Show Editor
// Render Editor markup
var fnEditor;
case "checkbox":
break;
case "date":
break;
case "dropdown":
break;
case "radio":
break;
case "textarea":
break;
case "textbox":
break;
default:
fnEditor = null;
}
}
}
if(fnEditor) {
// Create DOM input elements
fnEditor(this._oCellEditor, this);
this.showCellEditorBtns(elContainer);
}
// Hook to customize the UI
this.doBeforeShowCellEditor(this._oCellEditor);
oCellEditor.isActive = true;
//TODO: verify which args to pass
return;
}
}
}
};
/**
* Overridable abstract method to customize Cell Editor UI.
*
* @method doBeforeShowCellEditor
* @param oCellEditor {Object} Cell Editor object literal.
*/
};
/**
*
* @method showCellEditorBtns
* @param elContainer {HTMLElement} Cell Editor container.
*/
// Buttons
// Save button
// Cancel button
};
/**
* Clears Cell Editor of all state and UI.
*
* @method resetCellEditor
*/
this._oCellEditor.value = null;
this._oCellEditor.isActive = false;
};
/**
* Saves Cell Editor input to Record.
*
* @method saveCellEditor
*/
//TODO: Copy the editor's values to pass to the event
if(this._oCellEditor.isActive) {
// Validate input data
if(this._oCellEditor.validator) {
if(this._oCellEditor.value === null ) {
this.resetCellEditor();
this.fireEvent("editorRevertEvent",
return;
}
}
// Update the Record
this._oRecordSet.updateKey(this._oCellEditor.record, this._oCellEditor.column.key, this._oCellEditor.value);
// Update the UI
// Clear out the Cell Editor
this.resetCellEditor();
this.fireEvent("editorSaveEvent",
}
else {
}
};
/**
* Cancels Cell Editor.
*
* @method cancelCellEditor
*/
if(this._oCellEditor.isActive) {
this.resetCellEditor();
//TODO: preserve values for the event?
}
else {
}
};
/**
* Enables CHECKBOX Editor.
*
* @method editCheckbox
*/
//YAHOO.widget.DataTable.editCheckbox = function(elContainer, oRecord, oColumn, oEditor, oSelf) {
}
// Checkboxes
// First create the checkbox buttons in an IE-friendly way
// Then create the labels in an IE-friendly way
}
var aCheckboxEls = [];
var checkboxEl;
// Loop through checkboxes to check them
checkboxEl.checked = true;
}
}
// Focus the first checkbox
if(j===0) {
}
}
// Loop through checkboxes to assign click handlers
var aNewValues = [];
if(aCheckboxEls[m].checked) {
}
}
});
}
}
};
/**
* Enables Date Editor.
*
* @method editDate
*/
// Calendar widget
var calendar =
//var calFloatClearer = elContainer.appendChild(document.createElement("br"));
//calFloatClearer.style.clear = "both";
});
}
else {
//TODO;
}
};
/**
* Enables SELECT Editor.
*
* @method editDropdown
*/
// Textbox
var dropdownOptions = (oColumn.editorOptions && YAHOO.lang.isArray(oColumn.editorOptions.dropdownOptions)) ?
var dropdownOption = dropdownOptions[j];
}
}
// Set up a listener on each check box to track the input value
function(){
});
// Focus the dropdown
};
/**
* Enables INPUT TYPE=RADIO Editor.
*
* @method editRadio
*/
// Radios
// First create the radio buttons in an IE-friendly way
// Then create the labels in an IE-friendly way
}
// Then check one, and assign click handlers
}
function(){
});
}
}
};
/**
* Enables TEXTAREA Editor.
*
* @method editTextarea
*/
// Textarea
// Set up a listener on each check box to track the input value
//TODO: set on a timeout
});
// Select the text
elTextarea.focus();
elTextarea.select();
};
/**
* Enables INPUT TYPE=TEXT Editor.
*
* @method editTextbox
*/
// Textbox
//elTextbox.style.height = "1em"; //(parseInt(elCell.offsetHeight,10)) + "px";
// Set up a listener on each textbox to track the input value
//TODO: set on a timeout
});
// Select the text
};
/*
* Validates Editor input value to type Number, doing type conversion as
* necessary. A valid Number value is return, else the previous value is returned
* if input value does not validate.
*
*
* @method validateNumber
* @static
*/
//Convert to number
// Validate
return number;
}
else {
return null;
}
};
// ABSTRACT METHODS
/**
* Overridable method gives implementers a hook to access data before
* it gets added to RecordSet and rendered to the TBODY.
*
* @method doBeforeLoadData
* @param sRequest {String} Original request.
* @param oResponse {Object} Response object.
* @return {Boolean} Return true to continue loading data into RecordSet and
* updating DataTable with new Records, false to cancel.
*/
return true;
};
/////////////////////////////////////////////////////////////////////////////
//
// Public Custom Event Handlers
//
/////////////////////////////////////////////////////////////////////////////
/**
* Overridable custom event handler to sort Column.
*
* @method onEventSortColumn
* @param oArgs.event {HTMLEvent} Event object.
* @param oArgs.target {HTMLElement} Target element.
*/
//TODO: support nested header column sorting
}
else {
}
};
/**
* Overridable custom event handler to manage selection according to desktop paradigm.
*
* @method onEventSelectRow
* @param oArgs.event {HTMLEvent} Event object.
* @param oArgs.target {HTMLElement} Target element.
*/
return;
}
var i, nAnchorTrIndex;
// Validate target row
if(elTargetRow) {
// Both SHIFT and CTRL
// Validate anchor row
if(this.isSelected(elAnchorRow)) {
// Select all rows between anchor row and target row, including target row
if(nAnchorTrIndex < nTargetTrIndex) {
if(!this.isSelected(allRows[i])) {
}
}
}
// Select all rows between target row and anchor row, including target row
else {
if(!this.isSelected(allRows[i])) {
}
}
}
}
else {
// Unselect all rows between anchor row and target row
if(nAnchorTrIndex < nTargetTrIndex) {
if(this.isSelected(allRows[i])) {
this.unselectRow(allRows[i]);
}
}
}
// Unselect all rows between target row and anchor row
else {
if(this.isSelected(allRows[i])) {
this.unselectRow(allRows[i]);
}
}
}
// Select the target row
this.selectRow(elTargetRow);
}
}
// Invalid anchor
else {
// Set anchor
// Toggle selection of target
if(this.isSelected(elTargetRow)) {
this.unselectRow(elTargetRow);
}
else {
this.selectRow(elTargetRow);
}
}
}
// Only SHIFT
this.unselectAllRows();
// Validate anchor
// Select all rows between anchor row and target row,
// including the anchor row and target row
if(nAnchorTrIndex < nTargetTrIndex) {
for(i=nAnchorTrIndex; i<=nTargetTrIndex; i++) {
}
}
// Select all rows between target row and anchor row,
// including the target row and anchor row
else {
for(i=nAnchorTrIndex; i>=nTargetTrIndex; i--) {
}
}
}
// Invalid anchor
else {
// Set anchor
// Select target row only
this.selectRow(elTargetRow);
}
}
// Only CTRL
// Set anchor
// Toggle selection of target
if(this.isSelected(elTargetRow)) {
this.unselectRow(elTargetRow);
}
else {
this.selectRow(elTargetRow);
}
}
// Neither SHIFT nor CTRL
else if(sMode == "single") {
this.unselectAllRows();
this.selectRow(elTargetRow);
}
// Neither SHIFT nor CTRL
else {
// Set anchor
// Select only target
this.unselectAllRows();
this.selectRow(elTargetRow);
}
// Clear any selections that are a byproduct of the click or dblclick
var sel;
if(window.getSelection) {
}
else if(document.getSelection) {
}
}
if(sel) {
}
else if (sel.removeAllRanges) {
}
}
}
}
else {
}
};
/**
* Overridable custom event handler to select cell.
*
* @method onEventSelectCell
* @param oArgs.event {HTMLEvent} Event object.
* @param oArgs.target {HTMLElement} Target element.
*/
return;
}
if(elTargetCell) {
// Both SHIFT and CTRL
// Validate anchor
// Anchor is selected
if(this.isSelected(elAnchorCell)) {
// All cells are on the same row
if(nAnchorTrIndex == nTargetTrIndex) {
// Select all cells between anchor cell and target cell, including target cell
if(nAnchorTdIndex < nTargetTdIndex) {
}
}
// Select all cells between target cell and anchor cell, including target cell
else if(nTargetTdIndex < nAnchorTdIndex) {
for(i=nTargetTdIndex; i<nAnchorTdIndex; i++) {
}
}
}
// Anchor row is above target row
else if(nAnchorTrIndex < nTargetTrIndex) {
if(sMode == "cellrange") {
// Select all cells on anchor row from anchor cell to the end of the row
}
// Select all cells on all rows between anchor row and target row
}
}
// Select all cells on target row from first cell to the target cell
for(i=0; i<=nTargetTdIndex; i++) {
}
}
else if(sMode == "cellblock") {
// Select all cells from startIndex to endIndex on rows between anchor row and target row
for(i=nAnchorTrIndex; i<=nTargetTrIndex; i++) {
for(j=startIndex; j<=endIndex; j++) {
}
}
}
}
// Anchor row is below target row
else {
if(sMode == "cellrange") {
// Select all cells on target row from target cell to the end of the row
}
// Select all cells on all rows between target row and anchor row
}
}
// Select all cells on anchor row from first cell to the anchor cell
for(i=0; i<nAnchorTdIndex; i++) {
}
}
else if(sMode == "cellblock") {
// Select all cells from startIndex to endIndex on rows between target row and anchor row
for(i=nAnchorTrIndex; i>=nTargetTrIndex; i--) {
for(j=endIndex; j>=startIndex; j--) {
}
}
}
}
}
// Anchor cell is unselected
else {
// All cells are on the same row
if(nAnchorTrIndex == nTargetTrIndex) {
// Unselect all cells between anchor cell and target cell
if(nAnchorTdIndex < nTargetTdIndex) {
}
}
// Select all cells between target cell and anchor cell
else if(nTargetTdIndex < nAnchorTdIndex) {
}
}
}
// Anchor row is above target row
if(nAnchorTrIndex < nTargetTrIndex) {
// Unselect all cells from anchor cell to target cell
for(i=nAnchorTrIndex; i<=nTargetTrIndex; i++) {
currentRow = allRows[i];
// This is the anchor row, only unselect cells after the anchor cell
if(j>nAnchorTdIndex) {
}
}
// This is the target row, only unelect cells before the target cell
if(j<nTargetTdIndex) {
}
}
// Unselect all cells on this row
else {
}
}
}
}
// Anchor row is below target row
else {
// Unselect all cells from target cell to anchor cell
for(i=nTargetTrIndex; i<=nAnchorTrIndex; i++) {
currentRow = allRows[i];
// This is the target row, only unselect cells after the target cell
if(j>nTargetTdIndex) {
}
}
// This is the anchor row, only unselect cells before the anchor cell
if(j<nAnchorTdIndex) {
}
}
// Unselect all cells on this row
else {
}
}
}
}
// Select the target cell
this.selectCell(elTargetCell);
}
}
// Invalid anchor
else {
// Set anchor
// Toggle selection of target
if(this.isSelected(elTargetCell)) {
this.unselectCell(elTargetCell);
}
else {
this.selectCell(elTargetCell);
}
}
}
// Only SHIFT
this.unselectAllCells();
// Validate anchor
// All cells are on the same row
if(nAnchorTrIndex == nTargetTrIndex) {
// Select all cells between anchor cell and target cell,
// including the anchor cell and target cell
if(nAnchorTdIndex < nTargetTdIndex) {
for(i=nAnchorTdIndex; i<=nTargetTdIndex; i++) {
}
}
// Select all cells between target cell and anchor cell
// including the target cell and anchor cell
else if(nTargetTdIndex < nAnchorTdIndex) {
for(i=nTargetTdIndex; i<=nAnchorTdIndex; i++) {
}
}
}
// Anchor row is above target row
else if(nAnchorTrIndex < nTargetTrIndex) {
if(sMode == "cellrange") {
// Select all cells from anchor cell to target cell
// including the anchor cell and target cell
for(i=nAnchorTrIndex; i<=nTargetTrIndex; i++) {
currentRow = allRows[i];
// This is the anchor row, only select the anchor cell and after
if(j>=nAnchorTdIndex) {
}
}
// This is the target row, only select the target cell and before
if(j<=nTargetTdIndex) {
}
}
// Select all cells on this row
else {
}
}
}
}
else if(sMode == "cellblock") {
// Select the cellblock from anchor cell to target cell
// including the anchor cell and the target cell
for(i=nAnchorTrIndex; i<=nTargetTrIndex; i++) {
for(j=startIndex; j<=endIndex; j++) {
}
}
}
}
// Anchor row is below target row
else {
if(sMode == "cellrange") {
// Select all cells from target cell to anchor cell,
// including the target cell and anchor cell
for(i=nTargetTrIndex; i<=nAnchorTrIndex; i++) {
currentRow = allRows[i];
// This is the target row, only select the target cell and after
if(j>=nTargetTdIndex) {
}
}
// This is the anchor row, only select the anchor cell and before
if(j<=nAnchorTdIndex) {
}
}
// Select all cells on this row
else {
}
}
}
}
else if(sMode == "cellblock") {
// Select the cellblock from target cell to anchor cell
// including the target cell and the anchor cell
for(i=nTargetTrIndex; i<=nAnchorTrIndex; i++) {
for(j=startIndex; j<=endIndex; j++) {
}
}
}
}
}
// Invalid anchor
else {
// Set anchor
// Select target only
this.selectCell(elTargetCell);
}
}
// Only CTRL
// Set anchor
// Toggle selection of target
if(this.isSelected(elTargetCell)) {
this.unselectCell(elTargetCell);
}
else {
this.selectCell(elTargetCell);
}
}
// Neither SHIFT nor CTRL, or multi-selection has been disabled
else {
// Set anchor
// Select only target
this.unselectAllCells();
this.selectCell(elTargetCell);
}
// Clear any selections that are a byproduct of the click or dblclick
var sel;
if(window.getSelection) {
}
else if(document.getSelection) {
}
}
if(sel) {
}
else if (sel.removeAllRanges) {
}
}
}
}
else {
}
};
/**
* Overridable custom event handler to highlight row.
*
* @method onEventHighlightRow
* @param oArgs.event {HTMLEvent} Event object.
* @param oArgs.target {HTMLElement} Target element.
*/
this.highlightRow(elTarget);
};
/**
* Overridable custom event handler to unhighlight row.
*
* @method onEventUnhighlightRow
* @param oArgs.event {HTMLEvent} Event object.
* @param oArgs.target {HTMLElement} Target element.
*/
this.unhighlightRow(elTarget);
};
/**
* Overridable custom event handler to highlight cell.
*
* @method onEventHighlightCell
* @param oArgs.event {HTMLEvent} Event object.
* @param oArgs.target {HTMLElement} Target element.
*/
this.highlightCell(elTarget);
};
/**
* Overridable custom event handler to unhighlight cell.
*
* @method onEventUnhighlightCell
* @param oArgs.event {HTMLEvent} Event object.
* @param oArgs.target {HTMLElement} Target element.
*/
this.unhighlightCell(elTarget);
};
/**
* Overridable custom event handler to format cell.
*
* @method onEventFormatCell
* @param oArgs.event {HTMLEvent} Event object.
* @param oArgs.target {HTMLElement} Target element.
*/
}
else {
}
};
/**
* Overridable custom event handler to edit cell.
*
* @method onEventShowCellEditor
* @param oArgs.event {HTMLEvent} Event object.
* @param oArgs.target {HTMLElement} Target element.
*/
if(elCell) {
this.showCellEditor(elCell);
}
else {
}
};
// Backward compatibility
this.onEventShowCellEditor(oArgs);
};
/**
* Overridable custom event handler to save Cell Editor input.
*
* @method onEventSaveCellEditor
* @param oArgs.editor {Object} Cell Editor object literal.
*/
this.saveCellEditor();
};
/**
* Callback function for creating a progressively enhanced DataTable first
* receives data from DataSource and populates the RecordSet, then initializes
* DOM elements.
*
* @method _onDataReturnEnhanceTable
* @param sRequest {String} Original request.
* @param oResponse {Object} Response object.
* @param bError {Boolean} (optional) True if there was a data error.
* @private
*/
// Pass data through abstract method for any transformations
// Data ok to populate
// Update RecordSet
// Initialize DOM elements
this._initTableEl();
return;
}
// Call Element's constructor after DOM elements are created
// but *before* UI is updated with data
//HACK: Set the Paginator values
}
// Update the UI
this.refreshView();
}
// Error
}
// Empty
else if(ok){
}
};
/**
* Callback function receives data from DataSource and populates an entire
* DataTable with Records and TR elements, clearing previous Records, if any.
*
* @method onDataReturnInitializeTable
* @param sRequest {String} Original request.
* @param oResponse {Object} Response object.
* @param bError {Boolean} (optional) True if there was a data error.
*/
// Pass data through abstract method for any transformations
// Data ok to populate
}
// Error
}
// Empty
else if(ok){
}
};
// Backward compatibility
};
/**
* Callback function receives data from DataSource and appends to an existing
* DataTable new Records and, if applicable, creates or updates
* corresponding TR elements.
*
* @method onDataReturnAppendRows
* @param sRequest {String} Original request.
* @param oResponse {Object} Response object.
* @param bError {Boolean} (optional) True if there was a data error.
*/
// Pass data through abstract method for any transformations
// Data ok to append
}
// Error
}
};
/**
* Callback function receives data from DataSource and inserts into top of an
* existing DataTable new Records and, if applicable, creates or updates
* corresponding TR elements.
*
* @method onDataReturnInsertRows
* @param sRequest {String} Original request.
* @param oResponse {Object} Response object.
* @param bError {Boolean} (optional) True if there was a data error.
*/
// Pass data through abstract method for any transformations
// Data ok to append
}
// Error
}
};
/////////////////////////////////////////////////////////////////////////////
//
// Custom Events
//
/////////////////////////////////////////////////////////////////////////////
/**
* Fired when the DataTable instance's initialization is complete.
*
* @event initEvent
*/
/**
* Fired when the DataTable's view is refreshed.
*
* @event refreshEvent
*/
/**
* Fired when data is returned from DataSource.
*
* @event dataReturnEvent
* @param oArgs.request {String} Original request.
* @param oArgs.response {Object} Response object.
*/
/**
* Fired when the DataTable has a focus.
*
* @event tableFocusEvent
*/
/**
* Fired when the DataTable has a blur.
*
* @event tableBlurEvent
*/
/**
* Fired when the DataTable has a mouseover.
*
* @event tableMouseoverEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The DataTable's TABLE element.
*
*/
/**
* Fired when the DataTable has a mouseout.
*
* @event tableMouseoutEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The DataTable's TABLE element.
*
*/
/**
* Fired when the DataTable has a mousedown.
*
* @event tableMousedownEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The DataTable's TABLE element.
*
*/
/**
* Fired when the DataTable has a click.
*
* @event tableClickEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The DataTable's TABLE element.
*
*/
/**
* Fired when the DataTable has a dblclick.
*
* @event tableDblclickEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The DataTable's TABLE element.
*
*/
/**
* Fired when a fixed scrolling DataTable has a scroll.
*
* @event tableScrollEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The DataTable's CONTAINER element (in IE)
* or the DataTable's TBODY element (everyone else).
*
*/
/**
* Fired when a message is shown in the DataTable's message element.
*
* @event tableMsgShowEvent
* @param oArgs.html {String} The HTML displayed.
* @param oArgs.className {String} The className assigned.
*
*/
/**
* Fired when the DataTable's message element is hidden.
*
* @event tableMsgHideEvent
*/
/**
* Fired when a header row has a mouseover.
*
* @event headerRowMouseoverEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The TR element.
*/
/**
* Fired when a header row has a mouseout.
*
* @event headerRowMouseoutEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The TR element.
*/
/**
* Fired when a header row has a mousedown.
*
* @event headerRowMousedownEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The TR element.
*/
/**
* Fired when a header row has a click.
*
* @event headerRowClickEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The TR element.
*/
/**
* Fired when a header row has a dblclick.
*
* @event headerRowDblclickEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The TR element.
*/
/**
* Fired when a header cell has a mouseover.
*
* @event headerCellMouseoverEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The TH element.
*
*/
/**
* Fired when a header cell has a mouseout.
*
* @event headerCellMouseoutEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The TH element.
*
*/
/**
* Fired when a header cell has a mousedown.
*
* @event headerCellMousedownEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The TH element.
*/
/**
* Fired when a header cell has a click.
*
* @event headerCellClickEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The TH element.
*/
/**
* Fired when a header cell has a dblclick.
*
* @event headerCellDblclickEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The TH element.
*/
/**
* Fired when a header label has a mouseover.
*
* @event headerLabelMouseoverEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The SPAN element.
*
*/
/**
* Fired when a header label has a mouseout.
*
* @event headerLabelMouseoutEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The SPAN element.
*
*/
/**
* Fired when a header label has a mousedown.
*
* @event headerLabelMousedownEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The SPAN element.
*/
/**
* Fired when a header label has a click.
*
* @event headerLabelClickEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The SPAN element.
*/
/**
* Fired when a header label has a dblclick.
*
* @event headerLabelDblclickEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The SPAN element.
*/
/**
* Fired when a column is sorted.
*
* @event columnSortEvent
* @param oArgs.column {YAHOO.widget.Column} The Column instance.
* @param oArgs.dir {String} Sort direction "asc" or "desc".
*/
/**
* Fired when a column is resized.
*
* @event columnResizeEvent
* @param oArgs.column {YAHOO.widget.Column} The Column instance.
* @param oArgs.target {HTMLElement} The TH element.
*/
/**
* Fired when a row has a mouseover.
*
* @event rowMouseoverEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The TR element.
*/
/**
* Fired when a row has a mouseout.
*
* @event rowMouseoutEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The TR element.
*/
/**
* Fired when a row has a mousedown.
*
* @event rowMousedownEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The TR element.
*/
/**
* Fired when a row has a click.
*
* @event rowClickEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The TR element.
*/
/**
* Fired when a row has a dblclick.
*
* @event rowDblclickEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The TR element.
*/
/**
* Fired when a row is added.
*
* @event rowAddEvent
* @param oArgs.record {YAHOO.widget.Record} The added Record.
*/
/**
* Fired when a row is updated.
*
* @event rowUpdateEvent
* @param oArgs.record {YAHOO.widget.Record} The updated Record.
* @param oArgs.oldData {Object} Object literal of the old data.
*/
/**
* Fired when a row is deleted.
*
* @event rowDeleteEvent
* @param oArgs.oldData {Object} Object literal of the deleted data.
* @param oArgs.recordIndex {Number} Index of the deleted Record.
* @param oArgs.trElIndex {Number} Index of the deleted TR element, if in view.
*/
/**
* Fired when a row is selected.
*
* @event rowSelectEvent
* @param oArgs.el {HTMLElement} The selected TR element, if applicable.
* @param oArgs.record {YAHOO.widget.Record} The selected Record.
*/
/**
* Fired when a row is unselected.
*
* @event rowUnselectEvent
* @param oArgs.el {HTMLElement} The unselected TR element, if applicable.
* @param oArgs.record {YAHOO.widget.Record} The unselected Record.
*/
/*TODO: delete and use rowUnselectEvent?
* Fired when all row selections are cleared.
*
* @event unselectAllRowsEvent
*/
/*
* Fired when a row is highlighted.
*
* @event rowHighlightEvent
* @param oArgs.el {HTMLElement} The highlighted TR element.
* @param oArgs.record {YAHOO.widget.Record} The highlighted Record.
*/
/*
* Fired when a row is unhighlighted.
*
* @event rowUnhighlightEvent
* @param oArgs.el {HTMLElement} The highlighted TR element.
* @param oArgs.record {YAHOO.widget.Record} The highlighted Record.
*/
/**
* Fired when a cell has a mouseover.
*
* @event cellMouseoverEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The TD element.
*/
/**
* Fired when a cell has a mouseout.
*
* @event cellMouseoutEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The TD element.
*/
/**
* Fired when a cell has a mousedown.
*
* @event cellMousedownEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The TD element.
*/
/**
* Fired when a cell has a click.
*
* @event cellClickEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The TD element.
*/
/**
* Fired when a cell has a dblclick.
*
* @event cellDblclickEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The TD element.
*/
/**
* Fired when a cell is formatted.
*
* @event cellFormatEvent
* @param oArgs.el {HTMLElement} The formatted TD element.
* @param oArgs.record {YAHOO.widget.Record} The formatted Record.
* @param oArgs.key {String} The key of the formatted cell.
*/
/**
* Fired when a cell is selected.
*
* @event cellSelectEvent
* @param oArgs.el {HTMLElement} The selected TD element.
* @param oArgs.record {YAHOO.widget.Record} The selected Record.
* @param oArgs.key {String} The key of the selected cell.
*/
/**
* Fired when a cell is unselected.
*
* @event cellUnselectEvent
* @param oArgs.el {HTMLElement} The unselected TD element.
* @param oArgs.record {YAHOO.widget.Record} The unselected Record.
* @param oArgs.key {String} The key of the unselected cell.
*/
/**
* Fired when a cell is highlighted.
*
* @event cellHighlightEvent
* @param oArgs.el {HTMLElement} The highlighted TD element.
* @param oArgs.record {YAHOO.widget.Record} The highlighted Record.
* @param oArgs.key {String} The key of the highlighted cell.
*/
/**
* Fired when a cell is unhighlighted.
*
* @event cellUnhighlightEvent
* @param oArgs.el {HTMLElement} The unhighlighted TD element.
* @param oArgs.record {YAHOO.widget.Record} The unhighlighted Record.
* @param oArgs.key {String} The key of the unhighlighted cell.
*/
/*TODO: hide from doc and use cellUnselectEvent
* Fired when all cell selections are cleared.
*
* @event unselectAllCellsEvent
*/
/*TODO: implement
* Fired when DataTable paginator is updated.
*
* @event paginatorUpdateEvent
* @param paginator {Object} Object literal of Paginator values.
*/
/**
* Fired when an Editor is activated.
*
* @event editorShowEvent
* @param oArgs.editor {Object} The Editor object literal.
*/
/**
* Fired when an active Editor has a keydown.
*
* @event editorKeydownEvent
* @param oArgs.editor {Object} The Editor object literal.
* @param oArgs.event {HTMLEvent} The event object.
*/
/**
* Fired when Editor input is reverted.
*
* @event editorRevertEvent
* @param oArgs.editor {Object} The Editor object literal.
* @param oArgs.newData {Object} New data value.
* @param oArgs.oldData {Object} Old data value.
*/
/**
* Fired when Editor input is saved.
*
* @event editorSaveEvent
* @param oArgs.editor {Object} The Editor object literal.
* @param oArgs.newData {Object} New data value.
* @param oArgs.oldData {Object} Old data value.
*/
/**
* Fired when Editor input is canceled.
*
* @event editorCancelEvent
* @param oArgs.editor {Object} The Editor object literal.
*/
/**
* Fired when an active Editor has a blur.
*
* @event editorBlurEvent
* @param oArgs.editor {Object} The Editor object literal.
*/
/**
* Fired when a link is clicked.
*
* @event linkClickEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The A element.
*/
/**
* Fired when a BUTTON element is clicked.
*
* @event buttonClickEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The BUTTON element.
*/
/**
* Fired when a CHECKBOX element is clicked.
*
* @event checkboxClickEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The CHECKBOX element.
*/
/*TODO
* Fired when a SELECT element is changed.
*
* @event dropdownChangeEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The SELECT element.
*/
/**
* Fired when a RADIO element is clicked.
*
* @event radioClickEvent
* @param oArgs.event {HTMLEvent} The event object.
* @param oArgs.target {HTMLElement} The RADIO element.
*/
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
/**
* The ColumnSet class defines and manages a DataTable's Columns,
* including nested hierarchies and access to individual Column instances.
*
* @namespace YAHOO.widget
* @class ColumnSet
* @uses YAHOO.util.EventProvider
* @constructor
* @param aHeaders {Object[]} Array of object literals that define header cells.
*/
// DOM tree representation of all Columns
var tree = [];
// Flat representation of all Columns
var flat = [];
// Flat representation of only Columns that are meant to display data
var keys = [];
// Array of HEADERS attribute values for all keys in the "keys" array
var headers = [];
// Tracks current node list depth being tracked
var nodeDepth = -1;
// Internal recursive function to defined Column instances
// One level down
nodeDepth++;
// Create corresponding tree node if not already there for this depth
}
// Parse each node at this depth for attributes and any children
var currentNode = nodeList[j];
// Instantiate a new Column for each node
// Add the new Column to the flat list
// Assign its parent as an attribute, if applicable
if(parent) {
}
// The Column has descendants
// Determine COLSPAN value for this Column
var terminalChildNodes = 0;
var countTerminalChildNodes = function(ancestor) {
// Drill down each branch and count terminal nodes
// Keep drilling down
}
// Reached branch terminus
else {
}
}
};
// Cascade certain properties to children if not defined on their own
var child = currentChildren[k];
}
}
}
}
}
}
}
// Backward compatibility
}
}
}
}
}
}
// 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 tree
}
nodeDepth--;
};
// Parse out Column instances from the array of object literals
}
// Determine ROWSPAN value for each Column in the tree
var parseTreeForRowspan = function(tree) {
var maxRowDepth = 1;
var currentRow;
var currentColumn;
// Calculate the max depth of descendants for this row
// 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;
}
};
// Store header relationships in an array for HEADERS attribute
var recurseAncestorsForHeaders = function(i, oColumn) {
}
};
headers[i] = [];
recurseAncestorsForHeaders(i, keys[i]);
}
// Save to the ColumnSet instance
};
/////////////////////////////////////////////////////////////////////////////
//
// Public member variables
//
/////////////////////////////////////////////////////////////////////////////
/**
* Internal class variable to index multiple data table instances.
*
* @property ColumnSet._nCount
* @type number
* @private
* @static
*/
/**
* Unique instance name.
*
* @property _sName
* @type String
* @private
*/
/////////////////////////////////////////////////////////////////////////////
//
// Public member variables
//
/////////////////////////////////////////////////////////////////////////////
/**
* Top-down tree representation of Column hierarchy.
*
* @property tree
* @type YAHOO.widget.Column[]
*/
/**
* Flattened representation of all Columns.
*
* @property flat
* @type YAHOO.widget.Column[]
* @default []
*/
/**
* Array of Columns that map one-to-one to a table column.
*
* @property keys
* @type YAHOO.widget.Column[]
* @default []
*/
/**
* ID index of nested parent hierarchies for HEADERS accessibility attribute.
*
* @property headers
* @type String[]
* @default []
*/
/////////////////////////////////////////////////////////////////////////////
//
// Public methods
//
/////////////////////////////////////////////////////////////////////////////
/**
* Public accessor to the unique name of the ColumnSet instance.
*
* @method toString
* @return {String} Unique name of the ColumnSet instance.
*/
return "ColumnSet " + this._sName;
};
/**
* Returns Column instance with given ID number or key.
*
* @method getColumn
* @param column {Number | String} ID number or unique key.
* @return {YAHOO.widget.Column} Column instance.
*/
var allColumns = this.flat;
return allColumns[i];
}
}
}
return allColumns[i];
}
}
}
return null;
};
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
/**
* The Column class defines and manages attributes of DataTable Columns
*
* @namespace YAHOO.widget
* @class Column
* @constructor
* @param oConfigs {Object} Object literal of configuration values.
*/
// Internal variables
// Object literal defines Column attributes
if(sConfig) {
}
}
}
}
};
/////////////////////////////////////////////////////////////////////////////
//
// Private member variables
//
/////////////////////////////////////////////////////////////////////////////
/**
* Internal instance counter.
*
* @property Column._nCount
* @type Number
* @private
* @static
* @default 0
*/
/**
* Unique instance name.
*
* @property _sName
* @type String
* @private
*/
/**
* Unique number assigned at instantiation, indicates original order within
* ColumnSet.
*
* @property _nId
* @type Number
* @private
*/
/**
* Reference to Column's index within its ColumnSet's keys array, or null if not applicable.
*
* @property _nKeyIndex
* @type Number
* @private
*/
/**
* Number of table cells the Column spans.
*
* @property _colspan
* @type Number
* @private
*/
/**
* Number of table rows the Column spans.
*
* @property _rowspan
* @type Number
* @private
*/
/**
* Column's parent Column instance, or null.
*
* @property _parent
* @type YAHOO.widget.Column
* @private
*/
/**
* Current offsetWidth of the Column (in pixels).
*
* @property _width
* @type Number
* @private
*/
/**
* Minimum width the Column can support (in pixels). Value is populated only if table
* is fixedWidth, null otherwise.
*
* @property _minWidth
* @type Number
* @private
*/
/////////////////////////////////////////////////////////////////////////////
//
// Public member variables
//
/////////////////////////////////////////////////////////////////////////////
/**
* Associated database field, or null.
*
* @property key
* @type String
*/
/**
* Text or HTML for display as Column's label in the TH element.
*
* @property label
* @type String
*/
/**
* Column head cell ABBR for accessibility.
*
* @property abbr
* @type String
*/
/**
* Array of object literals that define children (nested headers) of a Column.
*
* @property children
* @type Object[]
*/
/**
* Column width.
*
* @property width
* @type String
*/
/**
* Custom CSS class or array of classes to be applied to every cell in the Column.
*
* @property className
* @type String || String[]
*/
/**
* Defines a format function.
*
* @property formatter
* @type String || HTMLFunction
*/
/**
* Defines an editor function, otherwise Column is not editable.
*
* @property editor
* @type String || HTMLFunction
*/
/**
* Defines editor options for Column in an object literal of param:value pairs.
*
* @property editorOptions
* @type Object
*/
/**
* True if Column is resizeable, false otherwise.
*
* @property resizeable
* @type Boolean
* @default false
*/
/**
* True if Column is sortable, false otherwise.
*
* @property sortable
* @type Boolean
* @default false
*/
/**
* Default sort order for Column: "asc" or "desc".
*
* @property sortOptions.defaultOrder
* @type String
* @default null
*/
/**
* Custom sort handler.
*
* @property sortOptions.sortFunction
* @type Function
* @default null
*/
/////////////////////////////////////////////////////////////////////////////
//
// Public methods
//
/////////////////////////////////////////////////////////////////////////////
/**
* Public accessor to the unique name of the Column instance.
*
* @method toString
* @return {String} Column's unique name.
*/
return this._sName;
};
/**
* Returns unique number assigned at instantiation, indicates original order
* within ColumnSet.
*
* @method getId
* @return {Number} Column's unique ID number.
*/
return this._nId;
};
/**
* Public accessor returns Column's key index within its ColumnSet's keys array, or
* null if not applicable.
*
* @method getKeyIndex
* @return {Number} Column's key index within its ColumnSet keys array, if applicable.
*/
return this._nKeyIndex;
};
/**
* Public accessor returns Column's parent instance if any, or null otherwise.
*
* @method getParent
* @return {YAHOO.widget.Column} Column's parent instance.
*/
return this._parent;
};
/**
* Public accessor returns Column's calculated COLSPAN value.
*
* @method getColspan
* @return {Number} Column's COLSPAN value.
*/
return this._colspan;
};
// Backward compatibility
return this.getColspan();
};
/**
* Public accessor returns Column's calculated ROWSPAN value.
*
* @method getRowspan
* @return {Number} Column's ROWSPAN value.
*/
return this._rowspan;
};
// Backward compatibility
return this.getKeyIndex();
};
};
};
};
};
};
};
};
};
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
/**
* Sort static utility to support Column sorting.
*
* @namespace YAHOO.util
* @class Sort
* @static
*/
/////////////////////////////////////////////////////////////////////////////
//
// Public methods
//
/////////////////////////////////////////////////////////////////////////////
/**
* Comparator function for simple case-insensitive string sorting.
*
* @method compare
* @param a {Object} First sort argument.
* @param b {Object} Second sort argument.
* @param desc {Boolean} True if sort direction is descending, false if
* sort direction is ascending.
*/
if((a === null) || (typeof a == "undefined")) {
if((b === null) || (typeof b == "undefined")) {
return 0;
}
else {
return 1;
}
}
else if((b === null) || (typeof b == "undefined")) {
return -1;
}
if(a.constructor == String) {
a = a.toLowerCase();
}
if(b.constructor == String) {
b = b.toLowerCase();
}
if(a < b) {
}
else if (a > b) {
}
else {
return 0;
}
}
};
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
/**
* ColumnResizer subclasses DragDrop to support resizeable Columns.
*
* @namespace YAHOO.util
* @class ColumnResizer
* @extends YAHOO.util.DragDrop
* @constructor
* @param oDataTable {YAHOO.widget.DataTable} DataTable instance.
* @param oColumn {YAHOO.widget.Column} Column instance.
* @param elThead {HTMLElement} TH element reference.
* @param sHandleElId {String} DOM ID of the handle element that causes the resize.
* @param sGroup {String} Group name of related DragDrop items.
* @param oConfig {Object} (Optional) Object literal of config values.
*/
this.datatable = oDataTable;
//this.initFrame();
}
else {
}
};
}
/////////////////////////////////////////////////////////////////////////////
//
// Public DOM event handlers
//
/////////////////////////////////////////////////////////////////////////////
/**
* Handles mousedown events on the Column resizer.
*
* @method onMouseDown
* @param e {string} The mousedown event
*/
if(this.datatable.fixedWidth) {
var cellLabel = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_LABEL,"span",this.cell)[0];
var sibCellLabel = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_LABEL,"span",sib)[0];
//!!
}
};
/**
* Handles mouseup events on the Column resizer.
*
* @method onMouseUp
* @param e {string} The mouseup event
*/
//TODO: replace the resizer where it belongs:
//.yui-dt-headresizer {position:absolute;margin-right:-6px;right:0;bottom:0;width:6px;height:100%;cursor:w-resize;cursor:col-resize;}
//var cells = this.datatable._elTable.tHead.rows[this.datatable._elTable.tHead.rows.length-1].cells;
//for(var i=0; i<cells.length; i++) {
//cells[i].style.width = "5px";
//}
//TODO: set new ColumnSet width values
};
/**
* Handles drag events on the Column resizer.
*
* @method onDrag
* @param e {string} The drag event
*/
}
// Resize the Column
var oDataTable = this.datatable;
// Resize the other Columns
if(oDataTable.fixedWidth) {
// Moving right or left?
//var sibIndex = elCell.index + 1;
if(sibnewwidth < this.sibMinWidth) {
sibnewwidth = this.sibMinWidth;
}
//TODO: how else to cycle through all the Columns without having to use an index property?
//if((i != elCell.index) && (i!=sibIndex)) {
// YAHOO.util.Dom.get(oDataTable._oColumnSet.keys[i].id).style.width = oDataTable._oColumnSet.keys[i].width + "px";
//}
}
//oDataTable._oColumnSet.flat[sibIndex].width = sibnewwidth;
//oDataTable._oColumnSet.flat[elCell.index].width = newWidth;
}
else {
}
};
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
/**
* A RecordSet defines and manages a set of Records.
*
* @namespace YAHOO.widget
* @class RecordSet
* @param data {Object || Object[]} An object literal or an array of data.
* @constructor
*/
// Internal variables
this._records = [];
this._length = 0;
if(data) {
this.addRecords(data);
}
else if(data.constructor == Object) {
}
}
/**
* Fired when a new Record is added to the RecordSet.
*
* @event recordAddEvent
* @param oArgs.record {YAHOO.widget.Record} The Record instance.
* @param oArgs.data {Object} Data added.
*/
this.createEvent("recordAddEvent");
/**
* Fired when multiple Records are added to the RecordSet at once.
*
* @event recordsAddEvent
* @param oArgs.records {YAHOO.widget.Record[]} An array of Record instances.
* @param oArgs.data {Object[]} Data added.
*/
this.createEvent("recordsAddEvent");
/**
* Fired when a Record is updated with new data.
*
* @event recordUpdateEvent
* @param oArgs.record {YAHOO.widget.Record} The Record instance.
* @param oArgs.newData {Object} New data.
* @param oArgs.oldData {Object} Old data.
*/
this.createEvent("recordUpdateEvent");
/**
* Fired when a Record is deleted from the RecordSet.
*
* @event recordDeleteEvent
* @param oArgs.data {Object} A copy of the data held by the Record,
* or an array of data object literals if multiple Records were deleted at once.
* @param oArgs.index {Object} Index of the deleted Record.
*/
this.createEvent("recordDeleteEvent");
/**
* Fired when multiple Records are deleted from the RecordSet at once.
*
* @event recordsDeleteEvent
* @param oArgs.data {Object[]} An array of data object literals copied
* from the Records.
* @param oArgs.index {Object} Index of the first deleted Record.
*/
this.createEvent("recordsDeleteEvent");
/**
* Fired when all Records are deleted from the RecordSet at once.
*
* @event resetEvent
*/
this.createEvent("resetEvent");
/**
* Fired when a Record Key is updated with new data.
*
* @event keyUpdateEvent
* @param oArgs.record {YAHOO.widget.Record} The Record instance.
* @param oArgs.key {String} The updated key.
* @param oArgs.newData {Object} New data.
* @param oArgs.oldData {Object} Old data.
*
*/
this.createEvent("keyUpdateEvent");
};
}
else {
}
/////////////////////////////////////////////////////////////////////////////
//
// Private member variables
//
/////////////////////////////////////////////////////////////////////////////
/**
* Internal class variable to name multiple Recordset instances.
*
* @property RecordSet._nCount
* @type Number
* @private
* @static
*/
/**
* Unique instance name.
*
* @property _sName
* @type String
* @private
*/
/**
* Internal variable to give unique indexes to Record instances.
*
* @property _nCount
* @type Number
* @private
*/
/**
* Internal counter of how many Records are in the RecordSet.
*
* @property _length
* @type Number
* @private
*/
/////////////////////////////////////////////////////////////////////////////
//
// Private methods
//
/////////////////////////////////////////////////////////////////////////////
/**
* Adds one Record to the RecordSet at the given index. If index is null,
* then adds the Record to the end of the RecordSet.
*
* @method _addRecord
* @param oData {Object} An object literal of data.
* @param index {Number} (optional) Position index.
* @return {YAHOO.widget.Record} A Record instance.
* @private
*/
this._nRecordCount++;
}
else {
}
this._length++;
return oRecord;
};
/**
* Deletes Records from the RecordSet at the given index. If range is null,
* then only one Record is deleted.
*
* @method _deleteRecord
* @param index {Number} Position index.
* @param range {Number} (optional) How many Records to delete
* @private
*/
range = 1;
}
};
/////////////////////////////////////////////////////////////////////////////
//
// Public methods
//
/////////////////////////////////////////////////////////////////////////////
/**
* Public accessor to the unique name of the RecordSet instance.
*
* @method toString
* @return {String} Unique name of the RecordSet instance.
*/
return this._sName;
};
/**
* Returns the number of Records held in the RecordSet.
*
* @method getLength
* @return {Number} Number of records in the RecordSet.
*/
return this._length;
};
/**
* Returns Record at given position index.
*
* @method getRecord
* @param index {Number} Record's Recordset position index.
* @return {YAHOO.widget.Record} Record object.
*/
}
/*else if(YAHOO.lang.isString(identifier)) {
for(var i=0; i<this._records.length; i++) {
if(this._records[i].yuiRecordId == identifier) {
return this._records[i];
}
}
}*/
return null;
};
/*
* Returns an array of Records from the RecordSet.
*
* @method getRecords
* @param index {Number} (optional) Recordset position index of which Record to
* start at.
* @param range {Number} (optional) Number of Records to get.
* @return {YAHOO.widget.Record[]} Array of Records starting at given index and
* length equal to given range. If index is not given, all Records are returned.
*/
return this._records;
}
}
};
/**
* Returns position index for the given Record.
*
* @method getRecordIndex
* @param oRecord {YAHOO.widget.Record} Record instance.
* @return {Number} Record's RecordSet position index.
*/
return i;
}
}
return null;
};
/**
* Adds one Record to the RecordSet at the given index. If index is null,
* then adds the Record to the end of the RecordSet.
*
* @method addRecord
* @param oData {Object} An object literal of data.
* @param index {Number} (optional) Position index.
* @return {YAHOO.widget.Record} A Record instance.
*/
return oRecord;
}
else {
return null;
}
};
/**
* Adds multiple Records at once to the RecordSet at the given index with the
* given data. If index is null, then the new Records are added to the end of
* the RecordSet.
*
* @method addRecords
* @param aData {Object[]} An array of object literal data.
* @param index {Number} (optional) Position index.
* @return {YAHOO.widget.Record[]} An array of Record instances.
*/
var newRecords = [];
// Can't go backwards bc we need to preserve order
}
}
return newRecords;
}
return oRecord;
}
else {
}
};
/**
* Updates given Record with given data.
*
* @method updateRecord
* @param record {YAHOO.widget.Record | Number} A Record instance, or Record's
* RecordSet position index.
* @param oData {Object) Object literal of new data.
* @return {YAHOO.widget.Record} Updated Record, or null.
*/
var oRecord = null;
}
}
// Copy data from the Record for the event that gets fired later
var oldData = {};
}
return oRecord;
}
else {
return null;
}
};
/**
* Updates given Record at given key with given data.
*
* @method updateKey
* @param record {YAHOO.widget.Record | Number} A Record instance, or Record's
* RecordSet position index.
* @param sKey {String} Key name.
* @param oData {Object) New data.
*/
var oRecord;
}
var oldData = null;
// Copy data from the Record for the event that gets fired later
oldData = {};
}
}
// Copy by value
else {
}
}
else {
}
};
/**
* Replaces all Records in RecordSet with new data.
*
* @method replaceRecords
* @param data {Object || Object[]} An object literal of data or an array of
* object literal data.
* @return {YAHOO.widget.Record || YAHOO.widget.Record[]} A Record instance or
* an array of Records.
*/
this.reset();
return this.addRecords(data);
};
/**
* Sorts all Records by given function.
*
* @method sortRecords
* @param fnSort {Function} Reference to a sort function.
* @param desc {Boolean} True if sort direction is descending, false if sort
* direction is ascending.
* @return {YAHOO.widget.Record[]} Sorted array of Records.
*/
};
/**
* Removes the Record at the given position index from the RecordSet. If a range
* is also provided, removes that many Records, starting from the index. Length
* of RecordSet is correspondingly shortened.
*
* @method deleteRecord
* @param index {Number} Record's RecordSet position index.
* @param range {Number} (optional) How many Records to delete.
* @return {Object} A copy of the data held by the deleted Record.
*/
// Copy data from the Record for the event that gets fired later
var oData = {};
for(var key in oRecordData) {
}
this._deleteRecord(index);
return oData;
}
else {
return null;
}
};
/**
* Removes the Record at the given position index from the RecordSet. If a range
* is also provided, removes that many Records, starting from the index. Length
* of RecordSet is correspondingly shortened.
*
* @method deleteRecords
* @param index {Number} Record's RecordSet position index.
* @param range {Number} (optional) How many Records to delete.
*/
range = 1;
}
// Copy data from each Record for the event that gets fired later
var deletedData = [];
var oData = {};
for(var key in recordsToDelete[i]) {
}
}
}
else {
}
};
/**
* Deletes all Records from the RecordSet.
*
* @method reset
*/
this._records = [];
this._length = 0;
this.fireEvent("resetEvent");
};
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
/**
* The Record class defines a DataTable record.
*
* @namespace YAHOO.widget
* @class Record
* @constructor
*/
this._oData = {};
}
}
};
/////////////////////////////////////////////////////////////////////////////
//
// Private member variables
//
/////////////////////////////////////////////////////////////////////////////
/**
* Unique number assigned at instantiation, indicates original order within
* RecordSet.
*
* @property _nId
* @type Number
* @private
*/
/**
* Holds data for the Record in an object literal.
*
* @property _oData
* @type Object
* @private
*/
/////////////////////////////////////////////////////////////////////////////
//
// Public member variables
//
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
// Public methods
//
/////////////////////////////////////////////////////////////////////////////
/**
* Returns unique number assigned at instantiation, indicates original order
* within RecordSet.
*
* @method getId
* @return Number
*/
return this._nId;
};
/**
* Returns data for the Record for a key if given, or the entire object
* literal otherwise.
*
* @method getData
* @param sKey {String} (Optional) The key to retrieve a single data value.
* @return Object
*/
}
else {
return this._oData;
}
};