Subversion Repositories Applications.papyrus

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1318 alexandre_ 1
/*
2
	Copyright (c) 2004-2006, The Dojo Foundation
3
	All Rights Reserved.
4
 
5
	Licensed under the Academic Free License version 2.1 or above OR the
6
	modified BSD license. For more information on Dojo licensing, see:
7
 
8
		http://dojotoolkit.org/community/licensing.shtml
9
*/
10
 
11
dojo.provide("dojo.widget.SortableTable");
12
dojo.deprecated("SortableTable will be removed in favor of FilteringTable.", "0.5");
13
dojo.require("dojo.lang.common");
14
dojo.require("dojo.date.format");
15
dojo.require("dojo.html.*");
16
dojo.require("dojo.html.selection");
17
dojo.require("dojo.html.util");
18
dojo.require("dojo.html.style");
19
dojo.require("dojo.event.*");
20
dojo.require("dojo.widget.*");
21
dojo.require("dojo.widget.HtmlWidget");
22
dojo.widget.defineWidget("dojo.widget.SortableTable", dojo.widget.HtmlWidget, function () {
23
	this.data = [];
24
	this.selected = [];
25
	this.columns = [];
26
}, {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) {
27
	var parts = s.split("."), i = 0, obj = dj_global;
28
	do {
29
		obj = obj[parts[i++]];
30
	} while (i < parts.length && obj);
31
	return (obj != dj_global) ? obj : null;
32
}, compare:function (o1, o2) {
33
	for (var p in o1) {
34
		if (!(p in o2)) {
35
			return false;
36
		}
37
		if (o1[p].valueOf() != o2[p].valueOf()) {
38
			return false;
39
		}
40
	}
41
	return true;
42
}, isSelected:function (o) {
43
	for (var i = 0; i < this.selected.length; i++) {
44
		if (this.compare(this.selected[i], o)) {
45
			return true;
46
		}
47
	}
48
	return false;
49
}, removeFromSelected:function (o) {
50
	var idx = -1;
51
	for (var i = 0; i < this.selected.length; i++) {
52
		if (this.compare(this.selected[i], o)) {
53
			idx = i;
54
			break;
55
		}
56
	}
57
	if (idx >= 0) {
58
		this.selected.splice(idx, 1);
59
	}
60
}, getSelection:function () {
61
	return this.selected;
62
}, getValue:function () {
63
	var a = [];
64
	for (var i = 0; i < this.selected.length; i++) {
65
		if (this.selected[i][this.valueField]) {
66
			a.push(this.selected[i][this.valueField]);
67
		}
68
	}
69
	return a.join();
70
}, reset:function () {
71
	this.columns = [];
72
	this.data = [];
73
	this.resetSelections(this.domNode.getElementsByTagName("tbody")[0]);
74
}, resetSelections:function (body) {
75
	this.selected = [];
76
	var idx = 0;
77
	var rows = body.getElementsByTagName("tr");
78
	for (var i = 0; i < rows.length; i++) {
79
		if (rows[i].parentNode == body) {
80
			rows[i].removeAttribute("selected");
81
			if (this.enableAlternateRows && idx % 2 == 1) {
82
				rows[i].className = this.rowAlternateClass;
83
			} else {
84
				rows[i].className = "";
85
			}
86
			idx++;
87
		}
88
	}
89
}, getObjectFromRow:function (row) {
90
	var cells = row.getElementsByTagName("td");
91
	var o = {};
92
	for (var i = 0; i < this.columns.length; i++) {
93
		if (this.columns[i].sortType == "__markup__") {
94
			o[this.columns[i].getField()] = cells[i].innerHTML;
95
		} else {
96
			var text = dojo.html.renderedTextContent(cells[i]);
97
			var val = text;
98
			if (this.columns[i].getType() != String) {
99
				var val = new (this.columns[i].getType())(text);
100
			}
101
			o[this.columns[i].getField()] = val;
102
		}
103
	}
104
	if (dojo.html.hasAttribute(row, "value")) {
105
		o[this.valueField] = dojo.html.getAttribute(row, "value");
106
	}
107
	return o;
108
}, setSelectionByRow:function (row) {
109
	var o = this.getObjectFromRow(row);
110
	var b = false;
111
	for (var i = 0; i < this.selected.length; i++) {
112
		if (this.compare(this.selected[i], o)) {
113
			b = true;
114
			break;
115
		}
116
	}
117
	if (!b) {
118
		this.selected.push(o);
119
	}
120
}, parseColumns:function (node) {
121
	this.reset();
122
	var row = node.getElementsByTagName("tr")[0];
123
	var cells = row.getElementsByTagName("td");
124
	if (cells.length == 0) {
125
		cells = row.getElementsByTagName("th");
126
	}
127
	for (var i = 0; i < cells.length; i++) {
128
		var o = {field:null, format:null, noSort:false, sortType:"String", dataType:String, sortFunction:null, label:null, align:"left", valign:"middle", getField:function () {
129
			return this.field || this.label;
130
		}, getType:function () {
131
			return this.dataType;
132
		}};
133
		if (dojo.html.hasAttribute(cells[i], "align")) {
134
			o.align = dojo.html.getAttribute(cells[i], "align");
135
		}
136
		if (dojo.html.hasAttribute(cells[i], "valign")) {
137
			o.valign = dojo.html.getAttribute(cells[i], "valign");
138
		}
139
		if (dojo.html.hasAttribute(cells[i], "nosort")) {
140
			o.noSort = dojo.html.getAttribute(cells[i], "nosort") == "true";
141
		}
142
		if (dojo.html.hasAttribute(cells[i], "sortusing")) {
143
			var trans = dojo.html.getAttribute(cells[i], "sortusing");
144
			var f = this.getTypeFromString(trans);
145
			if (f != null && f != window && typeof (f) == "function") {
146
				o.sortFunction = f;
147
			}
148
		}
149
		if (dojo.html.hasAttribute(cells[i], "field")) {
150
			o.field = dojo.html.getAttribute(cells[i], "field");
151
		}
152
		if (dojo.html.hasAttribute(cells[i], "format")) {
153
			o.format = dojo.html.getAttribute(cells[i], "format");
154
		}
155
		if (dojo.html.hasAttribute(cells[i], "dataType")) {
156
			var sortType = dojo.html.getAttribute(cells[i], "dataType");
157
			if (sortType.toLowerCase() == "html" || sortType.toLowerCase() == "markup") {
158
				o.sortType = "__markup__";
159
				o.noSort = true;
160
			} else {
161
				var type = this.getTypeFromString(sortType);
162
				if (type) {
163
					o.sortType = sortType;
164
					o.dataType = type;
165
				}
166
			}
167
		}
168
		o.label = dojo.html.renderedTextContent(cells[i]);
169
		this.columns.push(o);
170
		if (dojo.html.hasAttribute(cells[i], "sort")) {
171
			this.sortIndex = i;
172
			var dir = dojo.html.getAttribute(cells[i], "sort");
173
			if (!isNaN(parseInt(dir))) {
174
				dir = parseInt(dir);
175
				this.sortDirection = (dir != 0) ? 1 : 0;
176
			} else {
177
				this.sortDirection = (dir.toLowerCase() == "desc") ? 1 : 0;
178
			}
179
		}
180
	}
181
}, parseData:function (data) {
182
	this.data = [];
183
	this.selected = [];
184
	for (var i = 0; i < data.length; i++) {
185
		var o = {};
186
		for (var j = 0; j < this.columns.length; j++) {
187
			var field = this.columns[j].getField();
188
			if (this.columns[j].sortType == "__markup__") {
189
				o[field] = String(data[i][field]);
190
			} else {
191
				var type = this.columns[j].getType();
192
				var val = data[i][field];
193
				var t = this.columns[j].sortType.toLowerCase();
194
				if (type == String) {
195
					o[field] = val;
196
				} else {
197
					if (val != null) {
198
						o[field] = new type(val);
199
					} else {
200
						o[field] = new type();
201
					}
202
				}
203
			}
204
		}
205
		if (data[i][this.valueField] && !o[this.valueField]) {
206
			o[this.valueField] = data[i][this.valueField];
207
		}
208
		this.data.push(o);
209
	}
210
}, parseDataFromTable:function (tbody) {
211
	this.data = [];
212
	this.selected = [];
213
	var rows = tbody.getElementsByTagName("tr");
214
	for (var i = 0; i < rows.length; i++) {
215
		if (dojo.html.getAttribute(rows[i], "ignoreIfParsed") == "true") {
216
			continue;
217
		}
218
		var o = {};
219
		var cells = rows[i].getElementsByTagName("td");
220
		for (var j = 0; j < this.columns.length; j++) {
221
			var field = this.columns[j].getField();
222
			if (this.columns[j].sortType == "__markup__") {
223
				o[field] = cells[j].innerHTML;
224
			} else {
225
				var type = this.columns[j].getType();
226
				var val = dojo.html.renderedTextContent(cells[j]);
227
				if (type == String) {
228
					o[field] = val;
229
				} else {
230
					if (val != null) {
231
						o[field] = new type(val);
232
					} else {
233
						o[field] = new type();
234
					}
235
				}
236
			}
237
		}
238
		if (dojo.html.hasAttribute(rows[i], "value") && !o[this.valueField]) {
239
			o[this.valueField] = dojo.html.getAttribute(rows[i], "value");
240
		}
241
		this.data.push(o);
242
		if (dojo.html.getAttribute(rows[i], "selected") == "true") {
243
			this.selected.push(o);
244
		}
245
	}
246
}, showSelections:function () {
247
	var body = this.domNode.getElementsByTagName("tbody")[0];
248
	var rows = body.getElementsByTagName("tr");
249
	var idx = 0;
250
	for (var i = 0; i < rows.length; i++) {
251
		if (rows[i].parentNode == body) {
252
			if (dojo.html.getAttribute(rows[i], "selected") == "true") {
253
				rows[i].className = this.rowSelectedClass;
254
			} else {
255
				if (this.enableAlternateRows && idx % 2 == 1) {
256
					rows[i].className = this.rowAlternateClass;
257
				} else {
258
					rows[i].className = "";
259
				}
260
			}
261
			idx++;
262
		}
263
	}
264
}, render:function (bDontPreserve) {
265
	var data = [];
266
	var body = this.domNode.getElementsByTagName("tbody")[0];
267
	if (!bDontPreserve) {
268
		this.parseDataFromTable(body);
269
	}
270
	for (var i = 0; i < this.data.length; i++) {
271
		data.push(this.data[i]);
272
	}
273
	var col = this.columns[this.sortIndex];
274
	if (!col.noSort) {
275
		var field = col.getField();
276
		if (col.sortFunction) {
277
			var sort = col.sortFunction;
278
		} else {
279
			var sort = function (a, b) {
280
				if (a[field] > b[field]) {
281
					return 1;
282
				}
283
				if (a[field] < b[field]) {
284
					return -1;
285
				}
286
				return 0;
287
			};
288
		}
289
		data.sort(sort);
290
		if (this.sortDirection != 0) {
291
			data.reverse();
292
		}
293
	}
294
	while (body.childNodes.length > 0) {
295
		body.removeChild(body.childNodes[0]);
296
	}
297
	for (var i = 0; i < data.length; i++) {
298
		var row = document.createElement("tr");
299
		dojo.html.disableSelection(row);
300
		if (data[i][this.valueField]) {
301
			row.setAttribute("value", data[i][this.valueField]);
302
		}
303
		if (this.isSelected(data[i])) {
304
			row.className = this.rowSelectedClass;
305
			row.setAttribute("selected", "true");
306
		} else {
307
			if (this.enableAlternateRows && i % 2 == 1) {
308
				row.className = this.rowAlternateClass;
309
			}
310
		}
311
		for (var j = 0; j < this.columns.length; j++) {
312
			var cell = document.createElement("td");
313
			cell.setAttribute("align", this.columns[j].align);
314
			cell.setAttribute("valign", this.columns[j].valign);
315
			dojo.html.disableSelection(cell);
316
			if (this.sortIndex == j) {
317
				cell.className = this.columnSelected;
318
			}
319
			if (this.columns[j].sortType == "__markup__") {
320
				cell.innerHTML = data[i][this.columns[j].getField()];
321
				for (var k = 0; k < cell.childNodes.length; k++) {
322
					var node = cell.childNodes[k];
323
					if (node && node.nodeType == dojo.html.ELEMENT_NODE) {
324
						dojo.html.disableSelection(node);
325
					}
326
				}
327
			} else {
328
				if (this.columns[j].getType() == Date) {
329
					var format = this.defaultDateFormat;
330
					if (this.columns[j].format) {
331
						format = this.columns[j].format;
332
					}
333
					cell.appendChild(document.createTextNode(dojo.date.strftime(data[i][this.columns[j].getField()], format)));
334
				} else {
335
					cell.appendChild(document.createTextNode(data[i][this.columns[j].getField()]));
336
				}
337
			}
338
			row.appendChild(cell);
339
		}
340
		body.appendChild(row);
341
		dojo.event.connect(row, "onclick", this, "onUISelect");
342
	}
343
	var minRows = parseInt(this.minRows);
344
	if (!isNaN(minRows) && minRows > 0 && data.length < minRows) {
345
		var mod = 0;
346
		if (data.length % 2 == 0) {
347
			mod = 1;
348
		}
349
		var nRows = minRows - data.length;
350
		for (var i = 0; i < nRows; i++) {
351
			var row = document.createElement("tr");
352
			row.setAttribute("ignoreIfParsed", "true");
353
			if (this.enableAlternateRows && i % 2 == mod) {
354
				row.className = this.rowAlternateClass;
355
			}
356
			for (var j = 0; j < this.columns.length; j++) {
357
				var cell = document.createElement("td");
358
				cell.appendChild(document.createTextNode("\xa0"));
359
				row.appendChild(cell);
360
			}
361
			body.appendChild(row);
362
		}
363
	}
364
}, onSelect:function (e) {
365
}, onUISelect:function (e) {
366
	var row = dojo.html.getParentByType(e.target, "tr");
367
	var body = dojo.html.getParentByType(row, "tbody");
368
	if (this.enableMultipleSelect) {
369
		if (e.metaKey || e.ctrlKey) {
370
			if (this.isSelected(this.getObjectFromRow(row))) {
371
				this.removeFromSelected(this.getObjectFromRow(row));
372
				row.removeAttribute("selected");
373
			} else {
374
				this.setSelectionByRow(row);
375
				row.setAttribute("selected", "true");
376
			}
377
		} else {
378
			if (e.shiftKey) {
379
				var startRow;
380
				var rows = body.getElementsByTagName("tr");
381
				for (var i = 0; i < rows.length; i++) {
382
					if (rows[i].parentNode == body) {
383
						if (rows[i] == row) {
384
							break;
385
						}
386
						if (dojo.html.getAttribute(rows[i], "selected") == "true") {
387
							startRow = rows[i];
388
						}
389
					}
390
				}
391
				if (!startRow) {
392
					startRow = row;
393
					for (; i < rows.length; i++) {
394
						if (dojo.html.getAttribute(rows[i], "selected") == "true") {
395
							row = rows[i];
396
							break;
397
						}
398
					}
399
				}
400
				this.resetSelections(body);
401
				if (startRow == row) {
402
					row.setAttribute("selected", "true");
403
					this.setSelectionByRow(row);
404
				} else {
405
					var doSelect = false;
406
					for (var i = 0; i < rows.length; i++) {
407
						if (rows[i].parentNode == body) {
408
							rows[i].removeAttribute("selected");
409
							if (rows[i] == startRow) {
410
								doSelect = true;
411
							}
412
							if (doSelect) {
413
								this.setSelectionByRow(rows[i]);
414
								rows[i].setAttribute("selected", "true");
415
							}
416
							if (rows[i] == row) {
417
								doSelect = false;
418
							}
419
						}
420
					}
421
				}
422
			} else {
423
				this.resetSelections(body);
424
				row.setAttribute("selected", "true");
425
				this.setSelectionByRow(row);
426
			}
427
		}
428
	} else {
429
		this.resetSelections(body);
430
		row.setAttribute("selected", "true");
431
		this.setSelectionByRow(row);
432
	}
433
	this.showSelections();
434
	this.onSelect(e);
435
	e.stopPropagation();
436
	e.preventDefault();
437
}, onHeaderClick:function (e) {
438
	var oldIndex = this.sortIndex;
439
	var oldDirection = this.sortDirection;
440
	var source = e.target;
441
	var row = dojo.html.getParentByType(source, "tr");
442
	var cellTag = "td";
443
	if (row.getElementsByTagName(cellTag).length == 0) {
444
		cellTag = "th";
445
	}
446
	var headers = row.getElementsByTagName(cellTag);
447
	var header = dojo.html.getParentByType(source, cellTag);
448
	for (var i = 0; i < headers.length; i++) {
449
		if (headers[i] == header) {
450
			if (i != oldIndex) {
451
				this.sortIndex = i;
452
				this.sortDirection = 0;
453
				headers[i].className = this.headerSortDownClass;
454
			} else {
455
				this.sortDirection = (oldDirection == 0) ? 1 : 0;
456
				if (this.sortDirection == 0) {
457
					headers[i].className = this.headerSortDownClass;
458
				} else {
459
					headers[i].className = this.headerSortUpClass;
460
				}
461
			}
462
		} else {
463
			headers[i].className = this.headerClass;
464
		}
465
	}
466
	this.render();
467
}, postCreate:function () {
468
	var thead = this.domNode.getElementsByTagName("thead")[0];
469
	if (this.headClass.length > 0) {
470
		thead.className = this.headClass;
471
	}
472
	dojo.html.disableSelection(this.domNode);
473
	this.parseColumns(thead);
474
	var header = "td";
475
	if (thead.getElementsByTagName(header).length == 0) {
476
		header = "th";
477
	}
478
	var headers = thead.getElementsByTagName(header);
479
	for (var i = 0; i < headers.length; i++) {
480
		if (!this.columns[i].noSort) {
481
			dojo.event.connect(headers[i], "onclick", this, "onHeaderClick");
482
		}
483
		if (this.sortIndex == i) {
484
			if (this.sortDirection == 0) {
485
				headers[i].className = this.headerSortDownClass;
486
			} else {
487
				headers[i].className = this.headerSortUpClass;
488
			}
489
		}
490
	}
491
	var tbody = this.domNode.getElementsByTagName("tbody")[0];
492
	if (this.tbodyClass.length > 0) {
493
		tbody.className = this.tbodyClass;
494
	}
495
	this.parseDataFromTable(tbody);
496
	this.render(true);
497
}});
498