Index: lams_tool_assessment/web/pages/learning/learning.jsp =================================================================== diff -u -r998ba383ec2a06647d309f910ebefe0a33fa30a4 -rca3fa00d5084315963b72ba5db58180fee898754 --- lams_tool_assessment/web/pages/learning/learning.jsp (.../learning.jsp) (revision 998ba383ec2a06647d309f910ebefe0a33fa30a4) +++ lams_tool_assessment/web/pages/learning/learning.jsp (.../learning.jsp) (revision ca3fa00d5084315963b72ba5db58180fee898754) @@ -100,6 +100,8 @@ } }); }); + + initAssessmentTimeLimitWebsocket(); } //autocomplete for VSA @@ -121,160 +123,163 @@ } //boolean to indicate whether ok dialog is still ON so that autosave can't be run - var isWaitingForConfirmation = ${isTimeLimitEnabled && sessionMap.isTimeLimitNotLaunched}; + // var isWaitingForConfirmation = ${isTimeLimitEnabled && sessionMap.isTimeLimitNotLaunched}; + + //timelimit feature - - // websocket needs pinging and reconnection feature in case it fails - // it works pretty much the same as command websocket in Page.tag - var assessmentTimeLimitWebsocketInitTime = null, - assessmentTimeLimitWebsocket = null, - assessmentTimeLimitWebsocketPingTimeout = null, - assessmentTimeLimitWebsocketPingFunc = null, - assessmentTimeLimitWebsocketReconnectAttempts = 0, - counterInitialised = false; + + // websocket needs pinging and reconnection feature in case it fails + // it works pretty much the same as command websocket in Page.tag + var assessmentTimeLimitWebsocketInitTime = null, + assessmentTimeLimitWebsocket = null, + assessmentTimeLimitWebsocketPingTimeout = null, + assessmentTimeLimitWebsocketPingFunc = null, + assessmentTimeLimitWebsocketReconnectAttempts = 0, + counterInitialised = false; + + assessmentTimeLimitWebsocketPingFunc = function(skipPing){ + if (assessmentTimeLimitWebsocket.readyState == assessmentTimeLimitWebsocket.CLOSING + || assessmentTimeLimitWebsocket.readyState == assessmentTimeLimitWebsocket.CLOSED){ + return; + } - assessmentTimeLimitWebsocketPingFunc = function(skipPing){ - if (assessmentTimeLimitWebsocket.readyState == assessmentTimeLimitWebsocket.CLOSING - || assessmentTimeLimitWebsocket.readyState == assessmentTimeLimitWebsocket.CLOSED){ - return; + // check and ping every 3 minutes + assessmentTimeLimitWebsocketPingTimeout = setTimeout(assessmentTimeLimitWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + assessmentTimeLimitWebsocket.send("ping"); + } + }; + + function initAssessmentTimeLimitWebsocket(){ + assessmentTimeLimitWebsocketInitTime = Date.now(); + assessmentTimeLimitWebsocket = new WebSocket(''.replace('http', 'ws') + + 'learningWebsocket?toolContentID=' + ${sessionMap.assessment.contentId}); + + assessmentTimeLimitWebsocket.onclose = function(e){ + // check reason and whether the close did not happen immediately after websocket creation + // (possible access denied, user logged out?) + if (e.code === 1006 && + Date.now() - assessmentTimeLimitWebsocketInitTime > 1000 && + assessmentTimeLimitWebsocketReconnectAttempts < 20) { + assessmentTimeLimitWebsocketReconnectAttempts++; + // maybe iPad went into sleep mode? + // we need this websocket working, so init it again after delay + setTimeout(initAssessmentTimeLimitWebsocket, 3000); } - - // check and ping every 3 minutes - assessmentTimeLimitWebsocketPingTimeout = setTimeout(assessmentTimeLimitWebsocketPingFunc, 3*60*1000); - // initial set up does not send ping - if (!skipPing) { - assessmentTimeLimitWebsocket.send("ping"); - } }; - - function initAssessmentTimeLimitWebsocket(){ - assessmentTimeLimitWebsocketInitTime = Date.now(); - assessmentTimeLimitWebsocket = new WebSocket(''.replace('http', 'ws') - + 'learningWebsocket?toolContentID=' + ${sessionMap.assessment.contentId}); - assessmentTimeLimitWebsocket.onclose = function(e){ - // check reason and whether the close did not happen immediately after websocket creation - // (possible access denied, user logged out?) - if (e.code === 1006 && - Date.now() - assessmentTimeLimitWebsocketInitTime > 1000 && - assessmentTimeLimitWebsocketReconnectAttempts < 20) { - assessmentTimeLimitWebsocketReconnectAttempts++; - // maybe iPad went into sleep mode? - // we need this websocket working, so init it again after delay - setTimeout(initAssessmentTimeLimitWebsocket, 3000); - } - }; - - // set up timer for the first time - assessmentTimeLimitWebsocketPingFunc(true); + // set up timer for the first time + assessmentTimeLimitWebsocketPingFunc(true); + + // when the server pushes new inputs + assessmentTimeLimitWebsocket.onmessage = function(e){ - // when the server pushes new inputs - assessmentTimeLimitWebsocket.onmessage = function(e){ - // read JSON object - var input = JSON.parse(e.data); - - if (input.clearTimer == true) { - // teacher has stopped the timer, destroy it - $('#countdown').countdown('destroy').remove(); - counterInitialised = false; + // read JSON object + var input = JSON.parse(e.data); + + if (input.clearTimer == true) { + // teacher has stopped the timer, destroy it + $('#countdown').countdown('destroy').remove(); + counterInitialised = false; + } else { + // teacher has updated the timer + var secondsLeft = +input.secondsLeft; + if (counterInitialised) { + // just set the new time + $('#countdown').countdown('option', 'until', secondsLeft + 'S'); } else { - // teacher has updated the timer - var secondsLeft = +input.secondsLeft; - if (counterInitialised) { - // just set the new time - $('#countdown').countdown('option', 'until', secondsLeft + 'S'); - } else { - // initialise the timer - displayCountdown(secondsLeft); - } + // initialise the timer + displayCountdown(secondsLeft); } + } - // reset ping timer - clearTimeout(assessmentTimeLimitWebsocketPingTimeout); - assessmentTimeLimitWebsocketPingFunc(true); - }; - } + // reset ping timer + clearTimeout(assessmentTimeLimitWebsocketPingTimeout); + assessmentTimeLimitWebsocketPingFunc(true); + }; + } + + function displayCountdown(secondsLeft){ + counterIntialised = true; + var countdown = '
'; - function displayCountdown(secondsLeft){ - counterIntialised = true; - var countdown = '
'; + $.blockUI({ + message: countdown, + showOverlay: false, + focusInput: false, + css: { + top: '40px', + left: '', + right: '0%', + opacity: '.8', + width: '230px', + cursor: 'default', + border: 'none' + } + }); + + $('#countdown').countdown({ + until: '+' + secondsLeft +'S', + format: 'hMS', + compact: true, + alwaysExpire : true, + onTick: function(periods) { + //check for 30 seconds + if ((periods[4] == 0) && (periods[5] == 0) && (periods[6] <= 30)) { + $('#countdown').css('color', '#FF3333'); + } + }, + onExpiry: function(periods) { + $.blockUI({ message: '

' }); + + setTimeout(function() { + submitAll(true); + }, 4000); + }, + description: "
" + }); + } + + + /* + $(document).ready(function(){ + //show timelimit-start-dialog in order to start countdown + if (${sessionMap.isTimeLimitNotLaunched}) { - $.blockUI({ - message: countdown, - showOverlay: false, - focusInput: false, - css: { - top: '40px', - left: '', - right: '0%', - opacity: '.8', - width: '230px', - cursor: 'default', - border: 'none' - } + $.blockUI({ + message: $('#timelimit-start-dialog'), + css: { width: '325px', height: '120px'}, + overlayCSS: { opacity: '.98'} }); - $('#countdown').countdown({ - until: '+' + secondsLeft +'S', - format: 'hMS', - compact: true, - alwaysExpire : true, - onTick: function(periods) { - //check for 30 seconds - if ((periods[4] == 0) && (periods[5] == 0) && (periods[6] <= 30)) { - $('#countdown').css('color', '#FF3333'); - } - }, - onExpiry: function(periods) { - $.blockUI({ message: '

' }); - - setTimeout(function() { - submitAll(true); - }, 4000); - }, - description: "
" - }); - } + //once OK button pressed start countdown + $('#timelimit-start-ok').click(function() { + + //store date when user has started activity with time limit + $.ajax({ + async: true, + url: '', + data: 'sessionMapID=${sessionMapID}', + type: 'post' + }); + + $.unblockUI(); + initAssessmentTimeLimitWebsocket(); + isWaitingForConfirmation = false; + }); + } else { + initAssessmentTimeLimitWebsocket(); + } + });*/ - $(document).ready(function(){ - //show timelimit-start-dialog in order to start countdown - if (${sessionMap.isTimeLimitNotLaunched}) { - - $.blockUI({ - message: $('#timelimit-start-dialog'), - css: { width: '325px', height: '120px'}, - overlayCSS: { opacity: '.98'} - }); - - //once OK button pressed start countdown - $('#timelimit-start-ok').click(function() { - - //store date when user has started activity with time limit - $.ajax({ - async: true, - url: '', - data: 'sessionMapID=${sessionMapID}', - type: 'post' - }); - - $.unblockUI(); - initAssessmentTimeLimitWebsocket(); - isWaitingForConfirmation = false; - }); - - } else { - initAssessmentTimeLimitWebsocket(); - } - }); -
- //autosave feature function learnerAutosave(){ - if (isWaitingForConfirmation) return; + // if (isWaitingForConfirmation) return; //copy value from CKEditor (only available in essay type of questions) to textarea before ajax submit $("textarea[id^='question']").each(function() {