5d46deb0989999b2f8b80fd63fd86c5207491d6c
[moodle.git] / mod / quiz / yui / src / toolboxes / js / toolbox.js
1 /* eslint-disable no-unused-vars */
2 /**
3  * Resource and activity toolbox class.
4  *
5  * This class is responsible for managing AJAX interactions with activities and resources
6  * when viewing a course in editing mode.
7  *
8  * @module moodle-course-toolboxes
9  * @namespace M.course.toolboxes
10  */
12 // The CSS classes we use.
13 var CSS = {
14         ACTIVITYINSTANCE: 'activityinstance',
15         AVAILABILITYINFODIV: 'div.availabilityinfo',
16         CONTENTWITHOUTLINK: 'contentwithoutlink',
17         CONDITIONALHIDDEN: 'conditionalhidden',
18         DIMCLASS: 'dimmed',
19         DIMMEDTEXT: 'dimmed_text',
20         EDITINSTRUCTIONS: 'editinstructions',
21         EDITINGMAXMARK: 'editor_displayed',
22         HIDE: 'hide',
23         JOIN: 'page_join',
24         MODINDENTCOUNT: 'mod-indent-',
25         MODINDENTHUGE: 'mod-indent-huge',
26         PAGE: 'page',
27         SECTIONHIDDENCLASS: 'hidden',
28         SECTIONIDPREFIX: 'section-',
29         SELECTMULTIPLE: 'select-multiple',
30         SLOT: 'slot',
31         SHOW: 'editing_show',
32         TITLEEDITOR: 'titleeditor'
33     },
34     // The CSS selectors we use.
35     SELECTOR = {
36         ACTIONAREA: '.actions',
37         ACTIONLINKTEXT: '.actionlinktext',
38         ACTIVITYACTION: 'a.cm-edit-action[data-action], a.editing_maxmark, a.editing_section, input.shuffle_questions',
39         ACTIVITYFORM: 'span.instancemaxmarkcontainer form',
40         ACTIVITYINSTANCE: '.' + CSS.ACTIVITYINSTANCE,
41         SECTIONINSTANCE: '.sectioninstance',
42         ACTIVITYLI: 'li.activity, li.section',
43         ACTIVITYMAXMARK: 'input[name=maxmark]',
44         COMMANDSPAN: '.commands',
45         CONTENTAFTERLINK: 'div.contentafterlink',
46         CONTENTWITHOUTLINK: 'div.contentwithoutlink',
47         DELETESECTIONICON: 'a.editing_delete .icon',
48         DESELECTALL: '#questiondeselectall',
49         EDITMAXMARK: 'a.editing_maxmark',
50         EDITSECTION: 'a.editing_section',
51         EDITSECTIONICON: 'a.editing_section .icon',
52         EDITSHUFFLEQUESTIONSACTION: 'input.cm-edit-action[data-action]',
53         EDITSHUFFLEAREA: '.instanceshufflequestions .shuffle-progress',
54         HIDE: 'a.editing_hide',
55         HIGHLIGHT: 'a.editing_highlight',
56         INSTANCENAME: 'span.instancename',
57         INSTANCEMAXMARK: 'span.instancemaxmark',
58         INSTANCESECTION: 'span.instancesection',
59         INSTANCESECTIONAREA: 'div.section-heading',
60         MODINDENTDIV: '.mod-indent',
61         MODINDENTOUTER: '.mod-indent-outer',
62         NUMQUESTIONS: '.numberofquestions',
63         PAGECONTENT: 'div#page-content',
64         PAGELI: 'li.page',
65         SECTIONUL: 'ul.section',
66         SECTIONFORM: '.instancesectioncontainer form',
67         SECTIONINPUT: 'input[name=section]',
68         SELECTMULTIPLEBUTTON: '#selectmultiplecommand',
69         SELECTMULTIPLECANCELBUTTON: '#selectmultiplecancelcommand',
70         SELECTMULTIPLECHECKBOX: '.select-multiple-checkbox',
71         SELECTMULTIPLEDELETEBUTTON: '#selectmultipledeletecommand',
72         SELECTALL: '#questionselectall',
73         SHOW: 'a.' + CSS.SHOW,
74         SLOTLI: 'li.slot',
75         SUMMARKS: '.mod_quiz_summarks'
76     },
77     BODY = Y.one(document.body);
79 // Setup the basic namespace.
80 M.mod_quiz = M.mod_quiz || {};
82 /**
83  * The toolbox class is a generic class which should never be directly
84  * instantiated. Please extend it instead.
85  *
86  * @class toolbox
87  * @constructor
88  * @protected
89  * @extends Base
90  */
91 var TOOLBOX = function() {
92     TOOLBOX.superclass.constructor.apply(this, arguments);
93 };
95 Y.extend(TOOLBOX, Y.Base, {
96     /**
97      * Send a request using the REST API
98      *
99      * @method send_request
100      * @param {Object} data The data to submit with the AJAX request
101      * @param {Node} [statusspinner] A statusspinner which may contain a section loader
102      * @param {Function} success_callback The callback to use on success
103      * @param {Object} [optionalconfig] Any additional configuration to submit
104      * @chainable
105      */
106     send_request: function(data, statusspinner, success_callback, optionalconfig) {
107         // Default data structure
108         if (!data) {
109             data = {};
110         }
112         // Handle any variables which we must pass back through to
113         var pageparams = this.get('config').pageparams,
114             varname;
115         for (varname in pageparams) {
116             data[varname] = pageparams[varname];
117         }
119         data.sesskey = M.cfg.sesskey;
120         data.courseid = this.get('courseid');
121         data.quizid = this.get('quizid');
123         var uri = M.cfg.wwwroot + this.get('ajaxurl');
125         // Define the configuration to send with the request
126         var responsetext = [];
127         var config = {
128             method: 'POST',
129             data: data,
130             on: {
131                 success: function(tid, response) {
132                     try {
133                         responsetext = Y.JSON.parse(response.responseText);
134                         if (responsetext.error) {
135                             new M.core.ajaxException(responsetext);
136                         }
137                     } catch (e) {
138                         // Ignore.
139                     }
141                     // Run the callback if we have one.
142                     if (responsetext.hasOwnProperty('newsummarks')) {
143                         Y.one(SELECTOR.SUMMARKS).setHTML(responsetext.newsummarks);
144                     }
145                     if (responsetext.hasOwnProperty('newnumquestions')) {
146                         Y.one(SELECTOR.NUMQUESTIONS).setHTML(
147                                 M.util.get_string('numquestionsx', 'quiz', responsetext.newnumquestions)
148                             );
149                     }
150                     if (success_callback) {
151                         Y.bind(success_callback, this, responsetext)();
152                     }
154                     if (statusspinner) {
155                         window.setTimeout(function() {
156                             statusspinner.hide();
157                         }, 400);
158                     }
159                 },
160                 failure: function(tid, response) {
161                     if (statusspinner) {
162                         statusspinner.hide();
163                     }
164                     new M.core.ajaxException(response);
165                 }
166             },
167             context: this
168         };
170         // Apply optional config
171         if (optionalconfig) {
172             for (varname in optionalconfig) {
173                 config[varname] = optionalconfig[varname];
174             }
175         }
177         if (statusspinner) {
178             statusspinner.show();
179         }
181         // Send the request
182         Y.io(uri, config);
183         return this;
184     }
185 },
187     NAME: 'mod_quiz-toolbox',
188     ATTRS: {
189         /**
190          * The ID of the Moodle Course being edited.
191          *
192          * @attribute courseid
193          * @default 0
194          * @type Number
195          */
196         courseid: {
197             'value': 0
198         },
200         /**
201          * The Moodle course format.
202          *
203          * @attribute format
204          * @default 'topics'
205          * @type String
206          */
207         quizid: {
208             'value': 0
209         },
210         /**
211          * The URL to use when submitting requests.
212          * @attribute ajaxurl
213          * @default null
214          * @type String
215          */
216         ajaxurl: {
217             'value': null
218         },
219         /**
220          * Any additional configuration passed when creating the instance.
221          *
222          * @attribute config
223          * @default {}
224          * @type Object
225          */
226         config: {
227             'value': {}
228         }
229     }
231 );