diff --git a/frontend/src/utils/exam-correct/exam-correct.js b/frontend/src/utils/exam-correct/exam-correct.js
index 45f967ee7..70a9bdb63 100644
--- a/frontend/src/utils/exam-correct/exam-correct.js
+++ b/frontend/src/utils/exam-correct/exam-correct.js
@@ -9,13 +9,20 @@ import moment from 'moment';
const EXAM_CORRECT_URL_POST = 'correct';
+const EXAM_CORRECT_HEADERS = {
+ 'X-XSRF-TOKEN': Cookies.get('XSRF-TOKEN'),
+ 'Content-Type': HttpClient.ACCEPT.JSON,
+ 'Accept': HttpClient.ACCEPT.JSON,
+};
+
const EXAM_CORRECT_IDENT = 'uw-exam-correct';
const EXAM_CORRECT_PART_INPUT_ATTR = 'uw-exam-correct--part-input';
const EXAM_CORRECT_SEND_BTN_ID = 'exam-correct__send-btn';
-const EXAM_CORRECT_PARTICIPANT_INPUT_ID = 'exam-correct__participant';
+const EXAM_CORRECT_PARTICIPANT_INPUT_ID = 'exam-correct__user';
+const EXAM_CORRECT_USER_INPUT_CANDIDATES_ID = 'exam-correct__user-candidates';
const EXAM_CORRECT_INPUT_BODY_ID = 'exam-correct__new';
-const EXAM_CORRECT_PARTICIPANT_ATTR = 'exam-correct--participant';
+const EXAM_CORRECT_PARTICIPANT_ATTR = 'exam-correct--user';
const INPUT_EMPTY_CLASS = 'input--invalid';
@@ -33,7 +40,8 @@ export class ExamCorrect {
_element;
_sendBtn;
- _participantInput;
+ _userInput;
+ _userInputCandidates;
_partInputs;
constructor(element, app) {
@@ -48,40 +56,65 @@ export class ExamCorrect {
this._element = element;
this._app = app;
this._sendBtn = document.getElementById(EXAM_CORRECT_SEND_BTN_ID);
- this._participantInput = document.getElementById(EXAM_CORRECT_PARTICIPANT_INPUT_ID);
+ this._userInput = document.getElementById(EXAM_CORRECT_PARTICIPANT_INPUT_ID);
+ this._userInputCandidates = document.getElementById(EXAM_CORRECT_USER_INPUT_CANDIDATES_ID);
this._partInputs = [...this._element.querySelectorAll(`input[${EXAM_CORRECT_PART_INPUT_ATTR}]`)];
if (this._sendBtn)
this._sendBtn.addEventListener('click', this._sendCorrectionHandler.bind(this));
else console.error('ExamCorrect utility could not detect send button!');
- if (this._participantInput)
- this._participantInput.addEventListener('focusout', this._validateParticipantInput.bind(this));
- else throw new Error('ExamCorrect utility could not detect participant input!');
+ if (this._userInput)
+ this._userInput.addEventListener('focusout', this._validateUserInput.bind(this));
+ else throw new Error('ExamCorrect utility could not detect user input!');
+
+ if (!this._userInputCandidates) {
+ throw new Error('ExamCorrect utility could not detect user input candidate list!');
+ }
}
destroy() {
this._sendBtn.removeEventListener('click', this._sendCorrectionHandler);
- this._participantInput.removeEventListener('change', this._validateParticipantInput);
- this._participantInput.removeEventListener('input', this._removeInputEmptyClassHandler);
+ this._userInput.removeEventListener('change', this._validateUserInput);
+ this._userInput.removeEventListener('input', this._removeInputEmptyClassHandler);
}
- _validateParticipantInput(event) {
- console.log('WIP _validateParticipantInput', event);
+ _validateUserInput() {
+ const user = this._userInput.value;
+
+ if (!user) return;
+
+ const body = {
+ name: user,
+ results: {},
+ op: false,
+ };
+
+ this._app.httpClient.post({
+ url: EXAM_CORRECT_URL_POST,
+ headers: EXAM_CORRECT_HEADERS,
+ body: JSON.stringify(body),
+ }).then(
+ (response) => response.json()
+ ).then(
+ (response) => this._processResponse(response, user)
+ ).catch((error) => {
+ console.error('Error while validating user input', error);
+ });
}
_sendCorrectionHandler(event) {
console.log('WIP _sendCorrectionHandler', event);
- // refocus participant input element for convenience
- this._participantInput.focus();
+ // refocus user input element for convenience
+ this._userInput.focus();
- const participant = this._participantInput.value;
+ const user = this._userInput.value;
- // abort send if the participant input is empty
- if (!participant) {
- this._participantInput.classList.add(INPUT_EMPTY_CLASS);
- this._participantInput.addEventListener('input', this._removeInputEmptyClassHandler.bind(this), { once: true });
+ // abort send if the user input is empty
+ if (!user) {
+ this._userInput.classList.add(INPUT_EMPTY_CLASS);
+ this._userInput.addEventListener('input', this._removeInputEmptyClassHandler.bind(this), { once: true });
return;
}
@@ -106,9 +139,9 @@ export class ExamCorrect {
const now = moment();
dateTD.appendChild(document.createTextNode(now.format(MOMENT_FORMAT)));
dateTD.setAttribute('date', moment());
- const participantTD = document.createElement('TD');
- participantTD.appendChild(document.createTextNode(participant));
- participantTD.setAttribute(EXAM_CORRECT_PARTICIPANT_ATTR, participant);
+ const userTD = document.createElement('TD');
+ userTD.appendChild(document.createTextNode(user));
+ userTD.setAttribute(EXAM_CORRECT_PARTICIPANT_ATTR, user);
const partTDs = this._partInputs.map((input) => {
const partTD = document.createElement('TD');
const partKey = input.getAttribute(EXAM_CORRECT_PART_INPUT_ATTR);
@@ -120,7 +153,7 @@ export class ExamCorrect {
const statusDiv = document.createElement('DIV');
statusDiv.classList.add('exam-correct--loading');
statusTD.appendChild(statusDiv);
- [dateTD,participantTD,...partTDs, statusTD].forEach((td) => {
+ [dateTD,userTD,...partTDs, statusTD].forEach((td) => {
td.classList.add('table__td');
correctionRow.appendChild(td);
});
@@ -129,41 +162,65 @@ export class ExamCorrect {
// clear input values on validation success
// TODO only clear input on post success
- [this._participantInput, ...this._partInputs].forEach(clearInput);
+ [this._userInput, ...this._partInputs].forEach(clearInput);
- const url = EXAM_CORRECT_URL_POST;
- const headers = {
- 'X-XSRF-TOKEN': Cookies.get('XSRF-TOKEN'),
- 'Content-Type': HttpClient.ACCEPT.JSON,
- 'Accept': HttpClient.ACCEPT.JSON,
- };
const body = {
- name: participant,
+ name: user,
results: results,
op: true,
};
this._app.httpClient.post({
- url: url,
- headers: headers,
+ url: EXAM_CORRECT_URL_POST,
+ headers: EXAM_CORRECT_HEADERS,
body: JSON.stringify(body),
}).then(
(response) => response.json()
).then(
- (response) => this._processResponse(response, participant)
+ (response) => this._processResponse(response, user)
).catch((error) => {
console.error('Error while processing response', error);
});
}
- _processResponse(response, participant) {
- console.log('WIP ExamCorrect._processResponse', response, participant);
-
+ _processResponse(response, user) {
+ console.log('WIP _processResponse', response, user);
+
if (response) {
+ if (response.status === 'no-op') {
+ if (response.users) {
+ // TODO directly replace input value and add attr if list contains only one element
+
+ // TODO add event handler on links -> display name as input value and set id as attribute
+ // TODO how to destroy candidate handlers?
+ response.users.forEach((userCandidate) => {
+ const candidateItem = document.createElement('li');
+ userAsInnerHTML(candidateItem, userCandidate);
+ candidateItem.setAttribute(EXAM_CORRECT_PARTICIPANT_ATTR, userCandidate.id);
+
+ const acceptCandidateHandler = () => {
+ console.log('candidate accepted');
+ this._userInput.value = userCandidate['display-name'] || userCandidate.surname || userCandidate['mat-nr'];
+ this._userInput.setAttribute(EXAM_CORRECT_PARTICIPANT_ATTR, userCandidate.id);
+
+ // remove all candidates
+ while (this._userInputCandidates.firstChild) {
+ this._userInputCandidates.removeChild(this._userInputCandidates.firstChild);
+ }
+ };
+ candidateItem.addEventListener('click', acceptCandidateHandler, { once: true });
+
+ this._userInputCandidates.appendChild(candidateItem);
+ });
+ }
+
+ return;
+ }
+
for (let row of [...this._element.rows]) {
- const participantElem = row.cells.item(1);
- const participantIdent = participantElem && participantElem.getAttribute(EXAM_CORRECT_PARTICIPANT_ATTR);
- if (participantIdent === participant) {
+ const userElem = row.cells.item(1);
+ const userIdent = userElem && userElem.getAttribute(EXAM_CORRECT_PARTICIPANT_ATTR);
+ if (userIdent === user) {
let faIcon, ecClass;
switch (response.status) {
// TODO fetch update time from response and replace
@@ -171,9 +228,9 @@ export class ExamCorrect {
faIcon = 'fa-check';
ecClass = 'exam-correct--success';
if (response.user) {
- participantElem.setAttribute(EXAM_CORRECT_PARTICIPANT_ATTR, response.user.id);
- participantElem.innerHTML = '';
- formatUser(participantElem, response.user);
+ userElem.setAttribute(EXAM_CORRECT_PARTICIPANT_ATTR, response.user.id);
+ userElem.innerHTML = '';
+ userAsInnerHTML(userElem, response.user);
}
// TODO replace results with results from response
// TODO set edit button visibility
@@ -185,7 +242,7 @@ export class ExamCorrect {
ecClass = 'exam-correct--error';
// TODO show users
if (response.users) {
- showUsers(participantElem, response.users);
+ showUsers(userElem, response.users);
}
break;
case 'failure':
@@ -211,10 +268,10 @@ export class ExamCorrect {
_removeInputEmptyClassHandler() {
console.log('removeclass');
- if (this._participantInput.value) {
- this._participantInput.classList.remove(INPUT_EMPTY_CLASS);
+ if (this._userInput.value) {
+ this._userInput.classList.remove(INPUT_EMPTY_CLASS);
} else {
- this._participantInput.addEventListener('input', this._removeInputEmptyClassHandler, { once: true });
+ this._userInput.addEventListener('input', this._removeInputEmptyClassHandler, { once: true });
}
}
@@ -225,7 +282,7 @@ function clearInput(inputElement) {
inputElement.value = null;
}
-function formatUser(elem, user) {
+function userAsInnerHTML(elem, user) {
if (user && user['display-name'] && user['surname']) {
elem.innerHTML += user['display-name'].replace(new RegExp(user['surname']), `${user['surname']}`) + (user['mat-nr'] ? ` (${user['mat-nr']})` : '');
} else {
@@ -238,7 +295,7 @@ function showUsers(elem, users) {
elem.innerHTML = '';
if (users) {
for (const user of users) {
- formatUser(elem, user);
+ userAsInnerHTML(elem, user);
elem.innerHTML += '
';
}
} else {
diff --git a/records.json b/records.json
index 00fdc183c..9e7f6c03d 100644
--- a/records.json
+++ b/records.json
@@ -779,4 +779,4 @@
}
}
]
-}
+}
\ No newline at end of file
diff --git a/templates/exam-correct.hamlet b/templates/exam-correct.hamlet
index ab6645ba5..b825dda09 100644
--- a/templates/exam-correct.hamlet
+++ b/templates/exam-correct.hamlet
@@ -26,7 +26,8 @@ $newline never