feat: lms quizzes
This commit is contained in:
@@ -43,7 +43,7 @@ def save_current_lesson(batch_name, lesson_name):
|
||||
doctype="LMS Batch Membership",
|
||||
filters={
|
||||
"batch": batch_name,
|
||||
"member_email": frappe.session.user
|
||||
"member": frappe.session.user
|
||||
},
|
||||
fieldname="name")
|
||||
if not name:
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
"default": "1",
|
||||
"fieldname": "index_",
|
||||
"fieldtype": "Int",
|
||||
"in_list_view": 1,
|
||||
"label": "Index"
|
||||
},
|
||||
{
|
||||
@@ -56,14 +57,13 @@
|
||||
{
|
||||
"fieldname": "index_label",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Index Label",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2021-06-01 05:30:48.127494",
|
||||
"modified": "2021-06-07 11:58:13.395438",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "Lesson",
|
||||
|
||||
0
community/lms/doctype/lms_option/__init__.py
Normal file
0
community/lms/doctype/lms_option/__init__.py
Normal file
36
community/lms/doctype/lms_option/lms_option.json
Normal file
36
community/lms/doctype/lms_option/lms_option.json
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"actions": [],
|
||||
"creation": "2021-06-07 10:46:10.402684",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"option",
|
||||
"is_correct"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "option",
|
||||
"fieldtype": "Data",
|
||||
"label": "Option"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "is_correct",
|
||||
"fieldtype": "Check",
|
||||
"label": "Is Correct"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-06-07 10:48:45.290227",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Option",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
||||
8
community/lms/doctype/lms_option/lms_option.py
Normal file
8
community/lms/doctype/lms_option/lms_option.py
Normal file
@@ -0,0 +1,8 @@
|
||||
# Copyright (c) 2021, FOSS United and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class LMSOption(Document):
|
||||
pass
|
||||
0
community/lms/doctype/lms_quiz/__init__.py
Normal file
0
community/lms/doctype/lms_quiz/__init__.py
Normal file
8
community/lms/doctype/lms_quiz/lms_quiz.js
Normal file
8
community/lms/doctype/lms_quiz/lms_quiz.js
Normal file
@@ -0,0 +1,8 @@
|
||||
// Copyright (c) 2021, FOSS United and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('LMS Quiz', {
|
||||
// refresh: function(frm) {
|
||||
|
||||
// }
|
||||
});
|
||||
50
community/lms/doctype/lms_quiz/lms_quiz.json
Normal file
50
community/lms/doctype/lms_quiz/lms_quiz.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"actions": [],
|
||||
"autoname": "field:title",
|
||||
"creation": "2021-06-07 10:50:17.893625",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"title",
|
||||
"questions"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "title",
|
||||
"fieldtype": "Data",
|
||||
"label": "Title",
|
||||
"unique": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "questions",
|
||||
"fieldtype": "Table",
|
||||
"label": "Questions",
|
||||
"options": "LMS Quiz Question"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2021-06-07 12:22:37.333289",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Quiz",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
||||
36
community/lms/doctype/lms_quiz/lms_quiz.py
Normal file
36
community/lms/doctype/lms_quiz/lms_quiz.py
Normal file
@@ -0,0 +1,36 @@
|
||||
# Copyright (c) 2021, FOSS United and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
import json
|
||||
|
||||
class LMSQuiz(Document):
|
||||
pass
|
||||
|
||||
@frappe.whitelist()
|
||||
def submit(quiz, result):
|
||||
score = 0
|
||||
result = json.loads(result)
|
||||
quiz_details = frappe.get_doc("LMS Quiz", quiz)
|
||||
print(result, type(result))
|
||||
for response in result:
|
||||
match = list(filter(lambda x: x.question == response.get("question"), quiz_details.questions))[0]
|
||||
response["users_response"] = ("").join([ ans for ans in response.get("answer") ]).replace(" ", ", ")
|
||||
del response["answer"]
|
||||
print(response.get("users_response"), match.answer)
|
||||
if response.get("users_response") == match.answer:
|
||||
response["result"] = "Right"
|
||||
score += 1
|
||||
else:
|
||||
response["result"] = "Wrong"
|
||||
|
||||
frappe.get_doc({
|
||||
"doctype": "LMS Quiz Submission",
|
||||
"quiz": quiz,
|
||||
"result": result,
|
||||
"score": score
|
||||
}).save()
|
||||
return score
|
||||
|
||||
|
||||
8
community/lms/doctype/lms_quiz/test_lms_quiz.py
Normal file
8
community/lms/doctype/lms_quiz/test_lms_quiz.py
Normal file
@@ -0,0 +1,8 @@
|
||||
# Copyright (c) 2021, FOSS United and Contributors
|
||||
# See license.txt
|
||||
|
||||
# import frappe
|
||||
import unittest
|
||||
|
||||
class TestLMSQuiz(unittest.TestCase):
|
||||
pass
|
||||
0
community/lms/doctype/lms_quiz_question/__init__.py
Normal file
0
community/lms/doctype/lms_quiz_question/__init__.py
Normal file
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"actions": [],
|
||||
"creation": "2021-06-07 10:48:57.994714",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"question",
|
||||
"options",
|
||||
"answer",
|
||||
"multiple_correct_answers"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "question",
|
||||
"fieldtype": "Text",
|
||||
"in_list_view": 1,
|
||||
"label": "Question"
|
||||
},
|
||||
{
|
||||
"fieldname": "options",
|
||||
"fieldtype": "Text",
|
||||
"in_list_view": 1,
|
||||
"label": "Options"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "multiple_correct_answers",
|
||||
"fieldtype": "Check",
|
||||
"in_list_view": 1,
|
||||
"label": "Multiple Correct Answers"
|
||||
},
|
||||
{
|
||||
"fieldname": "answer",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Answer"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-06-07 12:47:22.787160",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Quiz Question",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
# Copyright (c) 2021, FOSS United and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class LMSQuizQuestion(Document):
|
||||
pass
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"actions": [],
|
||||
"creation": "2021-06-07 10:48:57.994714",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"question",
|
||||
"options",
|
||||
"multiple_correct_answers"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "question",
|
||||
"fieldtype": "Data",
|
||||
"label": "Question"
|
||||
},
|
||||
{
|
||||
"fieldname": "options",
|
||||
"fieldtype": "Table",
|
||||
"label": "Options",
|
||||
"options": "LMS Option"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "multiple_correct_answers",
|
||||
"fieldtype": "Check",
|
||||
"label": "Multiple Correct Answers"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-06-07 10:48:57.994714",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Quiz Questions",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
# Copyright (c) 2021, FOSS United and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class LMSQuizQuestions(Document):
|
||||
pass
|
||||
0
community/lms/doctype/lms_quiz_result/__init__.py
Normal file
0
community/lms/doctype/lms_quiz_result/__init__.py
Normal file
45
community/lms/doctype/lms_quiz_result/lms_quiz_result.json
Normal file
45
community/lms/doctype/lms_quiz_result/lms_quiz_result.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"actions": [],
|
||||
"creation": "2021-06-07 14:19:23.683323",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"question",
|
||||
"users_response",
|
||||
"result"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "question",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Question"
|
||||
},
|
||||
{
|
||||
"fieldname": "users_response",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Users Response"
|
||||
},
|
||||
{
|
||||
"fieldname": "result",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Result",
|
||||
"options": "Right\nWrong"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-06-07 14:21:07.768039",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Quiz Result",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
||||
8
community/lms/doctype/lms_quiz_result/lms_quiz_result.py
Normal file
8
community/lms/doctype/lms_quiz_result/lms_quiz_result.py
Normal file
@@ -0,0 +1,8 @@
|
||||
# Copyright (c) 2021, FOSS United and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class LMSQuizResult(Document):
|
||||
pass
|
||||
@@ -0,0 +1,8 @@
|
||||
// Copyright (c) 2021, FOSS United and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('LMS Quiz Submission', {
|
||||
// refresh: function(frm) {
|
||||
|
||||
// }
|
||||
});
|
||||
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"actions": [],
|
||||
"creation": "2021-06-07 14:19:54.958989",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"quiz",
|
||||
"result",
|
||||
"score"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "quiz",
|
||||
"fieldtype": "Link",
|
||||
"label": "Quiz",
|
||||
"options": "LMS Quiz"
|
||||
},
|
||||
{
|
||||
"fieldname": "result",
|
||||
"fieldtype": "Table",
|
||||
"label": "Result",
|
||||
"options": "LMS Quiz Result"
|
||||
},
|
||||
{
|
||||
"fieldname": "score",
|
||||
"fieldtype": "Data",
|
||||
"label": "Score"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2021-06-07 14:19:54.958989",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Quiz Submission",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
# Copyright (c) 2021, FOSS United and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class LMSQuizSubmission(Document):
|
||||
pass
|
||||
@@ -0,0 +1,8 @@
|
||||
# Copyright (c) 2021, FOSS United and Contributors
|
||||
# See license.txt
|
||||
|
||||
# import frappe
|
||||
import unittest
|
||||
|
||||
class TestLMSQuizSubmission(unittest.TestCase):
|
||||
pass
|
||||
@@ -14,6 +14,10 @@ class LMSSection(Document):
|
||||
if self.type == "exercise":
|
||||
return frappe.get_doc("Exercise", self.id)
|
||||
|
||||
def get_quiz(self):
|
||||
if self.type == "quiz":
|
||||
return frappe.get_doc("LMS Quiz", self.id)
|
||||
|
||||
def get_latest_code_for_user(self):
|
||||
"""Returns the latest code for the logged in user.
|
||||
"""
|
||||
|
||||
67
community/lms/widgets/Quiz.html
Normal file
67
community/lms/widgets/Quiz.html
Normal file
@@ -0,0 +1,67 @@
|
||||
<h3 id="title">{{ quiz.title }}</h3>
|
||||
<form id="quiz-form">
|
||||
{% for question in quiz.questions %}
|
||||
<div class="question mb-5" data-question="{{ question.question }}"
|
||||
data-multi="{{ question.multiple_correct_answers}}">
|
||||
<p> {{ loop.index }}. {{ question.question }}</p>
|
||||
{% set options = question.options.split(",") %}
|
||||
{% for option in options %}
|
||||
<div class="checkbox">
|
||||
<input {% if question.multiple_correct_answers %} type="checkbox" {% else %} type="radio"
|
||||
name="{{ question.question | urlencode }}" {% endif %} class="option" value="{{ option }}">
|
||||
<span class="label-area">{{ option }}</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
<button class="btn btn-secondary hide mb-5" id="try-again">Try Again</button>
|
||||
<button class="btn btn-primary" id="submit">Submit</button>
|
||||
<h4 class="success-message"></h4>
|
||||
<h5 class="score text-muted"></h5>
|
||||
</form>
|
||||
<script>
|
||||
frappe.ready(() => {
|
||||
$("#submit").click((e) => {
|
||||
e.preventDefault();
|
||||
var result = [];
|
||||
$('.question').each((i, element) => {
|
||||
var options = $(element).find(".option");
|
||||
var answers = [];
|
||||
options.filter((i, op) => $(op).prop("checked")).each((i, elem) => answers.push(elem.value));
|
||||
result.push({
|
||||
"question": element.dataset.question,
|
||||
"answer": answers
|
||||
});
|
||||
});
|
||||
frappe.call({
|
||||
method: "community.lms.doctype.lms_quiz.lms_quiz.submit",
|
||||
args: {
|
||||
quiz: $("#title").text(),
|
||||
result: result
|
||||
},
|
||||
callback: (data) => {
|
||||
$("#submit").addClass("hide");
|
||||
$("#try-again").removeClass("hide");
|
||||
$(":input[type='checkbox']").prop("disabled", true);
|
||||
$(":input[type='radio']").prop("disabled", true);
|
||||
if (data.message == result.length) {
|
||||
$(".success-message").text("Congratulations, you cleared the quiz!");
|
||||
}
|
||||
else {
|
||||
$(".success-message").text("Some of your answers weren't correct. You can give it another shot.");
|
||||
}
|
||||
$(".score").text(`Score: ${data.message}/${result.length}`);
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
$("#try-again").click((e) => {
|
||||
e.preventDefault();
|
||||
$("#quiz-form").trigger("reset");
|
||||
$(".success-message").text("");
|
||||
$(".score").text("");
|
||||
$("#submit").removeClass("hide");
|
||||
$("#try-again").addClass("hide");
|
||||
})
|
||||
})
|
||||
</script>
|
||||
@@ -23,6 +23,7 @@
|
||||
--cta-color: var(--c4);
|
||||
--send-message: var(--c7);
|
||||
--received-message: var(--c8);
|
||||
--checkbox-size: 14px;
|
||||
}
|
||||
|
||||
body {
|
||||
@@ -238,3 +239,7 @@ section {
|
||||
.page-card .btn {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
input[type=checkbox] {
|
||||
appearance: auto;
|
||||
}
|
||||
|
||||
@@ -53,6 +53,8 @@
|
||||
}}
|
||||
{% elif s.type == "exercise" %}
|
||||
{{ widgets.Exercise(exercise=s.get_exercise())}}
|
||||
{% elif s.type == "quiz" %}
|
||||
{{ widgets.Quiz(quiz=s.get_quiz())}}
|
||||
{% else %}
|
||||
<div>Unknown section type: {{s.type}}</div>
|
||||
{% endif %}
|
||||
|
||||
Reference in New Issue
Block a user