Subversion Repositories Applications.papyrus

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2150 mathias 1
if(!dojo._hasResource["dijit.form.Button"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2
dojo._hasResource["dijit.form.Button"] = true;
3
dojo.provide("dijit.form.Button");
4
 
5
dojo.require("dijit.form._FormWidget");
6
dojo.require("dijit._Container");
7
 
8
dojo.declare("dijit.form.Button", dijit.form._FormWidget, {
9
/*
10
 * usage
11
 *	<button dojoType="button" onClick="...">Hello world</button>
12
 *
13
 *  var button1 = new dijit.form.Button({label: "hello world", onClick: foo});
14
 *	dojo.body().appendChild(button1.domNode);
15
 */
16
	// summary
17
	//	Basically the same thing as a normal HTML button, but with special styling.
18
 
19
	// label: String
20
	//	text to display in button
21
	label: "",
22
 
23
	// showLabel: Boolean
24
	//	whether or not to display the text label in button
25
	showLabel: true,
26
 
27
	// iconClass: String
28
	//	class to apply to div in button to make it display an icon
29
	iconClass: "",
30
 
31
	type: "button",
32
	baseClass: "dijitButton",
33
	templateString:"<div class=\"dijit dijitLeft dijitInline dijitButton\"\n\tdojoAttachEvent=\"onclick:_onButtonClick,onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse\"\n\t><div class='dijitRight'\n\t\t><button class=\"dijitStretch dijitButtonNode dijitButtonContents\" dojoAttachPoint=\"focusNode,titleNode\"\n\t\t\ttype=\"${type}\" waiRole=\"button\" waiState=\"labelledby-${id}_label\"\n\t\t\t><span class=\"dijitInline ${iconClass}\" dojoAttachPoint=\"iconNode\" \n \t\t\t\t><span class=\"dijitToggleButtonIconChar\">&#10003</span \n\t\t\t></span\n\t\t\t><span class=\"dijitButtonText\" id=\"${id}_label\" dojoAttachPoint=\"containerNode\">${label}</span\n\t\t></button\n\t></div\n></div>\n",
34
 
35
	// TODO: set button's title to this.containerNode.innerText
36
 
37
	_onClick: function(/*Event*/ e){
38
		// summary: internal function to handle click actions
39
		if(this.disabled){ return false; }
40
		this._clicked(); // widget click actions
41
		return this.onClick(e); // user click actions
42
	},
43
 
44
	_onButtonClick: function(/*Event*/ e){
45
		// summary: callback when the user mouse clicks the button portion
46
		dojo.stopEvent(e);
47
		var okToSubmit = this._onClick(e) !== false; // returning nothing is same as true
48
 
49
		// for some reason type=submit buttons don't automatically submit the form; do it manually
50
		if(this.type=="submit" && okToSubmit){
51
			for(var node=this.domNode; node; node=node.parentNode){
52
				var widget=dijit.byNode(node);
53
				if(widget && widget._onSubmit){
54
					widget._onSubmit(e);
55
					break;
56
				}
57
				if(node.tagName.toLowerCase() == "form"){
58
					if(!node.onsubmit || node.onsubmit()){ node.submit(); }
59
					break;
60
				}
61
			}
62
		}
63
	},
64
 
65
	postCreate: function(){
66
		// summary:
67
		//	get label and set as title on button icon if necessary
68
		if (this.showLabel == false){
69
			var labelText = "";
70
			this.label = this.containerNode.innerHTML;
71
			labelText = dojo.trim(this.containerNode.innerText || this.containerNode.textContent);
72
			// set title attrib on iconNode
73
			this.titleNode.title=labelText;
74
			dojo.addClass(this.containerNode,"dijitDisplayNone");
75
		}
76
		this.inherited(arguments);
77
	},
78
 
79
	onClick: function(/*Event*/ e){
80
		// summary: user callback for when button is clicked
81
		//      if type="submit", return value != false to perform submit
82
		return true;
83
	},
84
 
85
	_clicked: function(/*Event*/ e){
86
		// summary: internal replaceable function for when the button is clicked
87
	},
88
 
89
	setLabel: function(/*String*/ content){
90
		// summary: reset the label (text) of the button; takes an HTML string
91
		this.containerNode.innerHTML = this.label = content;
92
		if(dojo.isMozilla){ // Firefox has re-render issues with tables
93
			var oldDisplay = dojo.getComputedStyle(this.domNode).display;
94
			this.domNode.style.display="none";
95
			var _this = this;
96
			setTimeout(function(){_this.domNode.style.display=oldDisplay;},1);
97
		}
98
		if (this.showLabel == false){
99
				this.titleNode.title=dojo.trim(this.containerNode.innerText || this.containerNode.textContent);
100
		}
101
	}
102
});
103
 
104
/*
105
 * usage
106
 *	<button dojoType="DropDownButton" label="Hello world"><div dojotype=dijit.Menu>...</div></button>
107
 *
108
 *  var button1 = new dijit.form.DropDownButton({ label: "hi", dropDown: new dijit.Menu(...) });
109
 *	dojo.body().appendChild(button1);
110
 */
111
dojo.declare("dijit.form.DropDownButton", [dijit.form.Button, dijit._Container], {
112
	// summary
113
	//		push the button and a menu shows up
114
 
115
	baseClass : "dijitDropDownButton",
116
 
117
	templateString:"<div class=\"dijit dijitLeft dijitInline\"\n\tdojoAttachEvent=\"onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse,onclick:_onDropDownClick,onkeydown:_onDropDownKeydown,onblur:_onDropDownBlur,onkeypress:_onKey\"\n\t><div class='dijitRight'>\n\t<button class=\"dijitStretch dijitButtonNode dijitButtonContents\" type=\"${type}\"\n\t\tdojoAttachPoint=\"focusNode,titleNode\" waiRole=\"button\" waiState=\"haspopup-true,labelledby-${id}_label\"\n\t\t><div class=\"dijitInline ${iconClass}\" dojoAttachPoint=\"iconNode\"></div\n\t\t><span class=\"dijitButtonText\" \tdojoAttachPoint=\"containerNode,popupStateNode\"\n\t\tid=\"${id}_label\">${label}</span\n\t\t><span class='dijitA11yDownArrow'>&#9660;</span>\n\t</button>\n</div></div>\n",
118
 
119
	_fillContent: function(){
120
		// my inner HTML contains both the button contents and a drop down widget, like
121
		// <DropDownButton>  <span>push me</span>  <Menu> ... </Menu> </DropDownButton>
122
		// The first node is assumed to be the button content. The widget is the popup.
123
		if(this.srcNodeRef){ // programatically created buttons might not define srcNodeRef
124
			//FIXME: figure out how to filter out the widget and use all remaining nodes as button
125
			//	content, not just nodes[0]
126
			var nodes = dojo.query("*", this.srcNodeRef);
127
			dijit.form.DropDownButton.superclass._fillContent.call(this, nodes[0]);
128
 
129
			// save pointer to srcNode so we can grab the drop down widget after it's instantiated
130
			this.dropDownContainer = this.srcNodeRef;
131
		}
132
	},
133
 
134
	startup: function(){
135
		// the child widget from srcNodeRef is the dropdown widget.  Insert it in the page DOM,
136
		// make it invisible, and store a reference to pass to the popup code.
137
		if(!this.dropDown){
138
			var dropDownNode = dojo.query("[widgetId]", this.dropDownContainer)[0];
139
			this.dropDown = dijit.byNode(dropDownNode);
140
			delete this.dropDownContainer;
141
		}
142
		dojo.body().appendChild(this.dropDown.domNode);
143
		this.dropDown.domNode.style.display="none";
144
	},
145
 
146
	_onArrowClick: function(/*Event*/ e){
147
		// summary: callback when the user mouse clicks on menu popup node
148
		if(this.disabled){ return; }
149
		this._toggleDropDown();
150
	},
151
 
152
	_onDropDownClick: function(/*Event*/ e){
153
		// on Firefox 2 on the Mac it is possible to fire onclick
154
		// by pressing enter down on a second element and transferring
155
		// focus to the DropDownButton;
156
		// we want to prevent opening our menu in this situation
157
		// and only do so if we have seen a keydown on this button;
158
		// e.detail != 0 means that we were fired by mouse
159
		var isMacFFlessThan3 = dojo.isFF && dojo.isFF < 3
160
			&& navigator.appVersion.indexOf("Macintosh") != -1;
161
		if(!isMacFFlessThan3 || e.detail != 0 || this._seenKeydown){
162
			this._onArrowClick(e);
163
		}
164
		this._seenKeydown = false;
165
	},
166
 
167
	_onDropDownKeydown: function(/*Event*/ e){
168
		this._seenKeydown = true;
169
	},
170
 
171
	_onDropDownBlur: function(/*Event*/ e){
172
		this._seenKeydown = false;
173
	},
174
 
175
	_onKey: function(/*Event*/ e){
176
		// summary: callback when the user presses a key on menu popup node
177
		if(this.disabled){ return; }
178
		if(e.keyCode == dojo.keys.DOWN_ARROW){
179
			if(!this.dropDown || this.dropDown.domNode.style.display=="none"){
180
				dojo.stopEvent(e);
181
				return this._toggleDropDown();
182
			}
183
		}
184
	},
185
 
186
	_onBlur: function(){
187
		// summary: called magically when focus has shifted away from this widget and it's dropdown
188
		this._closeDropDown();
189
		// don't focus on button.  the user has explicitly focused on something else.
190
	},
191
 
192
	_toggleDropDown: function(){
193
		// summary: toggle the drop-down widget; if it is up, close it, if not, open it
194
		if(this.disabled){ return; }
195
		dijit.focus(this.popupStateNode);
196
		var dropDown = this.dropDown;
197
		if(!dropDown){ return false; }
198
		if(!dropDown.isShowingNow){
199
			// If there's an href, then load that first, so we don't get a flicker
200
			if(dropDown.href && !dropDown.isLoaded){
201
				var self = this;
202
				var handler = dojo.connect(dropDown, "onLoad", function(){
203
					dojo.disconnect(handler);
204
					self._openDropDown();
205
				});
206
				dropDown._loadCheck(true);
207
				return;
208
			}else{
209
				this._openDropDown();
210
			}
211
		}else{
212
			this._closeDropDown();
213
		}
214
	},
215
 
216
	_openDropDown: function(){
217
		var dropDown = this.dropDown;
218
		var oldWidth=dropDown.domNode.style.width;
219
		var self = this;
220
 
221
		dijit.popup.open({
222
			parent: this,
223
			popup: dropDown,
224
			around: this.domNode,
225
			orient: this.isLeftToRight() ? {'BL':'TL', 'BR':'TR', 'TL':'BL', 'TR':'BR'}
226
				: {'BR':'TR', 'BL':'TL', 'TR':'BR', 'TL':'BL'},
227
			onExecute: function(){
228
				self._closeDropDown(true);
229
			},
230
			onCancel: function(){
231
				self._closeDropDown(true);
232
			},
233
			onClose: function(){
234
				dropDown.domNode.style.width = oldWidth;
235
				self.popupStateNode.removeAttribute("popupActive");
236
				this._opened = false;
237
			}
238
		});
239
		if(this.domNode.offsetWidth > dropDown.domNode.offsetWidth){
240
			var adjustNode = null;
241
			if(!this.isLeftToRight()){
242
				adjustNode = dropDown.domNode.parentNode;
243
				var oldRight = adjustNode.offsetLeft + adjustNode.offsetWidth;
244
			}
245
			// make menu at least as wide as the button
246
			dojo.marginBox(dropDown.domNode, {w: this.domNode.offsetWidth});
247
			if(adjustNode){
248
				adjustNode.style.left = oldRight - this.domNode.offsetWidth + "px";
249
			}
250
		}
251
		this.popupStateNode.setAttribute("popupActive", "true");
252
		this._opened=true;
253
		if(dropDown.focus){
254
			dropDown.focus();
255
		}
256
		// TODO: set this.checked and call setStateClass(), to affect button look while drop down is shown
257
	},
258
 
259
	_closeDropDown: function(/*Boolean*/ focus){
260
		if(this._opened){
261
			dijit.popup.close(this.dropDown);
262
			if(focus){ this.focus(); }
263
			this._opened = false;
264
		}
265
	}
266
});
267
 
268
/*
269
 * usage
270
 *	<button dojoType="ComboButton" onClick="..."><span>Hello world</span><div dojoType=dijit.Menu>...</div></button>
271
 *
272
 *  var button1 = new dijit.form.ComboButton({label: "hello world", onClick: foo, dropDown: "myMenu"});
273
 *	dojo.body().appendChild(button1.domNode);
274
 */
275
dojo.declare("dijit.form.ComboButton", dijit.form.DropDownButton, {
276
	// summary
277
	//		left side is normal button, right side displays menu
278
	templateString:"<table class='dijit dijitReset dijitInline dijitLeft'\n\tcellspacing='0' cellpadding='0'\n\tdojoAttachEvent=\"onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse\">\n\t<tr>\n\t\t<td\tclass=\"dijitStretch dijitButtonContents dijitButtonNode\"\n\t\t\ttabIndex=\"${tabIndex}\"\n\t\t\tdojoAttachEvent=\"ondijitclick:_onButtonClick\"  dojoAttachPoint=\"titleNode\"\n\t\t\twaiRole=\"button\" waiState=\"labelledby-${id}_label\">\n\t\t\t<div class=\"dijitInline ${iconClass}\" dojoAttachPoint=\"iconNode\"></div>\n\t\t\t<span class=\"dijitButtonText\" id=\"${id}_label\" dojoAttachPoint=\"containerNode\">${label}</span>\n\t\t</td>\n\t\t<td class='dijitReset dijitRight dijitButtonNode dijitDownArrowButton'\n\t\t\tdojoAttachPoint=\"popupStateNode,focusNode\"\n\t\t\tdojoAttachEvent=\"ondijitclick:_onArrowClick, onkeypress:_onKey\"\n\t\t\tstateModifier=\"DownArrow\"\n\t\t\ttitle=\"${optionsTitle}\" name=\"${name}\"\n\t\t\twaiRole=\"button\" waiState=\"haspopup-true\"\n\t\t><div waiRole=\"presentation\">&#9660;</div>\n\t</td></tr>\n</table>\n",
279
 
280
	attributeMap: dojo.mixin(dojo.clone(dijit.form._FormWidget.prototype.attributeMap),
281
		{id:"", name:""}),
282
 
283
	// optionsTitle: String
284
	//  text that describes the options menu (accessibility)
285
	optionsTitle: "",
286
 
287
	baseClass: "dijitComboButton",
288
 
289
	_focusedNode: null,
290
 
291
	postCreate: function(){
292
		this.inherited(arguments);
293
		this._focalNodes = [this.titleNode, this.popupStateNode];
294
		dojo.forEach(this._focalNodes, dojo.hitch(this, function(node){
295
			if(dojo.isIE){
296
				this.connect(node, "onactivate", this._onNodeFocus);
297
			}else{
298
				this.connect(node, "onfocus", this._onNodeFocus);
299
			}
300
		}));
301
	},
302
 
303
	focusFocalNode: function(node){
304
		// summary: Focus the focal node node.
305
		this._focusedNode = node;
306
		dijit.focus(node);
307
	},
308
 
309
	hasNextFocalNode: function(){
310
		// summary: Returns true if this widget has no node currently
311
		//		focused or if there is a node following the focused one.
312
		//		False is returned if the last node has focus.
313
		return this._focusedNode !== this.getFocalNodes()[1];
314
	},
315
 
316
	focusNext: function(){
317
		// summary: Focus the focal node following the current node with focus
318
		//		or the first one if no node currently has focus.
319
		this._focusedNode = this.getFocalNodes()[this._focusedNode ? 1 : 0];
320
		dijit.focus(this._focusedNode);
321
	},
322
 
323
	hasPrevFocalNode: function(){
324
		// summary: Returns true if this widget has no node currently
325
		//		focused or if there is a node before the focused one.
326
		//		False is returned if the first node has focus.
327
		return this._focusedNode !== this.getFocalNodes()[0];
328
	},
329
 
330
	focusPrev: function(){
331
		// summary: Focus the focal node before the current node with focus
332
		//		or the last one if no node currently has focus.
333
		this._focusedNode = this.getFocalNodes()[this._focusedNode ? 0 : 1];
334
		dijit.focus(this._focusedNode);
335
	},
336
 
337
	getFocalNodes: function(){
338
		// summary: Returns an array of focal nodes for this widget.
339
		return this._focalNodes;
340
	},
341
 
342
	_onNodeFocus: function(evt){
343
		this._focusedNode = evt.currentTarget;
344
	},
345
 
346
	_onBlur: function(evt){
347
		this.inherited(arguments);
348
		this._focusedNode = null;
349
	}
350
});
351
 
352
dojo.declare("dijit.form.ToggleButton", dijit.form.Button, {
353
	// summary
354
	//	A button that can be in two states (checked or not).
355
	//	Can be base class for things like tabs or checkbox or radio buttons
356
 
357
	baseClass: "dijitToggleButton",
358
 
359
	// checked: Boolean
360
	//		Corresponds to the native HTML <input> element's attribute.
361
	//		In markup, specified as "checked='checked'" or just "checked".
362
	//		True if the button is depressed, or the checkbox is checked,
363
	//		or the radio button is selected, etc.
364
	checked: false,
365
 
366
	_clicked: function(/*Event*/ evt){
367
		this.setChecked(!this.checked);
368
	},
369
 
370
	setChecked: function(/*Boolean*/ checked){
371
		// summary
372
		//	Programatically deselect the button
373
		this.checked = checked;
374
		dijit.setWaiState(this.focusNode || this.domNode, "pressed", this.checked);
375
		this._setStateClass();
376
		this.onChange(checked);
377
	}
378
});
379
 
380
}