feat(exam-correct): more stub
This commit is contained in:
parent
0467194e3d
commit
6727dff2ef
@ -1,7 +1,7 @@
|
|||||||
import { Utility } from '../../core/utility';
|
import { Utility } from '../../core/utility';
|
||||||
import { StorageManager, LOCATION } from '../../lib/storage-manager/storage-manager';
|
import { StorageManager, LOCATION } from '../../lib/storage-manager/storage-manager';
|
||||||
|
|
||||||
// import './exam-correct.sass';
|
import './exam-correct.sass';
|
||||||
|
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
|
||||||
@ -12,6 +12,8 @@ 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__participant';
|
||||||
const EXAM_CORRECT_INPUT_BODY_ID = 'exam-correct__new';
|
const EXAM_CORRECT_INPUT_BODY_ID = 'exam-correct__new';
|
||||||
|
|
||||||
|
const INPUT_EMPTY_CLASS = 'input--invalid';
|
||||||
|
|
||||||
|
|
||||||
@Utility({
|
@Utility({
|
||||||
selector: `table[${EXAM_CORRECT_IDENT}]`,
|
selector: `table[${EXAM_CORRECT_IDENT}]`,
|
||||||
@ -51,9 +53,9 @@ export class ExamCorrect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
// TODO work in progress
|
|
||||||
this._sendBtn.removeEventListener('click', this._sendCorrectionHandler);
|
this._sendBtn.removeEventListener('click', this._sendCorrectionHandler);
|
||||||
this._participantInput.removeEventListener('change', this._validateParticipantInput);
|
this._participantInput.removeEventListener('change', this._validateParticipantInput);
|
||||||
|
this._participantInput.removeEventListener('input', this._removeInputEmptyClassHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
_validateParticipantInput(event) {
|
_validateParticipantInput(event) {
|
||||||
@ -63,18 +65,36 @@ export class ExamCorrect {
|
|||||||
_sendCorrectionHandler(event) {
|
_sendCorrectionHandler(event) {
|
||||||
console.log('WIP _sendCorrectionHandler', event);
|
console.log('WIP _sendCorrectionHandler', event);
|
||||||
|
|
||||||
|
// refocus participant input element for convenience
|
||||||
|
this._participantInput.focus();
|
||||||
|
|
||||||
const participant = this._participantInput.value;
|
const participant = this._participantInput.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 });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const results = {};
|
const results = {};
|
||||||
this._partInputs.forEach((input) => {
|
this._partInputs.forEach((input) => {
|
||||||
if (input.value && !isNaN(input.value)) {
|
if (input.value && !isNaN(input.value)) {
|
||||||
|
// TODO instead of ignoring NaN values, abort send and add error class to corresponding input
|
||||||
|
// (latter is optional)
|
||||||
const partKey = input.getAttribute(EXAM_CORRECT_PART_INPUT_ATTR);
|
const partKey = input.getAttribute(EXAM_CORRECT_PART_INPUT_ATTR);
|
||||||
if (!partKey) throw new Error('Exam part input without part attribute!');
|
if (!partKey) throw new Error('Exam part input without part attribute!');
|
||||||
results[partKey] = input.value;
|
results[partKey] = parseFloat(input.value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// abort send if there are no results (after validation)
|
||||||
|
if (results === {}) return;
|
||||||
|
|
||||||
console.log(participant, results);
|
console.log(participant, results);
|
||||||
|
|
||||||
|
// TODO apply row and data classes
|
||||||
|
// (maybe create some sort of template for this instead)
|
||||||
const correctionRow = document.createElement('TR');
|
const correctionRow = document.createElement('TR');
|
||||||
const dateTD = document.createElement('TD');
|
const dateTD = document.createElement('TD');
|
||||||
dateTD.appendChild(document.createTextNode(moment().format()));
|
dateTD.appendChild(document.createTextNode(moment().format()));
|
||||||
@ -91,11 +111,8 @@ export class ExamCorrect {
|
|||||||
const tableBody = this._element.querySelector(`tbody:not(#${EXAM_CORRECT_INPUT_BODY_ID})`);
|
const tableBody = this._element.querySelector(`tbody:not(#${EXAM_CORRECT_INPUT_BODY_ID})`);
|
||||||
tableBody.insertBefore(correctionRow, tableBody.firstChild);
|
tableBody.insertBefore(correctionRow, tableBody.firstChild);
|
||||||
|
|
||||||
this._participantInput.value = null;
|
// clear input values on validation success
|
||||||
console.log(this._partInputs);
|
[this._participantInput, ...this._partInputs].forEach(clearInput);
|
||||||
this._partInputs.forEach((input) => {
|
|
||||||
input.value = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
const url = 'TODO';
|
const url = 'TODO';
|
||||||
const headers = {};
|
const headers = {};
|
||||||
@ -103,6 +120,7 @@ export class ExamCorrect {
|
|||||||
participant: participant,
|
participant: participant,
|
||||||
results: results,
|
results: results,
|
||||||
};
|
};
|
||||||
|
|
||||||
this._app.httpClient.post({
|
this._app.httpClient.post({
|
||||||
url: url,
|
url: url,
|
||||||
headers: headers,
|
headers: headers,
|
||||||
@ -110,13 +128,37 @@ export class ExamCorrect {
|
|||||||
}).then(
|
}).then(
|
||||||
(response) => response.json()
|
(response) => response.json()
|
||||||
).then(
|
).then(
|
||||||
(response) => this._processResponse(response)
|
(response) => this._processResponse(response, participant)
|
||||||
).catch((error) => {
|
).catch((error) => {
|
||||||
// TODO
|
console.error('Error while processing response', error);
|
||||||
console.error('Error while processing response', error, body);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO wait for response and replace status icon accordingly (add edit button to paste content in current input)
|
// TODO wait for response and replace status icon accordingly (add edit button to paste content in current input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_processResponse(response, participant) {
|
||||||
|
console.log('WIP ExamCorrect._processResponse', response, participant);
|
||||||
|
|
||||||
|
// TODO find the first corresponding row (participant matches cell entry in second column) top-down
|
||||||
|
// if found:
|
||||||
|
// if the response status is 'success' (i.e. the results have been upserted into the DB),
|
||||||
|
// replace loading spinner in this row with tick mark icon
|
||||||
|
// otherwise,
|
||||||
|
// replace loading spinner with error icon (error message as tooltip if present?)
|
||||||
|
}
|
||||||
|
|
||||||
|
_removeInputEmptyClassHandler() {
|
||||||
|
console.log('removeclass');
|
||||||
|
if (this._participantInput.value) {
|
||||||
|
this._participantInput.classList.remove(INPUT_EMPTY_CLASS);
|
||||||
|
} else {
|
||||||
|
this._participantInput.addEventListener('input', this._removeInputEmptyClassHandler, { once: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO move to general util section?
|
||||||
|
function clearInput(inputElement) {
|
||||||
|
inputElement.value = null;
|
||||||
}
|
}
|
||||||
|
|||||||
2
frontend/src/utils/exam-correct/exam-correct.sass
Normal file
2
frontend/src/utils/exam-correct/exam-correct.sass
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#exam-correct__participant.input--invalid
|
||||||
|
border: 2px solid var(--color-error)
|
||||||
Loading…
Reference in New Issue
Block a user