kenny_dialoggins 1.0.0 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.specification +4 -4
- data/README.rdoc +67 -11
- data/VERSION +1 -1
- data/generators/kenny_dialoggins/templates/kenny_dialoggins.css +28 -9
- data/generators/kenny_dialoggins/templates/kenny_dialoggins.js +124 -76
- data/kenny_dialoggins.gemspec +2 -2
- data/lib/generators/kenny_dialoggins/templates/kenny_dialoggins.css +28 -9
- data/lib/generators/kenny_dialoggins/templates/kenny_dialoggins.js +124 -76
- data/lib/kenny_dialoggins/helpers.rb +65 -12
- metadata +4 -4
data/.specification
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kenny_dialoggins
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
|
+
- 1
|
7
8
|
- 0
|
8
9
|
- 2
|
9
|
-
|
10
|
-
version: 0.2.3
|
10
|
+
version: 1.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Coroutine
|
@@ -17,7 +17,7 @@ autorequire:
|
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
19
|
|
20
|
-
date: 2010-
|
20
|
+
date: 2010-10-19 00:00:00 -05:00
|
21
21
|
default_executable:
|
22
22
|
dependencies:
|
23
23
|
- !ruby/object:Gem::Dependency
|
data/README.rdoc
CHANGED
@@ -32,16 +32,27 @@ What's that, you want more details? You got it, buddy.
|
|
32
32
|
<tt>render_dialog</tt> always needs a unique id for its first argument. After that, it will
|
33
33
|
take the same options as <tt>ActionController::Base#render</tt>. It'll also take a few more, namely:
|
34
34
|
|
35
|
+
* <tt>:class</tt> - a css class name that will be appended to the outermost div to facilitate multiple styles
|
35
36
|
* <tt>:before_show</tt> - a Javascript function that will be invoked before the dialog is shown
|
36
37
|
* <tt>:after_show</tt> - a Javascript function that will be invoked after the dialog has become visible
|
37
38
|
* <tt>:before_hide</tt> - a Javascript function that will be invoked before the dialog is hidden
|
38
39
|
* <tt>:after_hide</tt> - a Javascript function that will be invoked after the dialog has been hidden
|
40
|
+
* <tt>&block</tt> - HTML markup that will be automatically converted to render's inline option
|
39
41
|
|
40
42
|
Here's an example using the <tt>before_show</tt> option:
|
41
43
|
|
42
44
|
# Create the dialog with a callback
|
43
45
|
<%= render_dialog :footloose_dialog, :partial => "footloose", :before_show => "function() { alert('Everybody get footloose!'); }" %>
|
44
|
-
|
46
|
+
|
47
|
+
To invoke the dialog, use unobtrusive javascript to trap a click event and show the dialog.
|
48
|
+
|
49
|
+
// invoke the dialog
|
50
|
+
$("footloose_dialog_link").observe("click", function(evt) {
|
51
|
+
KennyDialoggins.Dialog.show("footloose_dialog");
|
52
|
+
});
|
53
|
+
|
54
|
+
Or, if you're using javascript helper functions, you can use the show/hide helpers to accomplish the same thing.
|
55
|
+
|
45
56
|
# Invoke the dialog
|
46
57
|
<%= link_to_function "Dance party!", show_dialog(:footloose_dialog) %>
|
47
58
|
|
@@ -56,6 +67,35 @@ Kenny Dialoggins
|
|
56
67
|
|
57
68
|
|
58
69
|
|
70
|
+
== Multiple Dialog Styles
|
71
|
+
|
72
|
+
If you need to style more than one kind of dialog, just use the <tt>:class</tt> option to append a css class name
|
73
|
+
on the outermost div. That'll give you a logical anchor around which you can restyle all the interior classes.
|
74
|
+
|
75
|
+
Please note that the blocking iframe is automatically given an additional class name equal to the outermost div's class
|
76
|
+
name plus the string "_frame".
|
77
|
+
|
78
|
+
By default, the top-level class assignments are "kenny_dialoggins_dialog" and "kenny_dialoggins_dialog_frame".
|
79
|
+
|
80
|
+
If you set the <tt>:class</tt> option to <tt>:error_dialog</tt>, the top-level class assignments will be
|
81
|
+
"kenny_dialoggins_dialog error_dialog" and "kenny_dialoggins_dialog_frame error_dialog_frame".
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
== IE6 Support
|
86
|
+
|
87
|
+
I'm not what you'd call a huge fan of IE6, so I don't provide a blocking
|
88
|
+
iframe for my dialogs by default. But I can. You just need to ask nicely.
|
89
|
+
|
90
|
+
At the top of the generated javascript file, just change the obviously-named property
|
91
|
+
hanging right off of the Kenny D namespace. Like this.
|
92
|
+
|
93
|
+
KennyDialoggins.SUPPORT_IE6_BULLSHIT = true;
|
94
|
+
|
95
|
+
That's it. I do the rest.
|
96
|
+
|
97
|
+
|
98
|
+
|
59
99
|
== Helpful Links
|
60
100
|
|
61
101
|
* <b>Repository:</b> http://github.com/coroutine/kenny_dialoggins
|
@@ -76,7 +116,22 @@ in the mix.
|
|
76
116
|
|
77
117
|
|
78
118
|
|
79
|
-
== Installation & Generators
|
119
|
+
== Installation & Generators (Rails 3)
|
120
|
+
|
121
|
+
Install me from RubyGems.org by adding a gem dependency to your Gemfile. Bundler does
|
122
|
+
the rest.
|
123
|
+
|
124
|
+
gem "kenny_dialoggins"
|
125
|
+
|
126
|
+
$ bundle install
|
127
|
+
|
128
|
+
Then generate the required javascript file and the starter stylesheet.
|
129
|
+
|
130
|
+
$ rails g kenny_dialoggins
|
131
|
+
|
132
|
+
|
133
|
+
|
134
|
+
== Installation & Generators (Rails 2)
|
80
135
|
|
81
136
|
Install me from RubyGems.org and add a gem dependency in the appropriate file.
|
82
137
|
|
@@ -86,23 +141,24 @@ Or install me as a plugin.
|
|
86
141
|
|
87
142
|
$ script/plugin install git://github.com/coroutine/kenny_dialoggins.git
|
88
143
|
|
89
|
-
Either way, then generate the
|
144
|
+
Either way, then generate the required javascript file and the starter stylesheet.
|
90
145
|
|
91
146
|
$ script/generate kenny_dialoggins
|
92
147
|
|
93
148
|
|
94
149
|
|
95
|
-
==
|
96
|
-
|
97
|
-
I'm not what you'd call a huge fan of IE6, so I don't provide a blocking
|
98
|
-
iframe for my dialogs by default. But I can. You just need to ask nicely.
|
150
|
+
== Gemroll
|
99
151
|
|
100
|
-
|
101
|
-
|
152
|
+
If you think I'm awesome, you should check out my soulmate
|
153
|
+
{Michael Hintbuble}[http://github.com/coroutine/michael_hintbuble].
|
102
154
|
|
103
|
-
|
155
|
+
Other gems by Coroutine include:
|
104
156
|
|
105
|
-
|
157
|
+
* {acts_as_current}[http://github.com/coroutine/acts_as_current]
|
158
|
+
* {acts_as_label}[http://github.com/coroutine/acts_as_label]
|
159
|
+
* {acts_as_list_with_sti_support}[http://github.com/coroutine/acts_as_list_with_sti_support]
|
160
|
+
* {delayed_form_observer}[http://github.com/coroutine/delayed_form_observer]
|
161
|
+
* {tiny_navigation}[http://github.com/coroutine/tiny_navigation]
|
106
162
|
|
107
163
|
|
108
164
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.3
|
@@ -1,20 +1,39 @@
|
|
1
|
-
|
2
|
-
* These styles are provided as examples. Feel free to change them however you like.
|
3
|
-
*/
|
1
|
+
/* core styles */
|
4
2
|
.kenny_dialoggins_dialog {
|
5
3
|
position: absolute;
|
6
4
|
padding: 1em;
|
7
|
-
|
8
|
-
background: #FFF;
|
5
|
+
width: 500px;
|
9
6
|
z-index: 2;
|
7
|
+
box-shadow: 4px 4px 16px rgba(0,0,0,0.5);
|
10
8
|
-moz-box-shadow: 4px 4px 16px rgba(0,0,0,0.5);
|
11
9
|
-webkit-box-shadow: 4px 4px 16px rgba(0,0,0,0.5);
|
12
|
-
|
10
|
+
opacity: 1;
|
11
|
+
filter: alpha(opacity=100);
|
12
|
+
background: #fff;
|
13
|
+
border: 1px solid #bbb;
|
13
14
|
}
|
14
|
-
|
15
15
|
.kenny_dialoggins_dialog_frame {
|
16
16
|
position: absolute;
|
17
|
-
border: none;
|
18
17
|
z-index: 1;
|
19
|
-
|
18
|
+
opacity: 0;
|
19
|
+
filter: alpha(opacity=0);
|
20
|
+
border: none;
|
21
|
+
}
|
22
|
+
|
23
|
+
|
24
|
+
/* error dialog */
|
25
|
+
.error_dialog {
|
26
|
+
width: 300px;
|
27
|
+
background: #d00;
|
28
|
+
color: #fff;
|
29
|
+
border: 1px solid #d00;
|
30
|
+
}
|
31
|
+
|
32
|
+
|
33
|
+
/* help dialog */
|
34
|
+
.help_dialog {
|
35
|
+
width: 600px;
|
36
|
+
background: #ccc;
|
37
|
+
color: #333;
|
38
|
+
border: 1px solid #666;
|
20
39
|
}
|
@@ -8,7 +8,7 @@
|
|
8
8
|
* Brought to you by the good folks at Coroutine. Hire us!
|
9
9
|
* http://coroutine.com
|
10
10
|
*/
|
11
|
-
var KennyDialoggins = {}
|
11
|
+
var KennyDialoggins = {};
|
12
12
|
|
13
13
|
|
14
14
|
/**
|
@@ -31,8 +31,9 @@ KennyDialoggins.Dialog = function(content, options) {
|
|
31
31
|
this._element = null;
|
32
32
|
this._frame = null;
|
33
33
|
this._hideListener = this._generateHideListener();
|
34
|
-
this.
|
34
|
+
this._isShowing = false;
|
35
35
|
|
36
|
+
this._class = options["class"] || ""
|
36
37
|
this._beforeShow = options["beforeShow"] || Prototype.emptyFunction
|
37
38
|
this._afterShow = options["afterShow"] || Prototype.emptyFunction
|
38
39
|
this._beforeHide = options["beforeHide"] || Prototype.emptyFunction
|
@@ -40,13 +41,11 @@ KennyDialoggins.Dialog = function(content, options) {
|
|
40
41
|
|
41
42
|
this._makeDialog();
|
42
43
|
this.setContent(content);
|
43
|
-
document.body.appendChild(this._element);
|
44
44
|
|
45
45
|
if (KennyDialoggins.SUPPORT_IE6_BULLSHIT) {
|
46
46
|
this._makeFrame();
|
47
|
-
document.body.appendChild(this._frame);
|
48
47
|
}
|
49
|
-
}
|
48
|
+
};
|
50
49
|
|
51
50
|
|
52
51
|
|
@@ -72,21 +71,18 @@ KennyDialoggins.Dialog._POSITION_FN_MAP = $H({
|
|
72
71
|
|
73
72
|
|
74
73
|
/**
|
75
|
-
* This method
|
74
|
+
* This method destroys the dialog with the corresponding id.
|
76
75
|
*
|
77
76
|
* @param {String} id The id value of the dialog element (also the key
|
78
77
|
* in the instances hash.)
|
79
|
-
*
|
80
|
-
* @return {Object} an instance of KennyDialoggins.Dialog
|
81
|
-
*
|
82
78
|
*/
|
83
|
-
KennyDialoggins.Dialog.
|
79
|
+
KennyDialoggins.Dialog.destroy = function(id) {
|
84
80
|
var dialog = this.instances[id];
|
85
|
-
if(dialog) {
|
86
|
-
dialog.
|
81
|
+
if (dialog) {
|
82
|
+
dialog.finalize();
|
87
83
|
}
|
88
|
-
|
89
|
-
}
|
84
|
+
this.instances[id] = null;
|
85
|
+
};
|
90
86
|
|
91
87
|
|
92
88
|
/**
|
@@ -100,11 +96,11 @@ KennyDialoggins.Dialog.show = function(id) {
|
|
100
96
|
*/
|
101
97
|
KennyDialoggins.Dialog.hide = function(id) {
|
102
98
|
var dialog = this.instances[id];
|
103
|
-
if(dialog) {
|
99
|
+
if (dialog) {
|
104
100
|
dialog.hide();
|
105
101
|
}
|
106
102
|
return dialog;
|
107
|
-
}
|
103
|
+
};
|
108
104
|
|
109
105
|
|
110
106
|
/**
|
@@ -118,13 +114,31 @@ KennyDialoggins.Dialog.hide = function(id) {
|
|
118
114
|
* id is showing.
|
119
115
|
*
|
120
116
|
*/
|
121
|
-
KennyDialoggins.Dialog.
|
117
|
+
KennyDialoggins.Dialog.isShowing = function(id) {
|
122
118
|
var dialog = this.instances[id];
|
123
119
|
if (!dialog) {
|
124
120
|
throw "No dialog cound be found for the supplied id.";
|
125
121
|
}
|
126
|
-
return dialog.
|
127
|
-
}
|
122
|
+
return dialog.isShowing();
|
123
|
+
};
|
124
|
+
|
125
|
+
|
126
|
+
/**
|
127
|
+
* This method shows the dialog with the corresponding id.
|
128
|
+
*
|
129
|
+
* @param {String} id The id value of the dialog element (also the key
|
130
|
+
* in the instances hash.)
|
131
|
+
*
|
132
|
+
* @return {Object} an instance of KennyDialoggins.Dialog
|
133
|
+
*
|
134
|
+
*/
|
135
|
+
KennyDialoggins.Dialog.show = function(id) {
|
136
|
+
var dialog = this.instances[id];
|
137
|
+
if (dialog) {
|
138
|
+
dialog.show();
|
139
|
+
}
|
140
|
+
return dialog;
|
141
|
+
};
|
128
142
|
|
129
143
|
|
130
144
|
|
@@ -133,6 +147,33 @@ KennyDialoggins.Dialog.is_showing = function(id) {
|
|
133
147
|
// ----------------------------------------------------------------------------
|
134
148
|
|
135
149
|
Object.extend(KennyDialoggins.Dialog.prototype, {
|
150
|
+
|
151
|
+
|
152
|
+
/**
|
153
|
+
* This function creates the function that handles click events when the dialog is
|
154
|
+
* shown. The handler ignores clicks targeted from within the dialog; any click
|
155
|
+
* targeted outside the dialog causes the dialog to hide itself and cancel the
|
156
|
+
* observer.
|
157
|
+
*/
|
158
|
+
_generateHideListener: function() {
|
159
|
+
return function(evt) {
|
160
|
+
var origin = evt.findElement(".kenny_dialoggins_dialog");
|
161
|
+
if (this._element !== origin) {
|
162
|
+
this.hide();
|
163
|
+
}
|
164
|
+
}.bind(this);
|
165
|
+
},
|
166
|
+
|
167
|
+
|
168
|
+
/**
|
169
|
+
* This function indicates whether or not the dialog is currently
|
170
|
+
* being shown.
|
171
|
+
*
|
172
|
+
* @return {Boolean} Whether or not the dialog is being shown.
|
173
|
+
*/
|
174
|
+
_isShowing: function() {
|
175
|
+
return this._isShowing;
|
176
|
+
},
|
136
177
|
|
137
178
|
/**
|
138
179
|
* This function constructs the dialog element and hides it by default.
|
@@ -146,8 +187,12 @@ Object.extend(KennyDialoggins.Dialog.prototype, {
|
|
146
187
|
_makeDialog: function() {
|
147
188
|
if (!this._element) {
|
148
189
|
this._element = new Element("DIV");
|
149
|
-
this._element.
|
190
|
+
this._element.addClassName("kenny_dialoggins_dialog");
|
191
|
+
if (this._class) {
|
192
|
+
this._element.addClassName(this._class);
|
193
|
+
}
|
150
194
|
this._element.hide();
|
195
|
+
document.body.appendChild(this._element);
|
151
196
|
}
|
152
197
|
},
|
153
198
|
|
@@ -164,26 +209,56 @@ Object.extend(KennyDialoggins.Dialog.prototype, {
|
|
164
209
|
_makeFrame: function() {
|
165
210
|
if (!this._frame) {
|
166
211
|
this._frame = new Element("IFRAME");
|
167
|
-
this._frame.
|
212
|
+
this._frame.addClassName("kenny_dialoggins_dialog_frame");
|
213
|
+
if (this._class) {
|
214
|
+
this._element.addClassName(this._class);
|
215
|
+
}
|
168
216
|
this._frame.setAttribute("src", "about:blank");
|
169
217
|
this._frame.hide();
|
218
|
+
document.body.appendChild(this._frame);
|
170
219
|
}
|
171
220
|
},
|
172
|
-
|
173
|
-
|
221
|
+
|
222
|
+
|
174
223
|
/**
|
175
|
-
* This function
|
176
|
-
*
|
177
|
-
* targeted outside the dialog causes the dialog to hide itself and cancel the
|
178
|
-
* observer.
|
224
|
+
* This function allows the dialog object to be destroyed without
|
225
|
+
* creating memory leaks.
|
179
226
|
*/
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
227
|
+
finalize: function() {
|
228
|
+
this.hide();
|
229
|
+
|
230
|
+
this._element.remove();
|
231
|
+
this._element = null;
|
232
|
+
|
233
|
+
if (this._frame) {
|
234
|
+
this._frame.remove();
|
235
|
+
this._frame = null;
|
236
|
+
}
|
237
|
+
|
238
|
+
this._hideListener = null;
|
239
|
+
},
|
240
|
+
|
241
|
+
|
242
|
+
/**
|
243
|
+
* This function hides the dialog. It uses a scriptaculous effect to fade out
|
244
|
+
* and disconnects the click observer to prevent memory leaks.
|
245
|
+
*/
|
246
|
+
hide: function() {
|
247
|
+
new Effect.Fade(this._element, {
|
248
|
+
duration: 0.2,
|
249
|
+
beforeStart: this._beforeHide,
|
250
|
+
afterFinish: function() {
|
251
|
+
this._isShowing = false;
|
252
|
+
this._afterHide();
|
253
|
+
document.stopObserving("click", this._hideListener);
|
254
|
+
}.bind(this)
|
255
|
+
});
|
256
|
+
|
257
|
+
if (this._frame) {
|
258
|
+
new Effect.Fade(this._frame, {
|
259
|
+
duration: 0.2
|
260
|
+
});
|
261
|
+
}
|
187
262
|
},
|
188
263
|
|
189
264
|
|
@@ -197,6 +272,16 @@ Object.extend(KennyDialoggins.Dialog.prototype, {
|
|
197
272
|
},
|
198
273
|
|
199
274
|
|
275
|
+
/**
|
276
|
+
* This function sets the position of the dialog element.
|
277
|
+
*/
|
278
|
+
setPosition: function() {
|
279
|
+
var layout = new Element.Layout(this._element);
|
280
|
+
this._element.style.top = Math.ceil(((document.viewport.getHeight()/2) + (document.viewport.getScrollOffsets().top) - (layout.get("padding-box-height")/2)) * 2/3) + "px";
|
281
|
+
this._element.style.left = Math.ceil((document.viewport.getWidth()/2) + (document.viewport.getScrollOffsets().left) - (layout.get("padding-box-width")/2)) + "px";
|
282
|
+
},
|
283
|
+
|
284
|
+
|
200
285
|
/**
|
201
286
|
* This function displays the dialog. It uses a scriptaculous effect to fade in,
|
202
287
|
* centers the dialog in the viewport (and adjusts the blocking iframe, if in use),
|
@@ -204,17 +289,14 @@ Object.extend(KennyDialoggins.Dialog.prototype, {
|
|
204
289
|
* the dialog.
|
205
290
|
*/
|
206
291
|
show: function() {
|
207
|
-
|
208
|
-
var method = pair.last();
|
209
|
-
this._element.style[pair.first()] =
|
210
|
-
(document.viewport[method]() / 2 + document.viewport.getScrollOffsets()[pair.first()] - this._element[method]() / 2) + "px";
|
211
|
-
}.bind(this));
|
292
|
+
this.setPosition();
|
212
293
|
|
213
294
|
if (this._frame) {
|
295
|
+
var layout = new Element.Layout(this._element);
|
214
296
|
this._frame.style.top = this._element.style.top;
|
215
297
|
this._frame.style.left = this._element.style.left;
|
216
|
-
this._frame.style.width =
|
217
|
-
this._frame.style.height =
|
298
|
+
this._frame.style.width = layout.get("padding-box-width") + "px";
|
299
|
+
this._frame.style.height = layout.get("padding-box-height") + "px";
|
218
300
|
|
219
301
|
new Effect.Appear(this._frame, {
|
220
302
|
duration: 0.2
|
@@ -225,44 +307,10 @@ Object.extend(KennyDialoggins.Dialog.prototype, {
|
|
225
307
|
duration: 0.2,
|
226
308
|
beforeStart: this._beforeShow,
|
227
309
|
afterFinish: function() {
|
228
|
-
this.
|
310
|
+
this._isShowing = true;
|
229
311
|
this._afterShow();
|
230
312
|
document.observe("click", this._hideListener);
|
231
313
|
}.bind(this)
|
232
314
|
});
|
233
|
-
},
|
234
|
-
|
235
|
-
|
236
|
-
/**
|
237
|
-
* This function hides the dialog. It uses a scriptaculous effect to fade out
|
238
|
-
* and disconnects the click observer to prevent memory leaks.
|
239
|
-
*/
|
240
|
-
hide: function() {
|
241
|
-
new Effect.Fade(this._element, {
|
242
|
-
duration: 0.2,
|
243
|
-
beforeStart: this._beforeHide,
|
244
|
-
afterFinish: function() {
|
245
|
-
this._is_showing = false;
|
246
|
-
this._afterHide();
|
247
|
-
document.stopObserving("click", this._hideListener);
|
248
|
-
}.bind(this)
|
249
|
-
});
|
250
|
-
|
251
|
-
if (this._frame) {
|
252
|
-
new Effect.Fade(this._frame, {
|
253
|
-
duration: 0.2
|
254
|
-
});
|
255
|
-
}
|
256
|
-
},
|
257
|
-
|
258
|
-
|
259
|
-
/**
|
260
|
-
* This function indicates whether or not the dialog is currently
|
261
|
-
* being shown.
|
262
|
-
*
|
263
|
-
* @return {Boolean} Whether or not the dialog is being shown.
|
264
|
-
*/
|
265
|
-
is_showing: function() {
|
266
|
-
return this._is_showing;
|
267
315
|
}
|
268
316
|
});
|
data/kenny_dialoggins.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{kenny_dialoggins}
|
8
|
-
s.version = "1.0.
|
8
|
+
s.version = "1.0.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Coroutine", "Tim Lowrimore", "John Dugan"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-10-19}
|
13
13
|
s.description = %q{Kenny Dialoggins allows you to include scriptaculous dialogs in Rails applications using the same syntax employed for rendering partials.}
|
14
14
|
s.email = %q{gems@coroutine.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -1,20 +1,39 @@
|
|
1
|
-
|
2
|
-
* These styles are provided as examples. Feel free to change them however you like.
|
3
|
-
*/
|
1
|
+
/* core styles */
|
4
2
|
.kenny_dialoggins_dialog {
|
5
3
|
position: absolute;
|
6
4
|
padding: 1em;
|
7
|
-
|
8
|
-
background: #FFF;
|
5
|
+
width: 500px;
|
9
6
|
z-index: 2;
|
7
|
+
box-shadow: 4px 4px 16px rgba(0,0,0,0.5);
|
10
8
|
-moz-box-shadow: 4px 4px 16px rgba(0,0,0,0.5);
|
11
9
|
-webkit-box-shadow: 4px 4px 16px rgba(0,0,0,0.5);
|
12
|
-
|
10
|
+
opacity: 1;
|
11
|
+
filter: alpha(opacity=100);
|
12
|
+
background: #fff;
|
13
|
+
border: 1px solid #bbb;
|
13
14
|
}
|
14
|
-
|
15
15
|
.kenny_dialoggins_dialog_frame {
|
16
16
|
position: absolute;
|
17
|
-
border: none;
|
18
17
|
z-index: 1;
|
19
|
-
|
18
|
+
opacity: 0;
|
19
|
+
filter: alpha(opacity=0);
|
20
|
+
border: none;
|
21
|
+
}
|
22
|
+
|
23
|
+
|
24
|
+
/* error dialog */
|
25
|
+
.error_dialog {
|
26
|
+
width: 300px;
|
27
|
+
background: #d00;
|
28
|
+
color: #fff;
|
29
|
+
border: 1px solid #d00;
|
30
|
+
}
|
31
|
+
|
32
|
+
|
33
|
+
/* help dialog */
|
34
|
+
.help_dialog {
|
35
|
+
width: 600px;
|
36
|
+
background: #ccc;
|
37
|
+
color: #333;
|
38
|
+
border: 1px solid #666;
|
20
39
|
}
|
@@ -8,7 +8,7 @@
|
|
8
8
|
* Brought to you by the good folks at Coroutine. Hire us!
|
9
9
|
* http://coroutine.com
|
10
10
|
*/
|
11
|
-
var KennyDialoggins = {}
|
11
|
+
var KennyDialoggins = {};
|
12
12
|
|
13
13
|
|
14
14
|
/**
|
@@ -31,8 +31,9 @@ KennyDialoggins.Dialog = function(content, options) {
|
|
31
31
|
this._element = null;
|
32
32
|
this._frame = null;
|
33
33
|
this._hideListener = this._generateHideListener();
|
34
|
-
this.
|
34
|
+
this._isShowing = false;
|
35
35
|
|
36
|
+
this._class = options["class"] || ""
|
36
37
|
this._beforeShow = options["beforeShow"] || Prototype.emptyFunction
|
37
38
|
this._afterShow = options["afterShow"] || Prototype.emptyFunction
|
38
39
|
this._beforeHide = options["beforeHide"] || Prototype.emptyFunction
|
@@ -40,13 +41,11 @@ KennyDialoggins.Dialog = function(content, options) {
|
|
40
41
|
|
41
42
|
this._makeDialog();
|
42
43
|
this.setContent(content);
|
43
|
-
document.body.appendChild(this._element);
|
44
44
|
|
45
45
|
if (KennyDialoggins.SUPPORT_IE6_BULLSHIT) {
|
46
46
|
this._makeFrame();
|
47
|
-
document.body.appendChild(this._frame);
|
48
47
|
}
|
49
|
-
}
|
48
|
+
};
|
50
49
|
|
51
50
|
|
52
51
|
|
@@ -72,21 +71,18 @@ KennyDialoggins.Dialog._POSITION_FN_MAP = $H({
|
|
72
71
|
|
73
72
|
|
74
73
|
/**
|
75
|
-
* This method
|
74
|
+
* This method destroys the dialog with the corresponding id.
|
76
75
|
*
|
77
76
|
* @param {String} id The id value of the dialog element (also the key
|
78
77
|
* in the instances hash.)
|
79
|
-
*
|
80
|
-
* @return {Object} an instance of KennyDialoggins.Dialog
|
81
|
-
*
|
82
78
|
*/
|
83
|
-
KennyDialoggins.Dialog.
|
79
|
+
KennyDialoggins.Dialog.destroy = function(id) {
|
84
80
|
var dialog = this.instances[id];
|
85
|
-
if(dialog) {
|
86
|
-
dialog.
|
81
|
+
if (dialog) {
|
82
|
+
dialog.finalize();
|
87
83
|
}
|
88
|
-
|
89
|
-
}
|
84
|
+
this.instances[id] = null;
|
85
|
+
};
|
90
86
|
|
91
87
|
|
92
88
|
/**
|
@@ -100,11 +96,11 @@ KennyDialoggins.Dialog.show = function(id) {
|
|
100
96
|
*/
|
101
97
|
KennyDialoggins.Dialog.hide = function(id) {
|
102
98
|
var dialog = this.instances[id];
|
103
|
-
if(dialog) {
|
99
|
+
if (dialog) {
|
104
100
|
dialog.hide();
|
105
101
|
}
|
106
102
|
return dialog;
|
107
|
-
}
|
103
|
+
};
|
108
104
|
|
109
105
|
|
110
106
|
/**
|
@@ -118,13 +114,31 @@ KennyDialoggins.Dialog.hide = function(id) {
|
|
118
114
|
* id is showing.
|
119
115
|
*
|
120
116
|
*/
|
121
|
-
KennyDialoggins.Dialog.
|
117
|
+
KennyDialoggins.Dialog.isShowing = function(id) {
|
122
118
|
var dialog = this.instances[id];
|
123
119
|
if (!dialog) {
|
124
120
|
throw "No dialog cound be found for the supplied id.";
|
125
121
|
}
|
126
|
-
return dialog.
|
127
|
-
}
|
122
|
+
return dialog.isShowing();
|
123
|
+
};
|
124
|
+
|
125
|
+
|
126
|
+
/**
|
127
|
+
* This method shows the dialog with the corresponding id.
|
128
|
+
*
|
129
|
+
* @param {String} id The id value of the dialog element (also the key
|
130
|
+
* in the instances hash.)
|
131
|
+
*
|
132
|
+
* @return {Object} an instance of KennyDialoggins.Dialog
|
133
|
+
*
|
134
|
+
*/
|
135
|
+
KennyDialoggins.Dialog.show = function(id) {
|
136
|
+
var dialog = this.instances[id];
|
137
|
+
if (dialog) {
|
138
|
+
dialog.show();
|
139
|
+
}
|
140
|
+
return dialog;
|
141
|
+
};
|
128
142
|
|
129
143
|
|
130
144
|
|
@@ -133,6 +147,33 @@ KennyDialoggins.Dialog.is_showing = function(id) {
|
|
133
147
|
// ----------------------------------------------------------------------------
|
134
148
|
|
135
149
|
Object.extend(KennyDialoggins.Dialog.prototype, {
|
150
|
+
|
151
|
+
|
152
|
+
/**
|
153
|
+
* This function creates the function that handles click events when the dialog is
|
154
|
+
* shown. The handler ignores clicks targeted from within the dialog; any click
|
155
|
+
* targeted outside the dialog causes the dialog to hide itself and cancel the
|
156
|
+
* observer.
|
157
|
+
*/
|
158
|
+
_generateHideListener: function() {
|
159
|
+
return function(evt) {
|
160
|
+
var origin = evt.findElement(".kenny_dialoggins_dialog");
|
161
|
+
if (this._element !== origin) {
|
162
|
+
this.hide();
|
163
|
+
}
|
164
|
+
}.bind(this);
|
165
|
+
},
|
166
|
+
|
167
|
+
|
168
|
+
/**
|
169
|
+
* This function indicates whether or not the dialog is currently
|
170
|
+
* being shown.
|
171
|
+
*
|
172
|
+
* @return {Boolean} Whether or not the dialog is being shown.
|
173
|
+
*/
|
174
|
+
_isShowing: function() {
|
175
|
+
return this._isShowing;
|
176
|
+
},
|
136
177
|
|
137
178
|
/**
|
138
179
|
* This function constructs the dialog element and hides it by default.
|
@@ -146,8 +187,12 @@ Object.extend(KennyDialoggins.Dialog.prototype, {
|
|
146
187
|
_makeDialog: function() {
|
147
188
|
if (!this._element) {
|
148
189
|
this._element = new Element("DIV");
|
149
|
-
this._element.
|
190
|
+
this._element.addClassName("kenny_dialoggins_dialog");
|
191
|
+
if (this._class) {
|
192
|
+
this._element.addClassName(this._class);
|
193
|
+
}
|
150
194
|
this._element.hide();
|
195
|
+
document.body.appendChild(this._element);
|
151
196
|
}
|
152
197
|
},
|
153
198
|
|
@@ -164,26 +209,56 @@ Object.extend(KennyDialoggins.Dialog.prototype, {
|
|
164
209
|
_makeFrame: function() {
|
165
210
|
if (!this._frame) {
|
166
211
|
this._frame = new Element("IFRAME");
|
167
|
-
this._frame.
|
212
|
+
this._frame.addClassName("kenny_dialoggins_dialog_frame");
|
213
|
+
if (this._class) {
|
214
|
+
this._element.addClassName(this._class);
|
215
|
+
}
|
168
216
|
this._frame.setAttribute("src", "about:blank");
|
169
217
|
this._frame.hide();
|
218
|
+
document.body.appendChild(this._frame);
|
170
219
|
}
|
171
220
|
},
|
172
|
-
|
173
|
-
|
221
|
+
|
222
|
+
|
174
223
|
/**
|
175
|
-
* This function
|
176
|
-
*
|
177
|
-
* targeted outside the dialog causes the dialog to hide itself and cancel the
|
178
|
-
* observer.
|
224
|
+
* This function allows the dialog object to be destroyed without
|
225
|
+
* creating memory leaks.
|
179
226
|
*/
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
227
|
+
finalize: function() {
|
228
|
+
this.hide();
|
229
|
+
|
230
|
+
this._element.remove();
|
231
|
+
this._element = null;
|
232
|
+
|
233
|
+
if (this._frame) {
|
234
|
+
this._frame.remove();
|
235
|
+
this._frame = null;
|
236
|
+
}
|
237
|
+
|
238
|
+
this._hideListener = null;
|
239
|
+
},
|
240
|
+
|
241
|
+
|
242
|
+
/**
|
243
|
+
* This function hides the dialog. It uses a scriptaculous effect to fade out
|
244
|
+
* and disconnects the click observer to prevent memory leaks.
|
245
|
+
*/
|
246
|
+
hide: function() {
|
247
|
+
new Effect.Fade(this._element, {
|
248
|
+
duration: 0.2,
|
249
|
+
beforeStart: this._beforeHide,
|
250
|
+
afterFinish: function() {
|
251
|
+
this._isShowing = false;
|
252
|
+
this._afterHide();
|
253
|
+
document.stopObserving("click", this._hideListener);
|
254
|
+
}.bind(this)
|
255
|
+
});
|
256
|
+
|
257
|
+
if (this._frame) {
|
258
|
+
new Effect.Fade(this._frame, {
|
259
|
+
duration: 0.2
|
260
|
+
});
|
261
|
+
}
|
187
262
|
},
|
188
263
|
|
189
264
|
|
@@ -197,6 +272,16 @@ Object.extend(KennyDialoggins.Dialog.prototype, {
|
|
197
272
|
},
|
198
273
|
|
199
274
|
|
275
|
+
/**
|
276
|
+
* This function sets the position of the dialog element.
|
277
|
+
*/
|
278
|
+
setPosition: function() {
|
279
|
+
var layout = new Element.Layout(this._element);
|
280
|
+
this._element.style.top = Math.ceil(((document.viewport.getHeight()/2) + (document.viewport.getScrollOffsets().top) - (layout.get("padding-box-height")/2)) * 2/3) + "px";
|
281
|
+
this._element.style.left = Math.ceil((document.viewport.getWidth()/2) + (document.viewport.getScrollOffsets().left) - (layout.get("padding-box-width")/2)) + "px";
|
282
|
+
},
|
283
|
+
|
284
|
+
|
200
285
|
/**
|
201
286
|
* This function displays the dialog. It uses a scriptaculous effect to fade in,
|
202
287
|
* centers the dialog in the viewport (and adjusts the blocking iframe, if in use),
|
@@ -204,17 +289,14 @@ Object.extend(KennyDialoggins.Dialog.prototype, {
|
|
204
289
|
* the dialog.
|
205
290
|
*/
|
206
291
|
show: function() {
|
207
|
-
|
208
|
-
var method = pair.last();
|
209
|
-
this._element.style[pair.first()] =
|
210
|
-
(document.viewport[method]() / 2 + document.viewport.getScrollOffsets()[pair.first()] - this._element[method]() / 2) + "px";
|
211
|
-
}.bind(this));
|
292
|
+
this.setPosition();
|
212
293
|
|
213
294
|
if (this._frame) {
|
295
|
+
var layout = new Element.Layout(this._element);
|
214
296
|
this._frame.style.top = this._element.style.top;
|
215
297
|
this._frame.style.left = this._element.style.left;
|
216
|
-
this._frame.style.width =
|
217
|
-
this._frame.style.height =
|
298
|
+
this._frame.style.width = layout.get("padding-box-width") + "px";
|
299
|
+
this._frame.style.height = layout.get("padding-box-height") + "px";
|
218
300
|
|
219
301
|
new Effect.Appear(this._frame, {
|
220
302
|
duration: 0.2
|
@@ -225,44 +307,10 @@ Object.extend(KennyDialoggins.Dialog.prototype, {
|
|
225
307
|
duration: 0.2,
|
226
308
|
beforeStart: this._beforeShow,
|
227
309
|
afterFinish: function() {
|
228
|
-
this.
|
310
|
+
this._isShowing = true;
|
229
311
|
this._afterShow();
|
230
312
|
document.observe("click", this._hideListener);
|
231
313
|
}.bind(this)
|
232
314
|
});
|
233
|
-
},
|
234
|
-
|
235
|
-
|
236
|
-
/**
|
237
|
-
* This function hides the dialog. It uses a scriptaculous effect to fade out
|
238
|
-
* and disconnects the click observer to prevent memory leaks.
|
239
|
-
*/
|
240
|
-
hide: function() {
|
241
|
-
new Effect.Fade(this._element, {
|
242
|
-
duration: 0.2,
|
243
|
-
beforeStart: this._beforeHide,
|
244
|
-
afterFinish: function() {
|
245
|
-
this._is_showing = false;
|
246
|
-
this._afterHide();
|
247
|
-
document.stopObserving("click", this._hideListener);
|
248
|
-
}.bind(this)
|
249
|
-
});
|
250
|
-
|
251
|
-
if (this._frame) {
|
252
|
-
new Effect.Fade(this._frame, {
|
253
|
-
duration: 0.2
|
254
|
-
});
|
255
|
-
}
|
256
|
-
},
|
257
|
-
|
258
|
-
|
259
|
-
/**
|
260
|
-
* This function indicates whether or not the dialog is currently
|
261
|
-
* being shown.
|
262
|
-
*
|
263
|
-
* @return {Boolean} Whether or not the dialog is being shown.
|
264
|
-
*/
|
265
|
-
is_showing: function() {
|
266
|
-
return this._is_showing;
|
267
315
|
}
|
268
316
|
});
|
@@ -6,10 +6,12 @@ module Coroutine
|
|
6
6
|
# to this method is the dialog's <tt>id</tt>. The id is required and should be unique.
|
7
7
|
# Further options may be provided; those that are specific to the dialog are:
|
8
8
|
#
|
9
|
+
# * <tt>:class</tt> - a css class name that will be appended to the outermost div to facilitate multiple styles
|
9
10
|
# * <tt>:before_show</tt> - a Javascript function that will be invoked before the dialog is shown
|
10
11
|
# * <tt>:after_show</tt> - a Javascript function that will be invoked after the dialog has become visible
|
11
12
|
# * <tt>:before_hide</tt> - a Javascript function that will be invoked before the dialog is hidden
|
12
13
|
# * <tt>:after_hide</tt> - a Javascript function that will be invoked after the dialog has been hidden
|
14
|
+
# * <tt>&block</tt> - HTML markup that will be automatically converted to render's inline option
|
13
15
|
#
|
14
16
|
# All remaining options are the same as the options available to ActionController::Base#render. Please
|
15
17
|
# see the documentation for ActionController::Base#render for further details.
|
@@ -39,41 +41,92 @@ module Coroutine
|
|
39
41
|
# <%= render_dialog :foo_dialog, :partial => "foo", :before_show => "function() { alert('bar!') }" %>
|
40
42
|
#
|
41
43
|
# This case is similar to the previous case, except that an alert containing the string, "bar!" will
|
42
|
-
# appear before the dialog is shown
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
content = escape_javascript
|
50
|
-
|
44
|
+
# appear before the dialog is shown.
|
45
|
+
#
|
46
|
+
def render_dialog(id, options = {}, &block)
|
47
|
+
options[:inline] = capture(&block) if block_given?
|
48
|
+
render_options = extract_dialog_render_options(options)
|
49
|
+
javascript_options = dialog_options_to_js(extract_dialog_javascript_options(options))
|
50
|
+
|
51
|
+
content = escape_javascript(render(render_options))
|
52
|
+
|
53
|
+
raise "You must specify an id to register a dialog." unless id
|
54
|
+
raise "You must provide content to register a dialog." unless content
|
55
|
+
|
56
|
+
javascript_tag "KennyDialoggins.Dialog.instances['#{id.to_s}'] = new KennyDialoggins.Dialog('#{content}', #{javascript_options});"
|
51
57
|
end
|
52
58
|
|
59
|
+
|
53
60
|
# Returns a string of Javascript that will show the dialog identified by the supplied
|
54
61
|
# dialog_id. As an example of useage, this method might be called as the second argument
|
55
62
|
# to ActionView::Helpers::JavaScriptHelper#link_to_function.
|
63
|
+
#
|
56
64
|
def show_dialog(dialog_id)
|
57
65
|
"KennyDialoggins.Dialog.show('#{dialog_id.to_s}')"
|
58
66
|
end
|
59
67
|
|
68
|
+
|
60
69
|
# Returns a string of Javascript that will hide the dialog identified by the supplied
|
61
70
|
# dialog_id. As an example of useage, this method might be called as the second argument
|
62
71
|
# to ActionView::Helpers::JavaScriptHelper#link_to_function.
|
72
|
+
#
|
63
73
|
def hide_dialog(dialog_id)
|
64
74
|
"KennyDialoggins.Dialog.hide('#{dialog_id.to_s}')"
|
65
75
|
end
|
66
76
|
|
77
|
+
|
78
|
+
|
67
79
|
private
|
68
|
-
|
80
|
+
|
81
|
+
# This method returns an array of javascript option keys supported by the accompanying
|
82
|
+
# javascript library.
|
83
|
+
#
|
84
|
+
def dialog_javascript_option_keys
|
85
|
+
[:class, :before_show, :after_show, :before_hide, :after_hide]
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
# This method converts ruby hashes using underscore notation to js strings using camelcase
|
90
|
+
# notation, which is more common in javascript.
|
91
|
+
#
|
69
92
|
def dialog_options_to_js(options={})
|
70
93
|
js_kv_pairs = []
|
71
|
-
options.
|
72
|
-
|
94
|
+
sorted_keys = options.keys.map { |k| k.to_s }.sort.map { |s| s.to_sym }
|
95
|
+
|
96
|
+
sorted_keys.each do |key|
|
97
|
+
js_key = key.to_s.camelcase(:lower)
|
98
|
+
js_value = "null"
|
99
|
+
|
100
|
+
unless options[key].empty?
|
101
|
+
case key
|
102
|
+
when :before_show, :after_show, :before_hide, :after_hide
|
103
|
+
js_value = "#{options[key]}"
|
104
|
+
else
|
105
|
+
js_value = "'#{options[key]}'"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
js_kv_pairs << "'#{js_key}':#{js_value}"
|
73
110
|
end
|
111
|
+
|
74
112
|
"{#{js_kv_pairs.join(',')}}"
|
75
113
|
end
|
76
114
|
|
115
|
+
|
116
|
+
# This method returns a hash with javascript options. It also inspects the supplied options
|
117
|
+
# and adds defaults as necessary.
|
118
|
+
#
|
119
|
+
def extract_dialog_javascript_options(options)
|
120
|
+
options.reject { |k,v| !dialog_javascript_option_keys.include?(k) }
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
# This method returns a hash with rendering options.
|
125
|
+
#
|
126
|
+
def extract_dialog_render_options(options)
|
127
|
+
options.reject { |k,v| dialog_javascript_option_keys.include?(k) }
|
128
|
+
end
|
129
|
+
|
77
130
|
end
|
78
131
|
end
|
79
132
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kenny_dialoggins
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 1.0.
|
9
|
+
- 3
|
10
|
+
version: 1.0.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Coroutine
|
@@ -17,7 +17,7 @@ autorequire:
|
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
19
|
|
20
|
-
date: 2010-
|
20
|
+
date: 2010-10-19 00:00:00 -05:00
|
21
21
|
default_executable:
|
22
22
|
dependencies:
|
23
23
|
- !ruby/object:Gem::Dependency
|