MDL-20636 Finish making ddwtos work, mostly. Also various other JS fixes.
[moodle.git] / question / qengine.js
1 M.core_question_engine = M.core_question_engine || {};
3 /**
4  * Flag used by M.core_question_engine.prevent_repeat_submission.
5  */
6 M.core_question_engine.questionformalreadysubmitted = false;
8 /**
9  * Initialise a question submit button. This saves the scroll position and
10  * sets the fragment on the form submit URL so the page reloads in the right place.
11  * @param id the id of the button in the HTML.
12  * @param slot the number of the question_attempt within the usage.
13  */
14 M.core_question_engine.init_submit_button = function(Y, button, slot) {
15     var buttonel = document.getElementById(button);
16     Y.on('click', function(e) {
17         var scrollpos = document.getElementById('scrollpos');
18         if (scrollpos) {
19             scrollpos.value = YAHOO.util.Dom.getDocumentScrollTop();
20         }
21         buttonel.form.action = buttonel.form.action + '#q' + slot;
22     }, buttonel);
23 }
25 /**
26  * Initialise a form that contains questions printed using print_question.
27  * This has the effect of:
28  * 1. Turning off browser autocomlete.
29  * 2. Stopping enter from submitting the form (or toggling the next flag) unless
30  *    keyboard focus is on the submit button or the flag.
31  * 3. Removes any '.questionflagsavebutton's, since we have JavaScript to toggle
32  *    the flags using ajax.
33  * 4. Scroll to the position indicated by scrollpos= in the URL, if it is there.
34  * 5. Prevent the user from repeatedly submitting the form.
35  * @param Y the Yahoo object. Needs to have the DOM and Event modules loaded.
36  * @param form something that can be passed to Y.one, to find the form element.
37  */
38 M.core_question_engine.init_form = function(Y, form) {
39     Y.one(form).setAttribute('autocomplete', 'off');
41     Y.on('submit', M.core_question_engine.prevent_repeat_submission, form, form, Y);
43     Y.on('key', function (e) {
44         if (!e.target.test('a') && !e.target.test('input[type=submit]') &&
45                 !e.target.test('input[type=img]')) {
46             e.preventDefault();
47         }
48     }, form, 'press:13');
50     Y.one(form).all('.questionflagsavebutton').remove();
52     var matches = window.location.href.match(/^.*[?&]scrollpos=(\d*)(?:&|$|#).*$/, '$1');
53     if (matches) {
54         // onDOMReady is the effective one here. I am leaving the immediate call to
55         // window.scrollTo in case it reduces flicker.
56         window.scrollTo(0, matches[1]);
57         Y.on('domready', function() { window.scrollTo(0, matches[1]); });
59         // And the following horror is necessary to make it work in IE 8.
60         // Note that the class ie8 on body is only there in Moodle 2.0 and OU Moodle.
61         if (YAHOO.util.Dom.hasClass(document.body, 'ie')) {
62             question_force_ie_to_scroll(matches[1])
63         }
64     }
65 }
67 /**
68  * Event handler to stop the quiz form being submitted more than once.
69  * @param e the form submit event.
70  * @param form the form element.
71  */
72 M.core_question_engine.prevent_repeat_submission = function(e, Y) {
73     if (M.core_question_engine.questionformalreadysubmitted) {
74         e.halt();
75         return;
76     }
78     setTimeout(function() {
79         Y.all('input[type=submit]').set('disabled', true);
80     }, 0);
81     M.core_question_engine.questionformalreadysubmitted = true;
82 }
84 /**
85  * Beat IE into submission.
86  * @param targetpos the target scroll position.
87  */
88 M.core_question_engine.force_ie_to_scroll = function(targetpos) {
89     var hackcount = 25;
90     function do_scroll() {
91         window.scrollTo(0, targetpos);
92         hackcount -= 1;
93         if (hackcount > 0) {
94             setTimeout(do_scroll, 10);
95         }
96     }
97     Y.on('load', do_scroll, window);
98 }