Subversion Repositories Applications.papyrus

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
        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);
}});