diff --git a/frontend/src/utils/exam-correct/exam-correct.js b/frontend/src/utils/exam-correct/exam-correct.js index f3cb8d810..f9ab25fa7 100644 --- a/frontend/src/utils/exam-correct/exam-correct.js +++ b/frontend/src/utils/exam-correct/exam-correct.js @@ -1,8 +1,17 @@ import { Utility } from '../../core/utility'; import { StorageManager, LOCATION } from '../../lib/storage-manager/storage-manager'; + // import './exam-correct.sass'; +import moment from 'moment'; + + 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_INPUT_BODY_ID = 'exam-correct__new'; + @Utility({ selector: `table[${EXAM_CORRECT_IDENT}]`, @@ -13,17 +22,101 @@ export class ExamCorrect { _element; - constructor(element) { + _sendBtn; + _participantInput; + _partInputs; + + constructor(element, app) { if (!element) { throw new Error('Exam Correct utility cannot be setup without an element!'); } - this._element = element; + if (!app) { + throw new Error('Exam Correct utility cannot be setup without an app!'); + } + 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._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!'); } destroy() { - console.log('TBD: destroy ExamCorrect'); + // TODO work in progress + this._sendBtn.removeEventListener('click', this._sendCorrectionHandler); + this._participantInput.removeEventListener('change', this._validateParticipantInput); + } + + _validateParticipantInput(event) { + console.log('WIP _validateParticipantInput', event); + } + + _sendCorrectionHandler(event) { + console.log('WIP _sendCorrectionHandler', event); + + const participant = this._participantInput.value; + const results = {}; + this._partInputs.forEach((input) => { + if (input.value && !isNaN(input.value)) { + const partKey = input.getAttribute(EXAM_CORRECT_PART_INPUT_ATTR); + if (!partKey) throw new Error('Exam part input without part attribute!'); + results[partKey] = input.value; + } + }); + + console.log(participant, results); + + const correctionRow = document.createElement('TR'); + const dateTD = document.createElement('TD'); + dateTD.appendChild(document.createTextNode(moment().format())); + const participantTD = document.createElement('TD'); + participantTD.appendChild(document.createTextNode(participant)); + const partTDs = this._partInputs.map((input) => { + const partTD = document.createElement('TD'); + const partKey = input.getAttribute(EXAM_CORRECT_PART_INPUT_ATTR); + if (results[partKey]) + partTD.appendChild(document.createTextNode(results[partKey])); + return partTD; + }); + [dateTD,participantTD,...partTDs].forEach((td) => correctionRow.appendChild(td)); + const tableBody = this._element.querySelector(`tbody:not(#${EXAM_CORRECT_INPUT_BODY_ID})`); + tableBody.insertBefore(correctionRow, tableBody.firstChild); + + this._participantInput.value = null; + console.log(this._partInputs); + this._partInputs.forEach((input) => { + input.value = null; + }); + + const url = 'TODO'; + const headers = {}; + const body = { + participant: participant, + results: results, + }; + this._app.httpClient.post({ + url: url, + headers: headers, + body: body, + }).then( + (response) => response.json() + ).then( + (response) => this._processResponse(response) + ).catch((error) => { + // TODO + 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) } } diff --git a/src/Handler/Exam/Correct.hs b/src/Handler/Exam/Correct.hs index 241ee642b..aef3dd55d 100644 --- a/src/Handler/Exam/Correct.hs +++ b/src/Handler/Exam/Correct.hs @@ -54,7 +54,7 @@ getECorrectR tid ssh csh examn = do ptsInput :: ExamPartNumber -> Widget ptsInput n = do name <- newIdent - fieldView (pointsField :: Field Handler Points) ("exam-correct__" <> toPathPiece n) name [("class","exam-correct__pts-input")] (Left "") False + fieldView (pointsField :: Field Handler Points) ("exam-correct__" <> toPathPiece n) name [("uw-exam-correct--part-input", toPathPiece n)] (Left "") False participantHeadTooltip = [whamlet| _{MsgExamCorrectHeadParticipantTooltip} |] diff --git a/templates/exam-correct.hamlet b/templates/exam-correct.hamlet index 9d0038cf2..ab6645ba5 100644 --- a/templates/exam-correct.hamlet +++ b/templates/exam-correct.hamlet @@ -22,7 +22,7 @@ $newline never _{MsgExamCorrectHeadPart examPartNumber}