Subversion Repositories Applications.papyrus

Rev

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