Version19.238.3

This commit is contained in:
acanas 2020-05-19 15:17:52 +02:00
parent 4012b22789
commit 0d4d513866
4 changed files with 120 additions and 54 deletions

View File

@ -550,15 +550,16 @@ function readConnUsrsData () {
/*****************************************************************************/
// This function is called when user changes an answer in an exam print
function updateExamPrint (idDiv,idInput,nameInput,Params) {
function updateExamPrint (idDiv,idInput,nameInput,Params,timeoutMsg) {
var objXMLHttp = false;
objXMLHttp = AJAXCreateObject ();
if (objXMLHttp) {
/* Send request to server */
objXMLHttp.onreadystatechange = function() { // onreadystatechange must be lowercase
if (objXMLHttp.readyState == 4) // Check if data have been received
if (objXMLHttp.status == 200)
if (objXMLHttp.readyState == 4) { // Check if data have been received
if (objXMLHttp.status == 200) {
clearTimeout (xmlHttpTimeout); // Response received ==> clear timeout
if (idDiv) {
var div = document.getElementById(idDiv); // Access to DIV
if (div) {
@ -572,6 +573,8 @@ function updateExamPrint (idDiv,idInput,nameInput,Params) {
MathJax.typeset();
}
}
}
}
};
var inputElem = document.getElementById(idInput);
@ -606,6 +609,16 @@ function updateExamPrint (idDiv,idInput,nameInput,Params) {
objXMLHttp.open('POST',ActionAJAX,true);
objXMLHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
objXMLHttp.send(Params);
/* Timeout to abort in 5 seconds.
See https://stackoverflow.com/questions/1018705/how-to-detect-timeout-on-an-ajax-xmlhttprequest-call-in-the-browser
and http://geekswithblogs.net/lorint/archive/2006/03/07/71625.aspx
"ontimeout" based solutions does not work when network disconnects */
var xmlHttpTimeout = setTimeout (ajaxTimeout,5000); // 5 s
function ajaxTimeout () {
objXMLHttp.abort ();
alert (timeoutMsg);
};
}
}

View File

@ -557,10 +557,11 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - *
En OpenSWAD:
ps2pdf source.ps destination.pdf
*/
#define Log_PLATFORM_VERSION "SWAD 19.238.2 (2020-05-18)"
#define Log_PLATFORM_VERSION "SWAD 19.238.3 (2020-05-19)"
#define CSS_FILE "swad19.238.2.css"
#define JS_FILE "swad19.236.4.js"
#define JS_FILE "swad19.238.3.js"
/*
Version 19.238.3: May 19, 2020 Fixed issue due to network timeout while answering exams. Reported by Nuria Torres Rosell. (301316 lines)
Version 19.238.2: May 19, 2020 Exam description is written in exam heading. Suggested by Eva Martínez Ortigosa. (301254 lines)
Version 19.238.1: May 19, 2020 Fixed bug: clicks on answers of exam prints are logged. (301566 lines)
Version 19.238: May 18, 2020 Fix exam-related details.

View File

@ -86,17 +86,22 @@ static void ExaPrn_WriteQstAndAnsToFill (const struct ExaPrn_Print *Print,
static void ExaPrn_WriteAnswersToFill (const struct ExaPrn_Print *Print,
unsigned NumQst,
const struct Tst_Question *Question);
//-----------------------------------------------------------------------------
static void ExaPrn_WriteIntAnsToFill (const struct ExaPrn_Print *Print,
unsigned NumQst);
static void ExaPrn_WriteFloatAnsToFill (const struct ExaPrn_Print *Print,
unsigned NumQst);
static void ExaPrn_WriteTFAnsToFill (const struct ExaPrn_Print *Print,
unsigned NumQst);
static void ExaPrn_WriteChoiceAnsToFill (const struct ExaPrn_Print *Print,
unsigned NumQst,
const struct Tst_Question *Question);
static void ExaPrn_WriteTextAnsToFill (const struct ExaPrn_Print *Print,
unsigned NumQst);
static void ExaPrn_WriteFloAnsToFill (const struct ExaPrn_Print *Print,
unsigned NumQst);
static void ExaPrn_WriteTF_AnsToFill (const struct ExaPrn_Print *Print,
unsigned NumQst);
static void ExaPrn_WriteChoAnsToFill (const struct ExaPrn_Print *Print,
unsigned NumQst,
const struct Tst_Question *Question);
static void ExaPrn_WriteTxtAnsToFill (const struct ExaPrn_Print *Print,
unsigned NumQst);
//-----------------------------------------------------------------------------
static void ExaPrn_WriteJSToUpdateExamPrint (const struct ExaPrn_Print *Print,
unsigned NumQst,
const char *Id,int NumOpt);
static unsigned ExaPrn_GetAnswerFromForm (struct ExaPrn_Print *Print);
@ -736,17 +741,17 @@ static void ExaPrn_WriteAnswersToFill (const struct ExaPrn_Print *Print,
ExaPrn_WriteIntAnsToFill (Print,NumQst);
break;
case Tst_ANS_FLOAT:
ExaPrn_WriteFloatAnsToFill (Print,NumQst);
ExaPrn_WriteFloAnsToFill (Print,NumQst);
break;
case Tst_ANS_TRUE_FALSE:
ExaPrn_WriteTFAnsToFill (Print,NumQst);
ExaPrn_WriteTF_AnsToFill (Print,NumQst);
break;
case Tst_ANS_UNIQUE_CHOICE:
case Tst_ANS_MULTIPLE_CHOICE:
ExaPrn_WriteChoiceAnsToFill (Print,NumQst,Question);
ExaPrn_WriteChoAnsToFill (Print,NumQst,Question);
break;
case Tst_ANS_TEXT:
ExaPrn_WriteTextAnsToFill (Print,NumQst);
ExaPrn_WriteTxtAnsToFill (Print,NumQst);
break;
default:
break;
@ -770,19 +775,16 @@ static void ExaPrn_WriteIntAnsToFill (const struct ExaPrn_Print *Print,
" size=\"11\" maxlength=\"11\" value=\"%s\"",
Id,
Print->PrintedQuestions[NumQst].StrAnswers);
HTM_TxtF (" onchange=\"updateExamPrint('examprint','%s','Ans',"
"'act=%ld&ses=%s&SesCod=%ld&NumQst=%u');"
" return false;\" />", // return false is necessary to not submit form
Id,
Act_GetActCod (ActAnsExaPrn),Gbl.Session.Id,Print->SesCod,NumQst);
ExaPrn_WriteJSToUpdateExamPrint (Print,NumQst,Id,-1);
HTM_Txt (" />");
}
/*****************************************************************************/
/****************** Write float answer when seeing a test ********************/
/*****************************************************************************/
static void ExaPrn_WriteFloatAnsToFill (const struct ExaPrn_Print *Print,
unsigned NumQst)
static void ExaPrn_WriteFloAnsToFill (const struct ExaPrn_Print *Print,
unsigned NumQst)
{
char Id[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Ansxx...x"
@ -794,19 +796,16 @@ static void ExaPrn_WriteFloatAnsToFill (const struct ExaPrn_Print *Print,
" size=\"11\" maxlength=\"%u\" value=\"%s\"",
Id,Tst_MAX_BYTES_FLOAT_ANSWER,
Print->PrintedQuestions[NumQst].StrAnswers);
HTM_TxtF (" onchange=\"updateExamPrint('examprint','%s','Ans',"
"'act=%ld&ses=%s&SesCod=%ld&NumQst=%u');"
" return false;\" />", // return false is necessary to not submit form
Id,
Act_GetActCod (ActAnsExaPrn),Gbl.Session.Id,Print->SesCod,NumQst);
ExaPrn_WriteJSToUpdateExamPrint (Print,NumQst,Id,-1);
HTM_Txt (" />");
}
/*****************************************************************************/
/************** Write false / true answer when seeing a test ****************/
/*****************************************************************************/
static void ExaPrn_WriteTFAnsToFill (const struct ExaPrn_Print *Print,
unsigned NumQst)
static void ExaPrn_WriteTF_AnsToFill (const struct ExaPrn_Print *Print,
unsigned NumQst)
{
extern const char *Txt_TF_QST[2];
char Id[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Ansxx...x"
@ -819,12 +818,8 @@ static void ExaPrn_WriteTFAnsToFill (const struct ExaPrn_Print *Print,
"Ans%010u",
NumQst);
HTM_TxtF ("<select id=\"%s\" name=\"Ans\"",Id);
HTM_TxtF (" onchange=\"updateExamPrint('examprint','%s','Ans',"
"'act=%ld&ses=%s&SesCod=%ld&NumQst=%u');"
" return false;\" />", // return false is necessary to not submit form
Id,
Act_GetActCod (ActAnsExaPrn),
Gbl.Session.Id,Print->SesCod,NumQst);
ExaPrn_WriteJSToUpdateExamPrint (Print,NumQst,Id,-1);
HTM_Txt (" />");
HTM_OPTION (HTM_Type_STRING,"" ,Print->PrintedQuestions[NumQst].StrAnswers[0] == '\0',false,"&nbsp;");
HTM_OPTION (HTM_Type_STRING,"T",Print->PrintedQuestions[NumQst].StrAnswers[0] == 'T' ,false,"%s",Txt_TF_QST[0]);
HTM_OPTION (HTM_Type_STRING,"F",Print->PrintedQuestions[NumQst].StrAnswers[0] == 'F' ,false,"%s",Txt_TF_QST[1]);
@ -835,9 +830,9 @@ static void ExaPrn_WriteTFAnsToFill (const struct ExaPrn_Print *Print,
/******** Write single or multiple choice answer when seeing a test **********/
/*****************************************************************************/
static void ExaPrn_WriteChoiceAnsToFill (const struct ExaPrn_Print *Print,
unsigned NumQst,
const struct Tst_Question *Question)
static void ExaPrn_WriteChoAnsToFill (const struct ExaPrn_Print *Print,
unsigned NumQst,
const struct Tst_Question *Question)
{
unsigned NumOpt;
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]; // Indexes of all answers of this question
@ -866,7 +861,6 @@ static void ExaPrn_WriteChoiceAnsToFill (const struct ExaPrn_Print *Print,
If the user does not confirm the submission of their exam ==>
==> the exam may be half filled ==> the answers displayed will be those selected by the user. */
HTM_TD_Begin ("class=\"LT\"");
snprintf (Id,sizeof (Id),
"Ans%010u",
NumQst);
@ -876,11 +870,8 @@ static void ExaPrn_WriteChoiceAnsToFill (const struct ExaPrn_Print *Print,
Id,NumOpt,Indexes[NumOpt],
UsrAnswers[Indexes[NumOpt]] ? " checked=\"checked\"" :
"");
HTM_TxtF (" onclick=\"updateExamPrint('examprint','%s_%u','Ans',"
"'act=%ld&ses=%s&SesCod=%ld&NumQst=%u');"
" return false;\" />", // return false is necessary to not submit form
Id,NumOpt,
Act_GetActCod (ActAnsExaPrn),Gbl.Session.Id,Print->SesCod,NumQst);
ExaPrn_WriteJSToUpdateExamPrint (Print,NumQst,Id,(int) NumOpt);
HTM_Txt (" />");
HTM_TD_End ();
HTM_TD_Begin ("class=\"LT\"");
@ -910,8 +901,8 @@ static void ExaPrn_WriteChoiceAnsToFill (const struct ExaPrn_Print *Print,
/******************** Write text answer when seeing a test *******************/
/*****************************************************************************/
static void ExaPrn_WriteTextAnsToFill (const struct ExaPrn_Print *Print,
unsigned NumQst)
static void ExaPrn_WriteTxtAnsToFill (const struct ExaPrn_Print *Print,
unsigned NumQst)
{
char Id[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Ansxx...x"
@ -923,11 +914,33 @@ static void ExaPrn_WriteTextAnsToFill (const struct ExaPrn_Print *Print,
" size=\"40\" maxlength=\"%u\" value=\"%s\"",
Id,Tst_MAX_CHARS_ANSWERS_ONE_QST,
Print->PrintedQuestions[NumQst].StrAnswers);
HTM_TxtF (" onchange=\"updateExamPrint('examprint','%s','Ans',"
"'act=%ld&ses=%s&SesCod=%ld&NumQst=%u');"
" return false;\" />", // return false is necessary to not submit form
Id,
Act_GetActCod (ActAnsExaPrn),Gbl.Session.Id,Print->SesCod,NumQst);
ExaPrn_WriteJSToUpdateExamPrint (Print,NumQst,Id,-1);
HTM_Txt (" />");
}
/*****************************************************************************/
/********************** Receive answer to an exam print **********************/
/*****************************************************************************/
static void ExaPrn_WriteJSToUpdateExamPrint (const struct ExaPrn_Print *Print,
unsigned NumQst,
const char *Id,int NumOpt)
{
extern const char *Txt_The_changes_have_not_been_saved_;
if (NumOpt < 0)
HTM_TxtF (" onchange=\"updateExamPrint('examprint','%s','Ans',"
"'act=%ld&ses=%s&SesCod=%ld&NumQst=%u','%s');",
Id,
Act_GetActCod (ActAnsExaPrn),Gbl.Session.Id,Print->SesCod,NumQst,
Txt_The_changes_have_not_been_saved_);
else // NumOpt >= 0
HTM_TxtF (" onclick=\"updateExamPrint('examprint','%s_%d','Ans',"
"'act=%ld&ses=%s&SesCod=%ld&NumQst=%u','%s');",
Id,NumOpt,
Act_GetActCod (ActAnsExaPrn),Gbl.Session.Id,Print->SesCod,NumQst,
Txt_The_changes_have_not_been_saved_);
HTM_Txt (" return false;\""); // return false is necessary to not submit form
}
/*****************************************************************************/

View File

@ -46312,6 +46312,45 @@ const char *Txt_The_centre_X_has_been_renamed_as_Y = // Warning: it is very impo
"O centro <strong>%s</strong> foi renomeado como <strong>%s</strong>.";
#endif
const char *Txt_The_changes_have_not_been_saved_ =
#if L==1 // ca
"Els canvis no s'han desat."
" &Eacute;s possible que el servidor estigui trigant a respondre"
" o que hi hagi problemes en la connexi&oacute; de xarxa.";
#elif L==2 // de
"Die &Auml;nderungen wurden nicht gespeichert."
" Der Server reagiert m&ouml;glicherweise nur langsam"
" oder es treten Probleme mit Ihrer Netzwerkverbindung auf.";
#elif L==3 // en
"The changes have not been saved."
" The server may be slow to respond"
" or there may be problems with your network connection.";
#elif L==4 // es
"Los cambios no se han guardado."
" Es posible que el servidor est&eacute; tardando en responder"
" o que haya problemas en la conexi&oacute;n de red.";
#elif L==5 // fr
"Les modifications n'ont pas &eacute;t&eacute; enregistr&eacute;es."
" Le serveur peut &ecirc;tre lent &agrave; r&eacute;pondre"
" ou il peut y avoir des probl&egrave;mes avec votre connexion r&eacute;seau.";
#elif L==6 // gn
"Los cambios no se han guardado."
" Es posible que el servidor est&eacute; tardando en responder"
" o que haya problemas en la conexi&oacute;n de red."; // Okoteve traducción
#elif L==7 // it
"Le modifiche non sono state salvate."
" Il server potrebbe rispondere lentamente"
" o potrebbero esserci problemi con la connessione di rete.";
#elif L==8 // pl
"Zmiany nie zosta&lstrok;y zapisane."
" Serwer mo&zdot;e d&lstrok;ugo reagowa&cacute;"
" lub mog&aogon; wyst&eogon;powa&cacute; problemy z po&lstrok;&atrok;czeniem sieciowym.";
#elif L==9 // pt
"As altera&ccedil;&otilde;es n&atilde;o foram salvas."
" O servidor pode demorar para responder"
" ou pode haver problemas com sua conex&atilde;o de rede.";
#endif
const char *Txt_The_comment_no_longer_exists =
#if L==1 // ca
"El comentari ja no existeix.";