From 2fbe5dacb20d19b2b75338d2d6bc9721b20783a6 Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Fri, 24 Mar 2023 18:06:42 +0530 Subject: [PATCH] feat: user input quiz portal form --- lms/lms/doctype/lms_quiz/lms_quiz.py | 16 ++----- lms/public/css/style.css | 27 +++++++++--- lms/templates/quiz.html | 8 ++-- lms/www/batch/learn.js | 31 ++++++++++--- lms/www/batch/quiz.html | 21 +++++++++ lms/www/batch/quiz.js | 65 +++++++++++++++++++--------- lms/www/batch/quiz.py | 3 +- 7 files changed, 123 insertions(+), 48 deletions(-) diff --git a/lms/lms/doctype/lms_quiz/lms_quiz.py b/lms/lms/doctype/lms_quiz/lms_quiz.py index bc158433..f9b4326a 100644 --- a/lms/lms/doctype/lms_quiz/lms_quiz.py +++ b/lms/lms/doctype/lms_quiz/lms_quiz.py @@ -148,17 +148,7 @@ def save_quiz(quiz_title, questions, quiz): } ) - question_doc.update({"question": row["question"], "multiple": row["multiple"]}) - - for num in range(1, 5): - question_doc.update( - { - "option_" + cstr(num): row["option_" + cstr(num)], - "explanation_" + cstr(num): row["explanation_" + cstr(num)], - "is_correct_" + cstr(num): row["is_correct_" + cstr(num)], - } - ) - + question_doc.update(row) question_doc.save(ignore_permissions=True) return doc.name @@ -197,6 +187,8 @@ def check_input_answers(question, answer): "LMS Quiz Question", question, fields, as_dict=1 ) for num in range(1, 5): - if question_details[f"possibility_{num}"] == answer: + current_possibility = question_details[f"possibility_{num}"] + if current_possibility and current_possibility.lower() == answer.lower(): return 1 + return 0 diff --git a/lms/public/css/style.css b/lms/public/css/style.css index d8e6b3aa..26f3cbd2 100644 --- a/lms/public/css/style.css +++ b/lms/public/css/style.css @@ -90,6 +90,7 @@ input[type=checkbox] { padding: 2rem 0 5rem; padding-top: 3rem; background-color: var(--bg-color); + font-size: var(--text-base); } .common-card-style { @@ -425,7 +426,6 @@ input[type=checkbox] { .lesson-links { display: flex; - align-items: center; padding: 0.5rem; color: var(--gray-900); font-size: var(--text-base); @@ -544,10 +544,10 @@ input[type=checkbox] { } .quiz-footer { - display: flex; - align-items: center; - justify-content: space-between; - margin-top: 5rem; + display: flex; + align-items: center; + justify-content: space-between; + margin-top: 2rem; } .question { @@ -1366,7 +1366,7 @@ pre { .question-header { display: flex; align-items: center; - margin-bottom: 2rem; + margin-bottom: 1rem; } .question-number { @@ -2027,3 +2027,18 @@ select { grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); grid-gap: 1.5rem; } + +.answer-indicator { + border-radius: var(--border-radius-md); + padding: 0.2rem 0.5rem; + width: fit-content; + margin-top: 0.5rem; +} + +.answer-indicator.success { + background-color: var(--dark-green-50); +} + +.answer-indicator.failure { + background-color: var(--red-50); +} \ No newline at end of file diff --git a/lms/templates/quiz.html b/lms/templates/quiz.html index a21ac009..c9752953 100644 --- a/lms/templates/quiz.html +++ b/lms/templates/quiz.html @@ -104,19 +104,19 @@ {% endif %} - - + + {% else %} + {% set possible_answer = question["possibility_" + num] %} + +
+ +
+
+
{% if possible_answer %}{{possible_answer}}{% endif %}
+
+
+
+ {% endif %} {% endfor %} {% endfor %} diff --git a/lms/www/batch/quiz.js b/lms/www/batch/quiz.js index 9df71c49..e2065612 100644 --- a/lms/www/batch/quiz.js +++ b/lms/www/batch/quiz.js @@ -93,36 +93,41 @@ const get_questions = () => { let details = {}; let correct_options = 0; + let possibilities = 0; + details["question"] = $(el).find(".question").text(); details["question_name"] = $(el).find(".question").data("question") || ""; + details["type"] = $(el).find(".type").val(); Array.from({ length: 4 }, (x, i) => { let num = i + 1; - details[`option_${num}`] = $(el) - .find(`.option-${num} .option-input:first`) - .text(); - details[`explanation_${num}`] = $(el) - .find(`.option-${num} .option-input:last`) - .text(); + if (details.type == "Choices") { + details[`option_${num}`] = $(el) + .find(`.option-${num} .option-input:first`) + .text(); + details[`explanation_${num}`] = $(el) + .find(`.option-${num} .option-input:last`) + .text(); - let is_correct = $(el) - .find(`.option-${num} .option-checkbox`) - .find("input") - .prop("checked"); - if (is_correct) correct_options += 1; + let is_correct = $(el) + .find(`.option-${num} .option-checkbox`) + .find("input") + .prop("checked"); + if (is_correct) correct_options += 1; - details[`is_correct_${num}`] = is_correct; + details[`is_correct_${num}`] = is_correct; + } else { + let possible_answer = $(el) + .find(`.possibility-${num}`) + .text() + .trim(); + if (possible_answer) possibilities += 1; + details[`possibility_${num}`] = possible_answer; + } }); - - if (!details["option_1"] || !details["option_2"]) - frappe.throw(__("Each question must have at least two options.")); - - if (!correct_options) - frappe.throw( - __("Each question must have at least one correct option.") - ); + validate_mandatory(details, correct_options, possibilities); details["multiple"] = correct_options > 1 ? 1 : 0; questions.push(details); @@ -131,6 +136,26 @@ const get_questions = () => { return questions; }; +const validate_mandatory = (details, correct_options, possibilities) => { + if (details["type"] == "Choices") { + if (!details["option_1"] || !details["option_2"]) + frappe.throw(__("Each question must have at least two options.")); + + if (!correct_options) + frappe.throw( + __( + "Question with choices must have at least one correct option." + ) + ); + } else if (!possibilities) { + frappe.throw( + __( + "Question with user input must have at least one possible answer." + ) + ); + } +}; + const scroll_to_question_container = () => { $([document.documentElement, document.body]).animate( { diff --git a/lms/www/batch/quiz.py b/lms/www/batch/quiz.py index 7db15054..5d687fea 100644 --- a/lms/www/batch/quiz.py +++ b/lms/www/batch/quiz.py @@ -9,11 +9,12 @@ def get_context(context): context.quiz = frappe._dict() context.quiz.edit_mode = 1 else: - fields_arr = ["name", "question"] + fields_arr = ["name", "question", "type"] for num in range(1, 5): fields_arr.append("option_" + cstr(num)) fields_arr.append("is_correct_" + cstr(num)) fields_arr.append("explanation_" + cstr(num)) + fields_arr.append("possibility_" + cstr(num)) context.quiz = frappe.db.get_value("LMS Quiz", quizname, ["title", "name"], as_dict=1) context.quiz.questions = frappe.get_all(