liuyg
2021-07-02 25ce610f6ecca7325e7a743dc032c4a76559c63d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
define([
    'dojo/_base/declare',
    'dojo/aspect',
    'dojo/dom-class',
    'dojo/on',
    'dojo/has',
    './Selection'
], function (declare, aspect, domClass, listen, has, Selection) {
 
    return declare(Selection, {
        // summary:
        //        Add cell level selection capabilities to a grid. The grid will have a selection property and
        //        fire "dgrid-select" and "dgrid-deselect" events.
 
        // ensure we don't select when an individual cell is not identifiable
        selectionDelegate: '.dgrid-cell',
 
        _selectionTargetType: 'cells',
 
        _select: function (cell, toCell, value) {
            var i,
                id;
            if (typeof value === 'undefined') {
                // default to true
                value = true;
            }
            if (typeof cell !== 'object' || !('element' in cell)) {
                cell = this.cell(cell);
            }
            else if (!cell.row) {
                // Row object was passed instead of cell
                if (value && typeof value === 'object') {
                    // value is a hash of true/false values
                    for (id in value) {
                        this._select(this.cell(cell.id, id), null, value[id]);
                    }
                }
                else {
                    // Select/deselect all columns in row
                    for (id in this.columns) {
                        this._select(this.cell(cell.id, id), null, value);
                    }
                }
                return;
            }
            if (this.allowSelect(cell)) {
                var selection = this.selection,
                    rowId = cell.row.id,
                    previousRow = selection[rowId];
                if (!cell.column) {
                    for (i in this.columns) {
                        this._select(this.cell(rowId, i), null, value);
                    }
                    return;
                }
                var previous = previousRow && previousRow[cell.column.id];
                if (value === null) {
                    // indicates a toggle
                    value = !previous;
                }
                var element = cell.element;
                previousRow = previousRow || {};
                previousRow[cell.column.id] = value;
                this.selection[rowId] = previousRow;
 
                // Check for all-false objects to see if it can be deleted.
                // This prevents build-up of unnecessary iterations later.
                var hasSelected = false;
                for (i in previousRow) {
                    if (previousRow[i] === true) {
                        hasSelected = true;
                        break;
                    }
                }
                if (!hasSelected) {
                    delete this.selection[rowId];
                }
 
                if (element) {
                    // add or remove classes as appropriate
                    if (value) {
                        domClass.add(element, 'dgrid-selected' +
                            (this.addUiClasses ? ' ui-state-active' : ''));
                    }
                    else {
                        domClass.remove(element, 'dgrid-selected ui-state-active');
                    }
                }
                /* jshint eqeqeq: false */
                // This comparison could coerce if previous is undefined; TODO: rewrite
                if (value != previous && element) {
                    this._selectionEventQueues[(value ? '' : 'de') + 'select'].push(cell);
                }
                if (toCell) {
                    if (!toCell.element) {
                        toCell = this.cell(toCell);
                    }
 
                    if (!toCell || !toCell.row) {
                        this._lastSelected = element;
                        console.warn('The selection range has been reset because the ' +
                            'beginning of the selection is no longer in the DOM. ' +
                            'If you are using OnDemandList, you may wish to increase ' +
                            'farOffRemoval to avoid this, but note that keeping more nodes ' +
                            'in the DOM may impact performance.');
                        return;
                    }
 
                    var toElement = toCell.element;
                    var fromElement = cell.element;
                    // Find if it is earlier or later in the DOM
                    var direction = this._determineSelectionDirection(fromElement, toElement);
                    if (!direction) {
                        // The original element was actually replaced
                        toCell = this.cell(
                            document.getElementById(toCell.row.element.id), toElement.columnId);
                        toElement = toCell && toCell.element;
                        direction = this._determineSelectionDirection(fromElement, toElement);
                    }
                    // now we determine which columns are in the range
                    var idFrom = cell.column.id,
                        idTo = toCell.column.id,
                        started,
                        columnIds = [];
 
                    for (id in this.columns) {
                        if (started) {
                            columnIds.push(id);
                        }
                        if (id === idFrom && (idFrom = columnIds) ||
                                id === idTo && (idTo = columnIds)) {
                            // Once found, mark it off so we don't hit it again
                            columnIds.push(id);
                            if (started || (idFrom == columnIds && id == idTo)) {
                                // We are done if we hit the last ID, or if the IDs are the same
                                break;
                            }
                            started = true;
                        }
                    }
                    // now we iterate over rows
                    var row = cell.row,
                        nextNode = row.element;
                    toElement = toCell.row.element;
                    do {
                        // looping through each row..
                        // and now loop through each column to be selected
                        for (i = 0; i < columnIds.length; i++) {
                            cell = this.cell(nextNode, columnIds[i]);
                            this._select(cell, null, value);
                        }
                        if (nextNode == toElement) {
                            break;
                        }
                    } while ((nextNode = cell.row.element[direction]));
                }
            }
        },
 
        _determineSelectionDirection: function () {
            // Extend Selection to return next/previousSibling instead of down/up,
            // given how CellSelection#_select is written
            var result = this.inherited(arguments);
            if (result === 'down') {
                return 'nextSibling';
            }
            if (result === 'up') {
                return 'previousSibling';
            }
            return result;
        },
 
        isSelected: function (object, columnId) {
            // summary:
            //        Returns true if the indicated cell is selected.
 
            if (typeof object === 'undefined' || object === null) {
                return false;
            }
            if (!object.element) {
                object = this.cell(object, columnId);
            }
 
            // First check whether the given cell is indicated in the selection hash;
            // failing that, check if allSelected is true (testing against the
            // allowSelect method if possible)
            var rowId = object.row.id;
            if (rowId in this.selection) {
                return !!this.selection[rowId][object.column.id];
            }
            else {
                return this.allSelected && (!object.row.data || this.allowSelect(object));
            }
        },
        clearSelection: function (exceptId) {
            // disable exceptId in cell selection, since it would require double parameters
            exceptId = false;
            this.inherited(arguments);
        }
    });
});