Moodle
  1. Moodle
  2. MDL-32064

Quiz navigation does not trigger the quiz on-submit JavaScript

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 2.1.5, 2.2.2
    • Fix Version/s: 2.1.6, 2.2.3
    • Component/s: Quiz
    • Labels:
    • Testing Instructions:
      Hide

      1. Create a quiz with several pages.
      2. Preview it.
      3. Click the next button at the bottom of the first page. Note that the next button immediately disables before the page reloads.
      4. Now click one of the buttons in the quiz navigation block. Verify that disables the buttons in the same way. (This is the bit that used to be broken.)

      Show
      1. Create a quiz with several pages. 2. Preview it. 3. Click the next button at the bottom of the first page. Note that the next button immediately disables before the page reloads. 4. Now click one of the buttons in the quiz navigation block. Verify that disables the buttons in the same way. (This is the bit that used to be broken.)
    • Affected Branches:
      MOODLE_21_STABLE, MOODLE_22_STABLE
    • Fixed Branches:
      MOODLE_21_STABLE, MOODLE_22_STABLE
    • Pull from Repository:
    • Pull Master Branch:

      Description

      The main form on mod/quiz/attempt.php has some on-submit JavaScrit. For example there is some code to prevent double-clicking on the submit button by disabling all submit buttons when the form is submitted.

      When you click on one of the question number buttons in the quiz navigation, it submits the form (currently by calling form.submit()). This does not run the on-submit JavaScript. We need to find another way to write the navigation JavaScript so that it does run the on-submit JavaScript.

        Gliffy Diagrams

          Activity

          Hide
          Tim Hunt added a comment -

          Colin Chambers found the necessary JS to make this work in both standards complient browsers and older versions of IE:

          from http://jehiah.cz/a/firing-javascript-events-properly

          function fireEventById(id,event) {
              element = document.getElementById(id);
              if (!element) {
                  return false;
              }
              return fireEvent(element,event);
          }
           
          function fireEvent(element,event) {
              if (!document.createEventObject) {
                  // dispatch for firefox + others
                  var evt = document.createEvent("HTMLEvents");
                  evt.initEvent(event, true, true); // event type,bubbling,cancelable
                  return !element.dispatchEvent(evt);
              }
              // dispatch for IE
              var evt = document.createEventObject();
              return element.fireEvent('on'+event,evt);
          }
          

          I will now turn this into a fix for Moodle.

          Show
          Tim Hunt added a comment - Colin Chambers found the necessary JS to make this work in both standards complient browsers and older versions of IE: from http://jehiah.cz/a/firing-javascript-events-properly function fireEventById(id,event) { element = document.getElementById(id); if (!element) { return false; } return fireEvent(element,event); }   function fireEvent(element,event) { if (!document.createEventObject) { // dispatch for firefox + others var evt = document.createEvent("HTMLEvents"); evt.initEvent(event, true, true); // event type,bubbling,cancelable return !element.dispatchEvent(evt); } // dispatch for IE var evt = document.createEventObject(); return element.fireEvent('on'+event,evt); } I will now turn this into a fix for Moodle.
          Hide
          Tim Hunt added a comment -

          Acutally, I cannot make the above approach work, so I have gone for an even more horrible approach. Find a submit button in the form, and simulate clicking it.

          Horrible, or not, that does seem to work in all IE7, 8, 9, Chrome and Firefox.

          Show
          Tim Hunt added a comment - Acutally, I cannot make the above approach work, so I have gone for an even more horrible approach. Find a submit button in the form, and simulate clicking it. Horrible, or not, that does seem to work in all IE7, 8, 9, Chrome and Firefox.
          Hide
          Andrew Nicols added a comment -

          +1 from me. I've looked at an issue caused by a similar problem in MDL-32070 and came up with a similar solution.

          Show
          Andrew Nicols added a comment - +1 from me. I've looked at an issue caused by a similar problem in MDL-32070 and came up with a similar solution.
          Hide
          Tim Hunt added a comment -

          Thanks for the review Andrew.

          Show
          Tim Hunt added a comment - Thanks for the review Andrew.
          Hide
          Tim Hunt added a comment -

          The fix failed if the first button in the form was disabled, which can happen in interactive mode.

          I have amended the commit to fix this.

          Show
          Tim Hunt added a comment - The fix failed if the first button in the form was disabled, which can happen in interactive mode. I have amended the commit to fix this.
          Hide
          Sam Hemelryk added a comment -

          Hi Tim,

          I was about to integrate this when I noticed one very minor thing that needs to be clarified/fixed before this gets in.
          What I noticed was that the call to nav_to_page(-1) on line 196, there is a potential bug here should #responseform not be found.
          The nav_to_page function (as well as find_enabled_submit) are only created if it is the form element is found, if it is not found but a.endtestlink is and is clicked you will get an error about undefined function.

          If #responseform is always going to be present then this can go in as it is if you like (although it would be great if the code could be tidied up to either handle the situation or to fail gracefully should #responseform not be found)
          Otherwise if there is a chance #responseform won't be found then certainly it would be great to clean this up now.

          I'll leave it in review for the time being.

          Cheers
          Sam

          Show
          Sam Hemelryk added a comment - Hi Tim, I was about to integrate this when I noticed one very minor thing that needs to be clarified/fixed before this gets in. What I noticed was that the call to nav_to_page(-1) on line 196, there is a potential bug here should #responseform not be found. The nav_to_page function (as well as find_enabled_submit) are only created if it is the form element is found, if it is not found but a.endtestlink is and is clicked you will get an error about undefined function. If #responseform is always going to be present then this can go in as it is if you like (although it would be great if the code could be tidied up to either handle the situation or to fail gracefully should #responseform not be found) Otherwise if there is a chance #responseform won't be found then certainly it would be great to clean this up now. I'll leave it in review for the time being. Cheers Sam
          Hide
          Tim Hunt added a comment -

          #responseform will always be found. Note that this aspect of the code has not changed.

          The old code used to just call form.submit(), which was buggy. The new code is just a more sophisticated way to trigger the form submit via javascript, and the helper functions are only needed if you are doing that.

          Show
          Tim Hunt added a comment - #responseform will always be found. Note that this aspect of the code has not changed. The old code used to just call form.submit(), which was buggy. The new code is just a more sophisticated way to trigger the form submit via javascript, and the helper functions are only needed if you are doing that.
          Hide
          Sam Hemelryk added a comment -

          Cool, given responseform is always going to exist things will run fine and so this has been integrated.

          Show
          Sam Hemelryk added a comment - Cool, given responseform is always going to exist things will run fine and so this has been integrated.
          Hide
          Rajesh Taneja added a comment -

          Works Great
          Thanks for fixing this, Tim.

          Show
          Rajesh Taneja added a comment - Works Great Thanks for fixing this, Tim.
          Hide
          Sam Hemelryk added a comment -

          Congratulations are in order, you've made it, or at least your code has!
          It's now part of Moodle and both the git and cvs repositories have been updated.

          This issue is being marked as fixed and closed.

          Thank you.

          Show
          Sam Hemelryk added a comment - Congratulations are in order, you've made it, or at least your code has! It's now part of Moodle and both the git and cvs repositories have been updated. This issue is being marked as fixed and closed. Thank you.

            People

            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: