Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
// This file is part of Moodle - http://moodle.org/
2
//
3
// Moodle is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, either version 3 of the License, or
6
// (at your option) any later version.
7
//
8
// Moodle is distributed in the hope that it will be useful,
9
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
// GNU General Public License for more details.
12
//
13
// You should have received a copy of the GNU General Public License
14
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
15
 
16
/**
17
 * A class to help show and hide advanced form content.
18
 *
19
 * @module     core_form/showadvanced
20
 * @copyright  2016 Damyon Wiese <damyon@moodle.com>
21
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22
 */
23
define(['jquery', 'core/log', 'core/str', 'core/notification'], function($, Log, Strings, Notification) {
24
 
25
    var SELECTORS = {
26
            FIELDSETCONTAINSADVANCED: 'fieldset.containsadvancedelements',
27
            DIVFITEMADVANCED: 'div.fitem.advanced',
28
            DIVADVANCEDSECTION: 'div#form-advanced-div',
29
            DIVFCONTAINER: 'div.fcontainer',
30
            MORELESSLINK: 'fieldset.containsadvancedelements .moreless-toggler'
31
        },
32
        CSS = {
33
            SHOW: 'show',
34
            MORELESSACTIONS: 'moreless-actions',
35
            MORELESSTOGGLER: 'moreless-toggler',
36
            SHOWLESS: 'moreless-less'
37
        },
38
        WRAPPERS = {
39
            FITEM: '<div class="fitem"></div>',
40
            FELEMENT: '<div class="felement"></div>',
41
            ADVANCEDDIV: '<div id="form-advanced-div"></div>'
42
        },
43
        IDPREFIX = 'showadvancedid-';
44
 
45
    /** @property {Integer} uniqIdSeed Auto incrementing number used to generate ids. */
46
    var uniqIdSeed = 0;
47
 
48
    /**
49
     * ShowAdvanced behaviour class.
50
     *
51
     * @class core_form/showadvanced
52
     * @param {String} id The id of the form.
53
     */
54
    var ShowAdvanced = function(id) {
55
        this.id = id;
56
 
57
        var form = $(document.getElementById(id));
58
        this.enhanceForm(form);
59
    };
60
 
61
    /** @property {String} id The form id to enhance. */
62
    ShowAdvanced.prototype.id = '';
63
 
64
    /**
65
     * @method enhanceForm
66
     * @param {JQuery} form JQuery selector representing the form
67
     * @return {ShowAdvanced}
68
     */
69
    ShowAdvanced.prototype.enhanceForm = function(form) {
70
        var fieldsets = form.find(SELECTORS.FIELDSETCONTAINSADVANCED);
71
 
72
        // Enhance each fieldset in the form matching the selector.
73
        fieldsets.each(function(index, item) {
74
            this.enhanceFieldset($(item));
75
        }.bind(this));
76
 
77
        // Attach some event listeners.
78
        // Subscribe more/less links to click event.
79
        form.on('click', SELECTORS.MORELESSLINK, this.switchState);
80
 
81
        // Subscribe to key events but filter for space or enter.
82
        form.on('keydown', SELECTORS.MORELESSLINK, function(e) {
83
            // Enter or space.
84
            if (e.which == 13 || e.which == 32) {
85
                return this.switchState(e);
86
            }
87
            return true;
88
        }.bind(this));
89
        return this;
90
    };
91
 
92
 
93
    /**
94
     * Generates a uniq id for the dom element it's called on unless the element already has an id.
95
     * The id is set on the dom node before being returned.
96
     *
97
     * @method generateId
98
     * @param {JQuery} node JQuery selector representing a single DOM Node.
99
     * @return {String}
100
     */
101
    ShowAdvanced.prototype.generateId = function(node) {
102
        var id = node.prop('id');
103
        if (typeof id === 'undefined') {
104
            id = IDPREFIX + (uniqIdSeed++);
105
            node.prop('id', id);
106
        }
107
        return id;
108
    };
109
 
110
    /**
111
     * @method enhanceFieldset
112
     * @param {JQuery} fieldset JQuery selector representing a fieldset
113
     * @return {ShowAdvanced}
114
     */
115
    ShowAdvanced.prototype.enhanceFieldset = function(fieldset) {
116
        var statuselement = $('input[name=mform_showmore_' + fieldset.prop('id') + ']');
117
        if (!statuselement.length) {
118
            Log.debug("M.form.showadvanced::processFieldset was called on an fieldset without a status field: '" +
119
                fieldset.prop('id') + "'");
120
            return this;
121
        }
122
 
123
        // Fetch some strings.
124
        Strings.get_strings([{
125
            key: 'showmore',
126
            component: 'core_form'
127
        }, {
128
            key: 'showless',
129
            component: 'core_form'
130
        }]).then(function(results) {
131
            var showmore = results[0],
132
                showless = results[1];
133
 
134
            // Generate more/less links.
135
            var morelesslink = $('<a href="#"></a>');
136
            morelesslink.addClass(CSS.MORELESSTOGGLER);
137
            if (statuselement.val() === '0') {
138
                morelesslink.html(showmore);
139
                morelesslink.attr('aria-expanded', 'false');
140
            } else {
141
                morelesslink.html(showless);
142
                morelesslink.attr('aria-expanded', 'true');
143
                morelesslink.addClass(CSS.SHOWLESS);
144
                fieldset.find(SELECTORS.DIVFITEMADVANCED).addClass(CSS.SHOW);
145
            }
146
            // Build a list of advanced fieldsets.
147
            var idlist = [];
148
            fieldset.find(SELECTORS.DIVFITEMADVANCED).each(function(index, node) {
149
                idlist[idlist.length] = this.generateId($(node));
150
            }.bind(this));
151
 
152
            // Set aria attributes.
153
            morelesslink.attr('role', 'button');
154
            morelesslink.attr('aria-controls', 'form-advanced-div');
155
 
156
            var formadvancedsection = $(WRAPPERS.ADVANCEDDIV);
157
            fieldset.find(SELECTORS.DIVFITEMADVANCED).wrapAll(formadvancedsection);
158
            // Add elements to the DOM.
159
            var fitem = $(WRAPPERS.FITEM);
160
            fitem.addClass(CSS.MORELESSACTIONS);
161
            var felement = $(WRAPPERS.FELEMENT);
162
            felement.append(morelesslink);
163
            fitem.append(felement);
164
 
165
            fieldset.find(SELECTORS.DIVADVANCEDSECTION).before(fitem);
166
            return true;
167
        }.bind(this)).fail(Notification.exception);
168
 
169
        return this;
170
    };
171
 
172
    /**
173
     * @method switchState
174
     * @param {Event} e Event that triggered this action.
175
     * @return {Boolean}
176
     */
177
    ShowAdvanced.prototype.switchState = function(e) {
178
        e.preventDefault();
179
 
180
        // Fetch some strings.
181
        Strings.get_strings([{
182
            key: 'showmore',
183
            component: 'core_form'
184
        }, {
185
            key: 'showless',
186
            component: 'core_form'
187
        }]).then(function(results) {
188
            var showmore = results[0],
189
                showless = results[1],
190
                fieldset = $(e.target).closest(SELECTORS.FIELDSETCONTAINSADVANCED);
191
 
192
            // Toggle collapsed class.
193
            fieldset.find(SELECTORS.DIVFITEMADVANCED).toggleClass(CSS.SHOW);
194
 
195
            // Get corresponding hidden variable.
196
            var statuselement = $('input[name=mform_showmore_' + fieldset.prop('id') + ']');
197
 
198
            // Invert it and change the link text.
199
            if (statuselement.val() === '0') {
200
                statuselement.val(1);
201
                $(e.target).addClass(CSS.SHOWLESS);
202
                $(e.target).html(showless);
203
                $(e.target).attr('aria-expanded', 'true');
204
            } else {
205
                statuselement.val(0);
206
                $(e.target).removeClass(CSS.SHOWLESS);
207
                $(e.target).html(showmore);
208
                $(e.target).attr('aria-expanded', 'false');
209
            }
210
            return true;
211
        }).fail(Notification.exception);
212
 
213
        return this;
214
    };
215
 
216
    return {
217
        /**
218
         * Initialise this module.
219
         * @method init
220
         * @param {String} formid
221
         * @return {ShowAdvanced}
222
         */
223
        init: function(formid) {
224
            return new ShowAdvanced(formid);
225
        }
226
    };
227
});