~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/app/javascript/confirmationoverlay/confirmationoverlay.js

  • Committer: j.c.sackett
  • Date: 2011-08-31 15:00:45 UTC
  • mfrom: (13834 devel)
  • mto: This revision was merged to the branch mainline in revision 13840.
  • Revision ID: jonathan.sackett@canonical.com-20110831150045-7s7u8upka5yx5c5c
MergedĀ inĀ devel.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2011, Canonical Ltd. All rights reserved. */
 
2
 
 
3
/* XXX: rvb 2011-08-30 bug=837447: This module should be moved to
 
4
 * a central place with the other overlays.
 
5
 * (lib/lp/app/javascript/overlay)
 
6
 */
 
7
 
 
8
YUI.add('lp.app.confirmationoverlay', function(Y) {
 
9
 
 
10
/**
 
11
 * Display a confirmation overlay before submitting a form.
 
12
 *
 
13
 * @module lp.app.confirmationoverlay
 
14
 */
 
15
 
 
16
var NAME = 'lp-app-confirmationoverlay';
 
17
 
 
18
/**
 
19
 * The ConfirmationOverlay class builds on the lazr.FormOverlay
 
20
 * class.  It 'wraps' itself around a button so that a confirmation
 
21
 * pop-up is displayed when the button is clicked to let the user
 
22
 * a chance to cancel the form submission.  Note that the button
 
23
 * can be simply 'disabled' if it's desirable to prevent the usage
 
24
 * of that button if the user's browser has no Javascript support.
 
25
 *
 
26
 * @class ConfirmationOverlay
 
27
 * @namespace lp.app
 
28
 */
 
29
function ConfirmationOverlay(config) {
 
30
    ConfirmationOverlay.superclass.constructor.apply(this, arguments);
 
31
}
 
32
 
 
33
ConfirmationOverlay.NAME = NAME;
 
34
 
 
35
ConfirmationOverlay.ATTRS = {
 
36
 
 
37
    /**
 
38
     * The input button what should be 'guarded' by this confirmation
 
39
     * overlay.
 
40
     *
 
41
     * @attribute button
 
42
     * @type Node
 
43
     * @default null
 
44
     */
 
45
    button: {
 
46
        value: null
 
47
    },
 
48
 
 
49
    /**
 
50
     * The form that should be submitted once the confirmation has been
 
51
     * passed.
 
52
     *
 
53
     * @attribute submit_form
 
54
     * @type Node
 
55
     * @default null
 
56
     */
 
57
    submit_form: {
 
58
        value: null
 
59
    },
 
60
 
 
61
    /**
 
62
     * An optional function (must return a string or a Node) that will be run
 
63
     * to populate the form_content of the confirmation overlay when it's
 
64
     * displayed.  This is useful if the confirmation overlay must displayed
 
65
     * information that is only available at form submission time.
 
66
     *
 
67
     * @attribute form_content_fn
 
68
     * @type Function
 
69
     * @default null
 
70
     *
 
71
     */
 
72
    form_content_fn: {
 
73
        value: null
 
74
    },
 
75
 
 
76
    /**
 
77
     * An optional function (must return a string or a Node) that will be run
 
78
     * to populate the headerContent of the confirmation overlay when it's
 
79
     * displayed.  This is useful if the confirmation overlay must displayed
 
80
     * information that is only available at form submission time.
 
81
     *
 
82
     * @attribute header_content_fn
 
83
     * @type Function
 
84
     * @default null
 
85
     *
 
86
     */
 
87
    header_content_fn: {
 
88
        value: null
 
89
    },
 
90
 
 
91
    /**
 
92
     * An optional function (must return a boolean) that will be run to
 
93
     * before the confirmation overlay is shown to decide whether it
 
94
     * should really be displayed.
 
95
     *
 
96
     * @attribute display_confirmation_fn
 
97
     * @type Function
 
98
     * @default null
 
99
     *
 
100
     */
 
101
    display_confirmation_fn: {
 
102
        value: null
 
103
    }
 
104
};
 
105
 
 
106
Y.extend(ConfirmationOverlay, Y.lazr.FormOverlay, {
 
107
 
 
108
    initializer: function(cfg) {
 
109
        var submit_button = Y.Node.create(
 
110
            '<button type="submit" class="lazr-pos lazr-btn ok-btn" />')
 
111
            .set("text", "OK");
 
112
        var cancel_button = Y.Node.create(
 
113
            '<button type="button" class="lazr-neg lazr-btn cancel-btn" />')
 
114
            .set("text", "Cancel");
 
115
        this.set('form_submit_button', submit_button);
 
116
        this.set('form_cancel_button', cancel_button);
 
117
 
 
118
        this.set('submit_form', this.get('button').ancestor('form'));
 
119
 
 
120
        // When ok is clicked, submit the form.
 
121
        var self = this;
 
122
        var submit_form = function() {
 
123
            self._createHiddenDispatcher();
 
124
            self._submitForm();
 
125
        };
 
126
        this.set('form_submit_callback', submit_form);
 
127
 
 
128
        // Enable the button if it's disabled.
 
129
        this.get('button').set('disabled', false);
 
130
 
 
131
        // Wire this._handleButtonClicked to the button.
 
132
        this.get(
 
133
            'button').on('click', Y.bind(this._handleButtonClicked, this));
 
134
 
 
135
        // Hide the overlay.
 
136
        this.hide();
 
137
    },
 
138
 
 
139
    /**
 
140
     * Submit the form (this is used after the user has clicked the 'ok'
 
141
     * button on the confirmation form.
 
142
     *
 
143
     * @method _submitForm
 
144
     */
 
145
    _submitForm: function() {
 
146
        // We can't use YUI's io-form here because we want the browser to
 
147
        // display the page returned by the POST's request.
 
148
        this.get('submit_form').submit();
 
149
    },
 
150
 
 
151
    /**
 
152
     * Prevent form submission and display the confirmation overlay.
 
153
     *
 
154
     * @method _handleButtonClicked
 
155
     */
 
156
     _handleButtonClicked: function(e) {
 
157
        var display_confirmation_fn = this.get('display_confirmation_fn');
 
158
        if (display_confirmation_fn === null || display_confirmation_fn()) {
 
159
            // Stop the event to prevent the form submission.
 
160
            e.preventDefault();
 
161
            // Update the overlay's content.
 
162
            this._renderUIFormOverlay();
 
163
            this._fillContent();
 
164
            this._positionOverlay();
 
165
            this._setFormContent();
 
166
            // Render and display the overlay.
 
167
            this.render();
 
168
            this.show();
 
169
        }
 
170
    },
 
171
 
 
172
    /**
 
173
     * Update the header and the content of the overlay.
 
174
     *
 
175
     * @method _fillContent
 
176
     */
 
177
     _fillContent: function() {
 
178
        var form_content_fn = this.get('form_content_fn');
 
179
        if (form_content_fn !== null) {
 
180
            var content = form_content_fn();
 
181
            // Make sure that form_content is a string,
 
182
            // if it's a Y.Node, FormOverlay will append
 
183
            // it to the form content instead of replacing it.
 
184
            if (content instanceof Y.Node) {
 
185
                content = content.get('innerHTML');
 
186
            }
 
187
            this.set('form_content', content);
 
188
        }
 
189
        var header_content_fn = this.get('header_content_fn');
 
190
        if (header_content_fn !== null) {
 
191
            this.set('headerContent', header_content_fn());
 
192
        }
 
193
     },
 
194
 
 
195
 
 
196
    /**
 
197
     * Center the overlay in the viewport.
 
198
     *
 
199
     * @method  _positionOverlay
 
200
     */
 
201
     _positionOverlay: function() {
 
202
        this.set(
 
203
            'align',
 
204
            {points: [
 
205
              Y.WidgetPositionAlign.CC,
 
206
              Y.WidgetPositionAlign.CC]
 
207
            });
 
208
    },
 
209
 
 
210
    /**
 
211
     * Create a hidden input to simulate the click on the right
 
212
     * button.
 
213
     *
 
214
     * @method _createHiddenDispatcher
 
215
     */
 
216
    _createHiddenDispatcher: function() {
 
217
        var dispatcher = Y.Node.create('<input>')
 
218
            .set('type', 'hidden')
 
219
            .addClass('hidden-input')
 
220
            .set('name', this.get('button').get('name'))
 
221
            .set('value', this.get('button').get('value'));
 
222
        this.get('submit_form').append(dispatcher);
 
223
    }
 
224
 
 
225
});
 
226
 
 
227
var namespace = Y.namespace('lp.app.confirmationoverlay');
 
228
namespace.ConfirmationOverlay = ConfirmationOverlay;
 
229
 
 
230
}, "0.1", {"skinnable": true, "requires": ["lazr.formoverlay"]});