| /* |
| Copyright (c) 2004-2006, The Dojo Foundation |
| All Rights Reserved. |
| |
| Licensed under the Academic Free License version 2.1 or above OR the |
| modified BSD license. For more information on Dojo licensing, see: |
| |
| http://dojotoolkit.org/community/licensing.shtml |
| */ |
| |
| |
| |
| dojo.provide("dojo.widget.SortableTable"); |
| dojo.deprecated("SortableTable will be removed in favor of FilteringTable.", "0.5"); |
| dojo.require("dojo.lang.common"); |
| dojo.require("dojo.date.format"); |
| dojo.require("dojo.html.*"); |
| dojo.require("dojo.html.selection"); |
| dojo.require("dojo.html.util"); |
| dojo.require("dojo.html.style"); |
| dojo.require("dojo.event.*"); |
| dojo.require("dojo.widget.*"); |
| dojo.require("dojo.widget.HtmlWidget"); |
| dojo.widget.defineWidget("dojo.widget.SortableTable", dojo.widget.HtmlWidget, function () { |
| this.data = []; |
| this.selected = []; |
| this.columns = []; |
| }, {enableMultipleSelect:false, maximumNumberOfSelections:0, enableAlternateRows:false, minRows:0, defaultDateFormat:"%D", sortIndex:0, sortDirection:0, valueField:"Id", headClass:"", tbodyClass:"", headerClass:"", headerSortUpClass:"selected", headerSortDownClass:"selected", rowClass:"", rowAlternateClass:"alt", rowSelectedClass:"selected", columnSelected:"sorted-column", isContainer:false, templatePath:null, templateCssPath:null, getTypeFromString:function (s) { |
| var parts = s.split("."), i = 0, obj = dj_global; |
| do { |
| obj = obj[parts[i++]]; |
| } while (i < parts.length && obj); |
| return (obj != dj_global) ? obj : null; |
| }, compare:function (o1, o2) { |
| for (var p in o1) { |
| if (!(p in o2)) { |
| return false; |
| } |
| if (o1[p].valueOf() != o2[p].valueOf()) { |
| return false; |
| } |
| } |
| return true; |
| }, isSelected:function (o) { |
| for (var i = 0; i < this.selected.length; i++) { |
| if (this.compare(this.selected[i], o)) { |
| return true; |
| } |
| } |
| return false; |
| }, removeFromSelected:function (o) { |
| var idx = -1; |
| for (var i = 0; i < this.selected.length; i++) { |
| if (this.compare(this.selected[i], o)) { |
| idx = i; |
| break; |
| } |
| } |
| if (idx >= 0) { |
| this.selected.splice(idx, 1); |
| } |
| }, getSelection:function () { |
| return this.selected; |
| }, getValue:function () { |
| var a = []; |
| for (var i = 0; i < this.selected.length; i++) { |
| if (this.selected[i][this.valueField]) { |
| a.push(this.selected[i][this.valueField]); |
| } |
| } |
| return a.join(); |
| }, reset:function () { |
| this.columns = []; |
| this.data = []; |
| this.resetSelections(this.domNode.getElementsByTagName("tbody")[0]); |
| }, resetSelections:function (body) { |
| this.selected = []; |
| var idx = 0; |
| var rows = body.getElementsByTagName("tr"); |
| for (var i = 0; i < rows.length; i++) { |
| if (rows[i].parentNode == body) { |
| rows[i].removeAttribute("selected"); |
| if (this.enableAlternateRows && idx % 2 == 1) { |
| rows[i].className = this.rowAlternateClass; |
| } else { |
| rows[i].className = ""; |
| } |
| idx++; |
| } |
| } |
| }, getObjectFromRow:function (row) { |
| var cells = row.getElementsByTagName("td"); |
| var o = {}; |
| for (var i = 0; i < this.columns.length; i++) { |
| if (this.columns[i].sortType == "__markup__") { |
| o[this.columns[i].getField()] = cells[i].innerHTML; |
| } else { |
| var text = dojo.html.renderedTextContent(cells[i]); |
| var val = text; |
| if (this.columns[i].getType() != String) { |
| var val = new (this.columns[i].getType())(text); |
| } |
| o[this.columns[i].getField()] = val; |
| } |
| } |
| if (dojo.html.hasAttribute(row, "value")) { |
| o[this.valueField] = dojo.html.getAttribute(row, "value"); |
| } |
| return o; |
| }, setSelectionByRow:function (row) { |
| var o = this.getObjectFromRow(row); |
| var b = false; |
| for (var i = 0; i < this.selected.length; i++) { |
| if (this.compare(this.selected[i], o)) { |
| b = true; |
| break; |
| } |
| } |
| if (!b) { |
| this.selected.push(o); |
| } |
| }, parseColumns:function (node) { |
| this.reset(); |
| var row = node.getElementsByTagName("tr")[0]; |
| var cells = row.getElementsByTagName("td"); |
| if (cells.length == 0) { |
| cells = row.getElementsByTagName("th"); |
| } |
| for (var i = 0; i < cells.length; i++) { |
| var o = {field:null, format:null, noSort:false, sortType:"String", dataType:String, sortFunction:null, label:null, align:"left", valign:"middle", getField:function () { |
| return this.field || this.label; |
| }, getType:function () { |
| return this.dataType; |
| }}; |
| if (dojo.html.hasAttribute(cells[i], "align")) { |
| o.align = dojo.html.getAttribute(cells[i], "align"); |
| } |
| if (dojo.html.hasAttribute(cells[i], "valign")) { |
| o.valign = dojo.html.getAttribute(cells[i], "valign"); |
| } |
| if (dojo.html.hasAttribute(cells[i], "nosort")) { |
| o.noSort = dojo.html.getAttribute(cells[i], "nosort") == "true"; |
| } |
| if (dojo.html.hasAttribute(cells[i], "sortusing")) { |
| var trans = dojo.html.getAttribute(cells[i], "sortusing"); |
| var f = this.getTypeFromString(trans); |
| if (f != null && f != window && typeof (f) == "function") { |
| o.sortFunction = f; |
| } |
| } |
| if (dojo.html.hasAttribute(cells[i], "field")) { |
| o.field = dojo.html.getAttribute(cells[i], "field"); |
| } |
| if (dojo.html.hasAttribute(cells[i], "format")) { |
| o.format = dojo.html.getAttribute(cells[i], "format"); |
| } |
| if (dojo.html.hasAttribute(cells[i], "dataType")) { |
| var sortType = dojo.html.getAttribute(cells[i], "dataType"); |
| if (sortType.toLowerCase() == "html" || sortType.toLowerCase() == "markup") { |
| o.sortType = "__markup__"; |
| o.noSort = true; |
| } else { |
| var type = this.getTypeFromString(sortType); |
| if (type) { |
| o.sortType = sortType; |
| o.dataType = type; |
| } |
| } |
| } |
| o.label = dojo.html.renderedTextContent(cells[i]); |
| this.columns.push(o); |
| if (dojo.html.hasAttribute(cells[i], "sort")) { |
| this.sortIndex = i; |
| var dir = dojo.html.getAttribute(cells[i], "sort"); |
| if (!isNaN(parseInt(dir))) { |
| dir = parseInt(dir); |
| this.sortDirection = (dir != 0) ? 1 : 0; |
| } else { |
| this.sortDirection = (dir.toLowerCase() == "desc") ? 1 : 0; |
| } |
| } |
| } |
| }, parseData:function (data) { |
| this.data = []; |
| this.selected = []; |
| for (var i = 0; i < data.length; i++) { |
| var o = {}; |
| for (var j = 0; j < this.columns.length; j++) { |
| var field = this.columns[j].getField(); |
| if (this.columns[j].sortType == "__markup__") { |
| o[field] = String(data[i][field]); |
| } else { |
| var type = this.columns[j].getType(); |
| var val = data[i][field]; |
| var t = this.columns[j].sortType.toLowerCase(); |
| if (type == String) { |
| o[field] = val; |
| } else { |
| if (val != null) { |
| o[field] = new type(val); |
| } else { |
| o[field] = new type(); |
| } |
| } |
| } |
| } |
| if (data[i][this.valueField] && !o[this.valueField]) { |
| o[this.valueField] = data[i][this.valueField]; |
| } |
| this.data.push(o); |
| } |
| }, parseDataFromTable:function (tbody) { |
| this.data = []; |
| this.selected = []; |
| var rows = tbody.getElementsByTagName("tr"); |
| for (var i = 0; i < rows.length; i++) { |
| if (dojo.html.getAttribute(rows[i], "ignoreIfParsed") == "true") { |
| continue; |
| } |
| var o = {}; |
| var cells = rows[i].getElementsByTagName("td"); |
| for (var j = 0; j < this.columns.length; j++) { |
| var field = this.columns[j].getField(); |
| if (this.columns[j].sortType == "__markup__") { |
| o[field] = cells[j].innerHTML; |
| } else { |
| var type = this.columns[j].getType(); |
| var val = dojo.html.renderedTextContent(cells[j]); |
| if (type == String) { |
| o[field] = val; |
| } else { |
| if (val != null) { |
| o[field] = new type(val); |
| } else { |
| o[field] = new type(); |
| } |
| } |
| } |
| } |
| if (dojo.html.hasAttribute(rows[i], "value") && !o[this.valueField]) { |
| o[this.valueField] = dojo.html.getAttribute(rows[i], "value"); |
| } |
| this.data.push(o); |
| if (dojo.html.getAttribute(rows[i], "selected") == "true") { |
| this.selected.push(o); |
| } |
| } |
| }, showSelections:function () { |
| var body = this.domNode.getElementsByTagName("tbody")[0]; |
| var rows = body.getElementsByTagName("tr"); |
| var idx = 0; |
| for (var i = 0; i < rows.length; i++) { |
| if (rows[i].parentNode == body) { |
| if (dojo.html.getAttribute(rows[i], "selected") == "true") { |
| rows[i].className = this.rowSelectedClass; |
| } else { |
| if (this.enableAlternateRows && idx % 2 == 1) { |
| rows[i].className = this.rowAlternateClass; |
| } else { |
| rows[i].className = ""; |
| } |
| } |
| idx++; |
| } |
| } |
| }, render:function (bDontPreserve) { |
| var data = []; |
| var body = this.domNode.getElementsByTagName("tbody")[0]; |
| if (!bDontPreserve) { |
| this.parseDataFromTable(body); |
| } |
| for (var i = 0; i < this.data.length; i++) { |
| data.push(this.data[i]); |
| } |
| var col = this.columns[this.sortIndex]; |
| if (!col.noSort) { |
| var field = col.getField(); |
| if (col.sortFunction) { |
| var sort = col.sortFunction; |
| } else { |
| var sort = function (a, b) { |
| if (a[field] > b[field]) { |
| return 1; |
| } |
| if (a[field] < b[field]) { |
| return -1; |
| } |
| return 0; |
| }; |
| } |
| data.sort(sort); |
| if (this.sortDirection != 0) { |
| data.reverse(); |
| } |
| } |
| while (body.childNodes.length > 0) { |
| body.removeChild(body.childNodes[0]); |
| } |
| for (var i = 0; i < data.length; i++) { |
| var row = document.createElement("tr"); |
| dojo.html.disableSelection(row); |
| if (data[i][this.valueField]) { |
| row.setAttribute("value", data[i][this.valueField]); |
| } |
| if (this.isSelected(data[i])) { |
| row.className = this.rowSelectedClass; |
| row.setAttribute("selected", "true"); |
| } else { |
| if (this.enableAlternateRows && i % 2 == 1) { |
| row.className = this.rowAlternateClass; |
| } |
| } |
| for (var j = 0; j < this.columns.length; j++) { |
| var cell = document.createElement("td"); |
| cell.setAttribute("align", this.columns[j].align); |
| cell.setAttribute("valign", this.columns[j].valign); |
| dojo.html.disableSelection(cell); |
| if (this.sortIndex == j) { |
| cell.className = this.columnSelected; |
| } |
| if (this.columns[j].sortType == "__markup__") { |
| cell.innerHTML = data[i][this.columns[j].getField()]; |
| for (var k = 0; k < cell.childNodes.length; k++) { |
| var node = cell.childNodes[k]; |
| if (node && node.nodeType == dojo.html.ELEMENT_NODE) { |
| dojo.html.disableSelection(node); |
| } |
| } |
| } else { |
| if (this.columns[j].getType() == Date) { |
| var format = this.defaultDateFormat; |
| if (this.columns[j].format) { |
| format = this.columns[j].format; |
| } |
| cell.appendChild(document.createTextNode(dojo.date.strftime(data[i][this.columns[j].getField()], format))); |
| } else { |
| cell.appendChild(document.createTextNode(data[i][this.columns[j].getField()])); |
| } |
| } |
| row.appendChild(cell); |
| } |
| body.appendChild(row); |
| dojo.event.connect(row, "onclick", this, "onUISelect"); |
| } |
| var minRows = parseInt(this.minRows); |
| if (!isNaN(minRows) && minRows > 0 && data.length < minRows) { |
| var mod = 0; |
| if (data.length % 2 == 0) { |
| mod = 1; |
| } |
| var nRows = minRows - data.length; |
| for (var i = 0; i < nRows; i++) { |
| var row = document.createElement("tr"); |
| row.setAttribute("ignoreIfParsed", "true"); |
| if (this.enableAlternateRows && i % 2 == mod) { |
| row.className = this.rowAlternateClass; |
| } |
| for (var j = 0; j < this.columns.length; j++) { |
| var cell = document.createElement("td"); |
| cell.appendChild(document.createTextNode("\xa0")); |
| row.appendChild(cell); |
| } |
| body.appendChild(row); |
| } |
| } |
| }, onSelect:function (e) { |
| }, onUISelect:function (e) { |
| var row = dojo.html.getParentByType(e.target, "tr"); |
| var body = dojo.html.getParentByType(row, "tbody"); |
| if (this.enableMultipleSelect) { |
| if (e.metaKey || e.ctrlKey) { |
| if (this.isSelected(this.getObjectFromRow(row))) { |
| this.removeFromSelected(this.getObjectFromRow(row)); |
| row.removeAttribute("selected"); |
| } else { |
| this.setSelectionByRow(row); |
| row.setAttribute("selected", "true"); |
| } |
| } else { |
| if (e.shiftKey) { |
| var startRow; |
| var rows = body.getElementsByTagName("tr"); |
| for (var i = 0; i < rows.length; i++) { |
| if (rows[i].parentNode == body) { |
| if (rows[i] == row) { |
| break; |
| } |
| if (dojo.html.getAttribute(rows[i], "selected") == "true") { |
| startRow = rows[i]; |
| } |
| } |
| } |
| if (!startRow) { |
| startRow = row; |
| for (; i < rows.length; i++) { |
| if (dojo.html.getAttribute(rows[i], "selected") == "true") { |
| row = rows[i]; |
| break; |
| } |
| } |
| } |
| this.resetSelections(body); |
| if (startRow == row) { |
| row.setAttribute("selected", "true"); |
| this.setSelectionByRow(row); |
| } else { |
| var doSelect = false; |
| for (var i = 0; i < rows.length; i++) { |
| if (rows[i].parentNode == body) { |
| rows[i].removeAttribute("selected"); |
| if (rows[i] == startRow) { |
| doSelect = true; |
| } |
| if (doSelect) { |
| this.setSelectionByRow(rows[i]); |
| rows[i].setAttribute("selected", "true"); |
| } |
| if (rows[i] == row) { |
| doSelect = false; |
| } |
| } |
| } |
| } |
| } else { |
| this.resetSelections(body); |
| row.setAttribute("selected", "true"); |
| this.setSelectionByRow(row); |
| } |
| } |
| } else { |
| this.resetSelections(body); |
| row.setAttribute("selected", "true"); |
| this.setSelectionByRow(row); |
| } |
| this.showSelections(); |
| this.onSelect(e); |
| e.stopPropagation(); |
| e.preventDefault(); |
| }, onHeaderClick:function (e) { |
| var oldIndex = this.sortIndex; |
| var oldDirection = this.sortDirection; |
| var source = e.target; |
| var row = dojo.html.getParentByType(source, "tr"); |
| var cellTag = "td"; |
| if (row.getElementsByTagName(cellTag).length == 0) { |
| cellTag = "th"; |
| } |
| var headers = row.getElementsByTagName(cellTag); |
| var header = dojo.html.getParentByType(source, cellTag); |
| for (var i = 0; i < headers.length; i++) { |
| if (headers[i] == header) { |
| if (i != oldIndex) { |
| this.sortIndex = i; |
| this.sortDirection = 0; |
| headers[i].className = this.headerSortDownClass; |
| } else { |
| this.sortDirection = (oldDirection == 0) ? 1 : 0; |
| if (this.sortDirection == 0) { |
| headers[i].className = this.headerSortDownClass; |
| } else { |
| headers[i].className = this.headerSortUpClass; |
| } |
| } |
| } else { |
| headers[i].className = this.headerClass; |
| } |
| } |
| this.render(); |
| }, postCreate:function () { |
| var thead = this.domNode.getElementsByTagName("thead")[0]; |
| if (this.headClass.length > 0) { |
| thead.className = this.headClass; |
| } |
| dojo.html.disableSelection(this.domNode); |
| this.parseColumns(thead); |
| var header = "td"; |
| if (thead.getElementsByTagName(header).length == 0) { |
| header = "th"; |
| } |
| var headers = thead.getElementsByTagName(header); |
| for (var i = 0; i < headers.length; i++) { |
| if (!this.columns[i].noSort) { |
| dojo.event.connect(headers[i], "onclick", this, "onHeaderClick"); |
| } |
| if (this.sortIndex == i) { |
| if (this.sortDirection == 0) { |
| headers[i].className = this.headerSortDownClass; |
| } else { |
| headers[i].className = this.headerSortUpClass; |
| } |
| } |
| } |
| var tbody = this.domNode.getElementsByTagName("tbody")[0]; |
| if (this.tbodyClass.length > 0) { |
| tbody.className = this.tbodyClass; |
| } |
| this.parseDataFromTable(tbody); |
| this.render(true); |
| }}); |
| |