Subversion Repositories Applications.papyrus

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2150 mathias 1
if(!dojo._hasResource["dojox.widget.SortList"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2
dojo._hasResource["dojox.widget.SortList"] = true;
3
dojo.provide("dojox.widget.SortList");
4
dojo.experimental("dojox.widget.SortList"); // level: prototype, designed for dijit.chat.demo
5
 
6
dojo.require("dijit.layout._LayoutWidget");
7
dojo.require("dijit._Templated");
8
 
9
dojo.declare("dojox.widget.SortList",
10
	[dijit.layout._LayoutWidget, dijit._Templated],
11
	{
12
	// summary: a sortable <ul> with a fixed header for use in dijit.demos.chat
13
	//	for demonstration purposes only for now. feel free to make API suggestions
14
	//	or fixes.
15
	//
16
	// title: String
17
	//	the title in the header
18
	title: "",
19
 
20
	// heading: String
21
	//	in the event a parent container is expecting a title="" attribute, set it for the parent
22
	//	via title, and the title of this widget via heading="" ... assuming you want different
23
	//	titles for each. eg: TabContainer, AccordionContainer, etc.
24
	heading: "",
25
 
26
	// descending: Boolean
27
	//	toggle sort order based on this value.
28
	descending: true,
29
 
30
	// selected: Array
31
	//	a list of the selected <li> nodes at any given time.
32
	selected: null,
33
 
34
 
35
	// sortable: Boolean
36
	//	toggle to enable/disable sorting
37
	sortable: true,
38
 
39
	// FIXME: this is really simple store support
40
	store: "",
41
	key: "name",
42
 
43
	templateString:"<div class=\"sortList\" id=\"${id}\">\n\t\t<div class=\"sortListTitle\" dojoAttachPoint=\"titleNode\">\n\t\t<div class=\"sortListIcon\"></div>\n\t\t<span dojoAttachPoint=\"focusNode\">${title}</span>\n\t\t</div>\n\t\t<div class=\"sortListBodyWrapper\" dojoAttachEvent=\"onmouseover: _set, onmouseout: _unset, onclick:_handleClick\" dojoAttachPoint=\"bodyWrapper\">\n\t\t<ul dojoAttachPoint=\"containerNode\" class=\"sortListBody\"></ul>\n\t</div>\n</div>\n",
44
 
45
	_addItem: function(item){
46
		var node = document.createElement("li");
47
		var text = this.store.getValue(item,this.key);
48
		node.innerHTML = text;
49
		this.containerNode.appendChild(node);
50
	},
51
 
52
	postCreate: function(){
53
		if (this.store){
54
			// FIXME: is this right?
55
			this.store = eval(this.store);
56
			var props = {
57
				onItem: dojo.hitch(this,"_addItem"),
58
				onComplete: dojo.hitch(this,"onSort")
59
			};
60
			this.store.fetch(props);
61
		}else{ this.onSort(); }
62
		this.inherited("postCreate",arguments);
63
	},
64
 
65
	startup: function(){
66
		this.inherited("startup",arguments);
67
		if(this.heading){
68
			this.setTitle(this.heading); this.title=this.heading;
69
		}
70
		// we cheat, and give the browser just enough time so we know our height
71
		setTimeout(dojo.hitch(this,"resize"),5);
72
		if (this.sortable){ this.connect(this.titleNode,"onclick", "onSort"); }
73
	},
74
 
75
	resize: function(){
76
		// summary: do our additional calculations when resize() is called by or in a parent
77
		this.inherited("resize",arguments);
78
		// FIXME:
79
		// the 10 comes from the difference between the contentBox and calculated height
80
		// because of badding and border extents. this shouldn't be done this way, a theme change will
81
		// break it: but we also don't want to run getComputedStyle or dojo.coords() every time resize()
82
		// is fired.
83
		var offset = ((this._contentBox.h) - (dojo.style(this.titleNode,"height")))-10;
84
		this.bodyWrapper.style.height = Math.abs(offset) + "px";
85
	},
86
 
87
	onSort: function(/* Event */e){
88
		// summary: sort the data, and style the nodes.
89
 
90
		var arr = dojo.query("li",this.domNode);
91
		if (this.sortable){
92
			this.descending = !this.descending;
93
			dojo.addClass(this.titleNode,((this.descending)?"sortListDesc":"sortListAsc"));
94
			dojo.removeClass(this.titleNode,((this.descending)?"sortListAsc":"sortListDesc"));
95
			arr.sort(this._sorter);
96
			if(this.descending){ arr.reverse(); }
97
		}
98
		var i=0;
99
		dojo.forEach(arr,function(item){
100
			dojo[(((i++)%2)===0)?"addClass":"removeClass"](item,"sortListItemOdd");
101
			this.containerNode.appendChild(item);
102
		},this);
103
	},
104
 
105
	_set: function(/* Event */e){
106
		// summary: set hover state
107
		if (e.target != this.bodyWrapper){
108
			dojo.addClass(e.target,"sortListItemHover");
109
		}
110
	},
111
 
112
	_unset: function(/* Event */e){
113
		// summary: remove hover state (FIXME: combine with _set?)
114
		dojo.removeClass(e.target,"sortListItemHover");
115
	},
116
 
117
	_handleClick: function(/* Event */e){
118
		// summary: click listener for data portion of widget. toggle selected state
119
		//	of node, and update this.selected array accordingly
120
		dojo.toggleClass(e.target,"sortListItemSelected");
121
		e.target.focus();
122
		this._updateValues(e.target.innerHTML);
123
	},
124
 
125
	_updateValues: function(){
126
		this._selected = dojo.query("li.sortListItemSelected",this.containerNode);
127
		this.selected = [];
128
		dojo.forEach(this._selected,function(node){
129
			this.selected.push(node.innerHTML);
130
		},this);
131
		this.onChanged(arguments);
132
	},
133
 
134
	_sorter: function(a,b){
135
		// summary: a basic sort function, use query sort, or keep this?
136
		var aStr = a.innerHTML;
137
		var bStr = b.innerHTML;
138
		if(aStr>bStr){ return 1; }
139
		if(aStr<bStr){ return -1; }
140
		return 0;
141
	},
142
 
143
	setTitle: function(/* String */title){
144
		// summary: Sets the widget title to a String
145
		this.focusNode.innerHTML = title;
146
	},
147
 
148
	onChanged: function(){
149
		// summary: stub function, passes the last changed item, and is fired after current state
150
	}
151
});
152
 
153
}