1
/* Copyright (c) 2009, Canonical Ltd. All rights reserved. */
3
YUI.add('lazr.activator', function(Y) {
5
var ACTIVATOR = 'activator',
8
getCN = Y.ClassNameManager.getClassName,
11
MESSAGE_HEADER_TEMPLATE = '<div></div>',
12
MESSAGE_BODY_TEMPLATE = '<div></div>',
13
MESSAGE_CLOSE_BUTTON_TEMPLATE = '<button>Close</button>',
18
// Class for hiding elements.
19
C_HIDDEN = getCN(ACTIVATOR, 'hidden'),
21
// Classes identifying elements.
22
C_ACT = getCN(ACTIVATOR, 'act'),
23
C_DATA_BOX = getCN(ACTIVATOR, 'data-box'),
24
C_MESSAGE_BOX = getCN(ACTIVATOR, 'message-box'),
26
// Classes for internally created elements.
27
C_MESSAGE_CLOSE = getCN(ACTIVATOR, 'message-close'),
28
C_MESSAGE_HEADER = getCN(ACTIVATOR, 'message-header'),
29
C_MESSAGE_BODY = getCN(ACTIVATOR, 'message-body'),
31
// Classes indicating status.
32
C_PROCESSING = getCN(ACTIVATOR, 'processing'),
33
C_CANCEL = getCN(ACTIVATOR, 'cancellation'),
34
C_SUCCESS = getCN(ACTIVATOR, 'success'),
35
C_FAILURE = getCN(ACTIVATOR, 'failure'),
37
ALL_STATUSES = [C_SUCCESS, C_FAILURE, C_CANCEL, C_PROCESSING];
40
* The Activator widget will hook up an element to trigger an action,
41
* and it will change the display to indicate whether the action
42
* is processing, ended successfully, ended in error, or was cancelled.
44
* A CSS class is applied in each different state. Success and
45
* failure also trigger a green or red flash animation.
51
var Activator = function() {
52
Activator.superclass.constructor.apply(this, arguments);
55
Activator.NAME = ACTIVATOR;
59
Y.extend(Activator, Y.Widget, {
62
* Destination of status messages.
64
* @property message_box
70
* Destination of new data. Useful when activating an editor.
78
* Element that triggers the event.
80
* @property action_element
86
* Set the CSS class on the context box to indicate that the status is
87
* either error, success, cancellation, or processing.
89
* @method _setStatusClass
92
_setStatusClass: function(css_class) {
93
Y.Array.each(ALL_STATUSES, function (old_class, i) {
94
this.get('contentBox').removeClass(old_class);
96
this.get('contentBox').addClass(css_class);
100
* Display message for either error, success, cancellation, or
103
* @method _renderMessage
106
_renderMessage: function(title, message_node) {
107
this.message_box.set('innerHTML', '');
108
if (message_node === undefined) {
109
this.message_box.addClass(C_HIDDEN);
111
this.message_box.removeClass(C_HIDDEN);
114
var message_close_button = Y.Node.create(
115
MESSAGE_CLOSE_BUTTON_TEMPLATE);
116
message_close_button.addClass(C_MESSAGE_CLOSE);
117
message_close_button.addClass('lazr-btn');
119
message_close_button.on('click', function (e) {
120
this.message_box.addClass(C_HIDDEN);
124
var message_header = Y.Node.create(MESSAGE_HEADER_TEMPLATE);
125
message_header.appendChild(message_close_button);
126
message_header.appendChild(Y.Node.create(title));
127
message_header.addClass(C_MESSAGE_HEADER);
130
var message_body = Y.Node.create(
131
MESSAGE_BODY_TEMPLATE);
132
message_body.appendChild(message_node);
133
message_body.addClass(C_MESSAGE_BODY);
135
this.message_box.appendChild(message_header);
136
this.message_box.appendChild(message_body);
141
* Animate that the action occurred successfully, and overwrite the
142
* contents of the element which has the C_DATA_BOX class.
144
* @method renderSuccess
145
* @param {Node} data_node Optional parameter to update data. Normally
146
* this would indicate editing a field.
147
* @param {Node} message_node Optional parameter to display a message.
150
renderSuccess: function(data_node, message_node) {
151
if (data_node !== undefined) {
152
this.data_box.set('innerHTML', '');
153
this.data_box.appendChild(data_node);
155
this._setStatusClass(C_SUCCESS);
156
this._renderMessage('Message', message_node);
157
var anim = Y.lazr.anim.green_flash({node: this.animation_node});
164
* @method renderFailure
165
* @param {Node} Optional parameter to display a message.
168
renderFailure: function(message_node) {
169
this._renderMessage('Error', message_node);
170
this._setStatusClass(C_FAILURE);
171
var anim = Y.lazr.anim.red_flash({node: this.animation_node});
176
* Animate cancellation.
178
* @method renderCancellation
179
* @param {Node} Optional parameter to display a message.
182
renderCancellation: function(message_node) {
183
this._renderMessage('Message', message_node);
184
this._setStatusClass(C_CANCEL);
185
var anim = Y.lazr.anim.red_flash({node: this.animation_node});
190
* Indicate that the action is processing. This is normally done
191
* by configuring the C_PROCESSING class to display a spinning
194
* @method renderProcessing
195
* @param {Node} Optional parameter to display a message.
198
renderProcessing: function(message_node) {
199
this._renderMessage('Message', message_node);
200
this._setStatusClass(C_PROCESSING);
204
* Initialize the widget.
206
* @method initializer
209
initializer: function(cfg) {
211
if (cfg === undefined || cfg.contentBox === undefined) {
212
// We need the contentBox to be passed in the cfg,
213
// although the init method is the one that actually copies
214
// that cfg to the contentBox ATTR.
215
throw new Error("Missing contentBox argument for Activator.");
217
this.message_box = this.get('contentBox').one('.' + C_MESSAGE_BOX);
218
if (this.message_box === null) {
219
throw new Error("Can't find element with CSS class " +
220
C_MESSAGE_BOX + ".");
222
this.data_box = this.get('contentBox').one('.' + C_DATA_BOX);
223
if (this.data_box === null) {
224
throw new Error("Can't find element with CSS class " +
227
this.action_element = this.get('contentBox').one('.' + C_ACT);
228
if (this.action_element === null) {
229
throw new Error("Can't find element with CSS class " +
232
this.animation_node = cfg.animationNode;
233
if (this.animation_node === undefined) {
234
this.animation_node = this.get('contentBox');
239
* Update the DOM structure and edit CSS classes.
244
renderUI: function() {
245
// Just in case the user didn't assign the correct classes.
246
this.action_element.removeClass(C_HIDDEN);
247
// Use   character to prevent IE7 from hiding the
248
// yui3-activator-act button, when it just has a background-image
249
// and no content in it or in the data_box.
250
this.get('contentBox').prepend(' ');
254
* Set the event handler for the actor element.
260
var activator = this;
261
Y.on('click', function(e) {
264
}, this.action_element);
268
* UI syncing should all be handled by the status events.
277
Y.lazr.ui.disableTabIndex(Activator);
279
Y.namespace('lazr.activator');
280
Y.lazr.activator.Activator = Activator;
283
}, "0.1", {"skinnable": true,
284
"requires": ["oop", "event", "node", "widget",
285
"lazr.anim", "lazr.base"]});