DropdownButton_wev8.js
5.8 KB
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
/*
Copyright (c) 2004-2005, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
/* TODO:
* - make the dropdown "smart" so it can't get cutoff on bottom of page, sides of page, etc.
*/
dojo.provide("dojo.widget.html.DropdownButton");
dojo.require("dojo.event.*");
dojo.require("dojo.widget.*");
dojo.require("dojo.widget.HtmlWidget");
dojo.require("dojo.uri.Uri");
dojo.require("dojo.dom");
dojo.require("dojo.style");
dojo.require("dojo.html");
dojo.widget.html.DropdownButton = function() {
// mix in the button properties
dojo.widget.DropdownButton.call(this);
dojo.widget.HtmlWidget.call(this);
}
dojo.inherits(dojo.widget.html.DropdownButton, dojo.widget.HtmlWidget);
dojo.lang.extend(dojo.widget.html.DropdownButton, {
// In IE, event handlers on objects inside buttons don't work correctly, so
// we just set onClick on the button itself.
templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlDropDownButtonTemplate.html"),
templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlButtonTemplate_wev8.css"),
// attach points
button: null,
table: null,
labelCell: null,
borderCell: null,
arrowCell: null,
arrow: null,
fillInTemplate: function(args, frag) {
// input data (containing the anchor for the button itself, plus the
// thing to display when you push the down arrow)
var input = frag["dojo:"+this.widgetType.toLowerCase()]["nodeRef"];
// Recursively expand widgets inside of the <dojo:dropdownButton>
var parser = new dojo.xml.Parse();
var frag = parser.parseElement(input, null, true);
var ary = dojo.widget.getParser().createComponents(frag);
this.a = dojo.dom.getFirstChildElement(input); // the button contents
this.menu = dojo.dom.getNextSiblingElement(this.a); // the menu under the button
this.disabled = dojo.html.hasClass(this.a, "disabled");
if( this.disabled ) {
dojo.html.addClass(this.button, "dojoDisabled");
this.domNode.setAttribute("disabled", "true");
}
dojo.html.disableSelection(this.a);
this.a.style["text-decoration"]="none";
this.labelCell.appendChild(this.a);
this.arrow.src =
dojo.uri.dojoUri("src/widget/templates/images/dropdownButtonsArrow" +
(this.disabled ? "-disabled" : "") + "_wev8.gif");
// Attach menu to body so that it appears above other buttons
this.menu.style.position="absolute";
this.menu.style.display="none";
this.menu.style["z-index"] = 99;
dojo.html.body().appendChild(this.menu);
},
postCreate: function() {
if ( dojo.render.html.ie ) {
// Compensate for IE's weird padding of button content, which seems to be relative
// to the length of the content
var contentWidth = dojo.style.getOuterWidth(this.table);
this.labelCell.style["left"] = "-" + (contentWidth / 10) + "px";
this.arrowCell.style["left"] = (contentWidth / 10) + "px";
}
// Make menu at least as wide as the button
var buttonWidth = dojo.style.getOuterWidth(this.button);
var menuWidth = dojo.style.getOuterWidth(this.menu);
if ( buttonWidth > menuWidth ) {
dojo.style.setOuterWidth(this.menu, buttonWidth);
}
},
// If someone clicks anywhere else on the screen (including another menu),
// then close this menu.
onCanvasMouseDown: function(e) {
if( !dojo.dom.isDescendantOf(e.target, this.button) &&
!dojo.dom.isDescendantOf(e.target, this.menu) ) {
this.hideMenu();
}
},
eventWasOverArrow: function(e) {
// want to use dojo.html.overElement() but also need to detect clicks
// on the area between the arrow and the edge of the button
var eventX = e.clientX;
var borderX = dojo.style.totalOffsetLeft(this.borderCell);
return (eventX > borderX );
},
onMouseOver: function(e) {
dojo.html.addClass(this.button, "dojoButtonHover");
dojo.html.removeClass(this.button, "dojoButtonNoHover");
},
onMouseOut: function(e) {
dojo.html.removeClass(this.button, "dojoButtonHover");
dojo.html.addClass(this.button, "dojoButtonNoHover");
},
onClick: function(e) {
if ( this.eventWasOverArrow(e) ) {
this._onClickArrow();
} else {
this._onClickButton();
}
},
// Action when the user presses the button
_onClickButton: function(e) {
if ( this.a ) {
if ( this.a.click ) {
this.a.click();
} else if ( this.a.href ) {
location.href = this.a.href;
}
}
},
// Action when user presses the arrow
_onClickArrow: function() {
if ( this.menu.style.display == "none" ) {
this.showMenu();
} else {
this.hideMenu();
}
},
showMenu: function() {
if ( this.disabled )
return;
// Position it accordingly, relative to screen root (since
// it's attached to document.body)
this.menu.style.left = dojo.style.totalOffsetLeft(this.button) + "px";
this.menu.style.top = dojo.style.totalOffsetTop(this.button) + dojo.style.getOuterHeight(this.button) + "px";
// Display the menu; do this funky code below to stop the menu from extending
// all the way to the right edge of the screen.
// TODO: retest simple display="" to confirm that it doesn't work.
try {
this.menu.style.display="table"; // mozilla
} catch(e) {
this.menu.style.display="block"; // IE
}
// If someone clicks somewhere else on the screen then close the menu
dojo.event.connect(document.documentElement, "onmousedown", this, "onCanvasMouseDown");
// When someone clicks the menu, after the menu handles the event,
// close the menu (be careful not to close the menu too early or else
// the menu will never receive the event.)
dojo.event.connect(this.menu, "onclick", this, "hideMenu");
},
hideMenu: function() {
this.menu.style.display = "none";
dojo.event.disconnect(document.documentElement, "onmousedown", this, "onCanvasMouseDown");
dojo.event.disconnect(this.menu, "onclick", this, "hideMenu");
}
});