2
Copyright (c) 2009, Canonical Ltd. All rights reserved.
4
This program is free software: you can redistribute it and/or modify
5
it under the terms of the GNU Affero General Public License as published by
6
the Free Software Foundation, either version 3 of the License, or
7
(at your option) any later version.
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU Affero General Public License for more details.
14
You should have received a copy of the GNU Affero General Public License
15
along with this program. If not, see <http://www.gnu.org/licenses/>.
18
YUI.add('lazr.effects-async', function(Y) {
21
* A quick and simple effect for revealing blocks of text when you click
22
* on them. The first click fetches the content using an AJAX request,
23
* after which the widget acts like a regular sliding-reveal.
25
* @module lazr.effects
27
* @namespace lazr.effects
30
Y.namespace('lazr.effects');
32
var effects = Y.lazr.effects;
34
var FOLDED = 'lazr-folded';
38
* A quick and simple effect for revealing blocks of asynchronously loaded
39
* content when you click on them. The first click fetches the content using
40
* an AJAX request, after which the widget acts like a regular sliding-reveal.
42
* The function tracks the state of the initial content load by setting the
43
* <code>content_loaded</code> attribute on the container object. The
44
* attribute will be set to <code>true</code> after the initial load
47
* The trigger recieves the 'lazr-trigger' class, and the content
48
* receives 'lazr-content'.
50
* Both the trigger and content nodes receive the 'lazr-folded' class whenever
51
* the content is closed.
53
* The container may also obtain the 'lazr-waiting' and 'lazr-io-error'
54
* classes during the asynchronous data fetch.
56
* @method async_slideout
58
* @param slider {Node} The node that will slide open and closed, and hold the
59
* asynchronous content.
60
* @param trigger {Node} The node that we will clicked on to open and close
62
* @param uri {String} The URI to fetch the content from.
63
* @param container {Node} <i>Optional</i> A child of the sliding
64
* container node that will hold the asynchronous content.
66
Y.lazr.effects.async_slideout = function(slider, trigger, uri, container) {
67
// The slider is busted in IE 7 :(
72
// Prepare our object state.
73
slider = Y.one(slider);
74
if (typeof slider.content_loaded == 'undefined') {
75
slider.content_loaded = false;
78
if (typeof container == 'undefined' || container === null) {
79
// The user didn't give us an explict target container for the new
80
// content, so we'll reuse the sliding container node.
84
trigger.addClass(FOLDED);
85
trigger.addClass('lazr-trigger');
86
slider.addClass(FOLDED);
87
slider.addClass('lazr-content');
89
trigger.on('click', function(e) {
92
trigger.toggleClass(FOLDED);
93
container.toggleClass(FOLDED);
95
if (!container.content_loaded) {
96
fetch_and_reveal_content(slider, container, uri);
97
container.content_loaded = true;
99
animate_drawer(slider);
105
* Slide the content in or out by reversing the slider.fx animation object.
107
function animate_drawer(slider) {
109
slider.fx.set('reverse', !slider.fx.get("reverse"));
114
* Fetch the slide-out drawer's data asynchronously, unset the waiting state,
115
* and fill the container with either the new content or an appropriate error
116
* message. Finally, slide the drawer to fit its new contents.
118
function fetch_and_reveal_content(slider, container, uri) {
122
complete: function() {
123
ui.clear_waiting(container);
125
success: function(id, response) {
126
container.set('innerHTML', response.responseText);
128
slider.fx = effects.slide_out(slider);
131
failure: function(id, response, args) {
132
// Undo the slide animation's changes to the container style.
137
show_nice_error(id, response, args, container, run_io);
138
Y.lazr.anim.red_flash({ node: slider }).run();
140
// If the user clicks the collapse trigger, we want to slide
141
// the drawer back in. But doing so first reverses the
142
// animation, then runs it (because it assumes that slider.fx
143
// is a effects.slide_out() object), so we need to reverse
144
// our effects.slide_in() animation, so its state is the same
145
// as if it were an open effects.slide_out().
147
slider.fx = effects.slide_in(slider);
148
slider.fx.set('reverse', !slider.fx.get('reverse'));
153
// Wrap this in a closure, so we can retry it if there is an error.
155
ui.waiting(container);
156
container.set('innerHTML', '');
157
// Slide out enough to fully show the spinner.
158
slider.fx = effects.slide_out(slider, { to: { height: '20px' } });
167
* Display a nice error message in the specified container if the asynchronous
168
* data request failed.
170
* XXX mars 2009-04-21 bug=364612
172
* Need to move this to lazr.io.
174
function show_nice_error(id, response, args, message_container,
176
var status_msg = '<span class="io-status">' +
177
response.status + ' ' +
178
response.statusText +
181
['<div class="lazr-io-error">',
182
'<p>Communication with the server failed</p>',
183
'<p>The server\'s response was: ' + status_msg + '</p>',
184
'<button title="Try to contact the server again">Retry</button>',
187
message_container.set('innerHTML', msg_html);
189
// Hook up our Retry function.
190
message_container.one('button').on('click', function(e) {
197
}, null, { "requires":["node", "event", "io-base", "lazr.base", "lazr.effects",