This commit is contained in:
Ross
2021-07-07 17:08:45 +01:00
parent 26b110d278
commit 70e0f60f61
4 changed files with 167 additions and 93 deletions
+1
View File
@@ -60,6 +60,7 @@ urlpatterns = [
path("feedback/note/<int:pk>/complete", views.feedback_mark_complete, name="feedback_mark_complete"), path("feedback/note/<int:pk>/complete", views.feedback_mark_complete, name="feedback_mark_complete"),
#path("feedback/", views.AddQuestionNote.as_view(), name="feedback"), #path("feedback/", views.AddQuestionNote.as_view(), name="feedback"),
path("feedback/answer", views.answer_suggestion_submit, name="answer_suggestion_submit"), path("feedback/answer", views.answer_suggestion_submit, name="answer_suggestion_submit"),
path("feedback/answer_submit", views.answer_submit, name="answer_submit"),
path("feedback/answer/confirm", views.answer_suggestion_confirm, name="answer_suggestion_confirm"), path("feedback/answer/confirm", views.answer_suggestion_confirm, name="answer_suggestion_confirm"),
path("feedback/view", views.view_feedback, name="view_feedback"), path("feedback/view", views.view_feedback, name="view_feedback"),
+31
View File
@@ -248,6 +248,37 @@ def answer_suggestion_submit(request):
# postExamAnswers # postExamAnswers
return JsonResponse({"success": False, "error": "Invalid data"}) return JsonResponse({"success": False, "error": "Invalid data"})
@login_required
def answer_submit(request):
if request.is_ajax and request.method == "POST":
post_data = json.loads(request.body)
qid = post_data["qid"]
question_type = post_data["question_type"]
answer_string = post_data["answer"]
status = post_data["status"]
if str(status) not in "012":
return JsonResponse({"success": False, "error": "Invalid status"})
if question_type == "anatomy":
AnswerModel = AnatomyAnswer
question = AnatomyQuestion
elif question_type == "rapid":
AnswerModel = RapidAnswer
question = Rapid
else:
return JsonResponse({"success": False, "error": "Invalid question type"})
q = get_object_or_404(question, pk=qid)
if AnswerModel.objects.filter(answer=answer_string, question=q):
return JsonResponse({"success": False, "error": "Answer already exists"})
a = AnswerModel(question=q, answer=answer_string, status=status)
a.save()
return JsonResponse({"success": False, "error": "Invalid data"})
@login_required @login_required
def answer_suggestion_confirm(request): def answer_suggestion_confirm(request):
if request.is_ajax and request.method == "POST": if request.is_ajax and request.method == "POST":
+1
View File
@@ -312,6 +312,7 @@ class Rapid(models.Model):
for r in self.region.all(): for r in self.region.all():
for a in self.abnormality.all(): for a in self.abnormality.all():
answers.append("{} {}".format(r.name, a.name)) answers.append("{} {}".format(r.name, a.name))
answers.append("{} {}".format(a.name, r.name))
compare_answers = self.get_compare_answers() compare_answers = self.get_compare_answers()
@@ -8,17 +8,18 @@
<p class="pre-whitespace"><b>Examination:</b> {{ question.get_examinations }}</p> <p class="pre-whitespace"><b>Examination:</b> {{ question.get_examinations }}</p>
<p class="pre-whitespace"><b>Laterality:</b> {{ question.laterality }}</p> <p class="pre-whitespace"><b>Laterality:</b> {{ question.laterality }}</p>
<p class="pre-whitespace"><b>Abnormality:</b> {{ question.get_abnormalities }}</p> <p class="pre-whitespace"><b>Abnormality:</b> {{ question.get_abnormalities }}</p>
<div class="pre-whitespace multi-image-block"><b>Images:</b> <div class="pre-whitespace multi-image-block"><b>Images:</b>
{% for image in question.images.all %} {% for image in question.images.all %}
<span class="image-block"> <span class="image-block">
Image {{ forloop.counter }}{% if image.feedback_image %} [feedback image]{% endif %}: Image {{ forloop.counter }}{% if image.feedback_image %} [feedback image]{% endif %}:
<div class="dicom-image rapid-img {% if image.feedback_image %}feedback-img{% endif %}" data-url="https://penracourses.org.uk{{ image.image.url}}"></div> <div class="dicom-image rapid-img {% if image.feedback_image %}feedback-img{% endif %}"
data-url="https://penracourses.org.uk{{ image.image.url}}"></div>
</span> </span>
{% endfor %} {% endfor %}
</div> </div>
<div> <div>
Exams: {% for exam in question.exams.all %} Exams: {% for exam in question.exams.all %}
<a href="{% url 'rapids:exam_overview' pk=exam.pk %}">{{ exam.name }}</a>, <a href="{% url 'rapids:exam_overview' pk=exam.pk %}">{{ exam.name }}</a>,
{% endfor %} {% endfor %}
</div> </div>
<p class="pre-whitespace"><b>Open Access:</b> {{ question.open_access }}</p> <p class="pre-whitespace"><b>Open Access:</b> {{ question.open_access }}</p>
@@ -29,15 +30,16 @@
href="{% url 'rapids:verified_detail' pk=verified.pk %}">{{verified}}</a>, {% endfor %}</p> href="{% url 'rapids:verified_detail' pk=verified.pk %}">{{verified}}</a>, {% endfor %}</p>
<p><b>Scrapped:</b> {{ question.scrapped }} <a href="{% url 'rapids:rapid_scrap' pk=question.pk %}">(toggle)</a> <p><b>Scrapped:</b> {{ question.scrapped }} <a href="{% url 'rapids:rapid_scrap' pk=question.pk %}">(toggle)</a>
<p class="pre-whitespace"> <p class="pre-whitespace">
Answers (score): {% for answer in question.answers.all %} Answers (score): {% for answer in question.answers.all %}
<span {% if answer.proposed %}class="proposed-answer" data-aid="{{answer.pk}}" data-question-type="rapid" {% endif %}> <span {% if answer.proposed %}class="proposed-answer" data-aid="{{answer.pk}}" data-question-type="rapid" {%
{{ answer }} ({{answer.status}}), endif %}>
</span> {{ answer }} ({{answer.status}}),
{% endfor %} </span>
{% endfor %}
</p> </p>
</div> </div>
<div> <div>
{% if view_feedback %} {% if view_feedback %}
Notes: Notes:
<ul> <ul>
@@ -51,97 +53,136 @@
<ul class="notes"> <ul class="notes">
{% for note in question.anon_notes.all %} {% for note in question.anon_notes.all %}
<li {% if note.complete %}class='complete' {% endif %}> <li {% if note.complete %}class='complete' {% endif %}>
{{ note.created_on }} by {{ note.author }}: {{note.note_type}} / {{ note.note }} {{ note.created_on }} by {{ note.author }}: {{note.note_type}} / {{ note.note }}
{% if not note.complete %} {% if not note.complete %}
(<a href="{% url 'feedback_mark_complete' pk=note.pk %}">Mark complete</a>) (<a href="{% url 'feedback_mark_complete' pk=note.pk %}">Mark complete</a>)
{% endif %} {% endif %}
</li> </li>
{% endfor %} {% endfor %}
</ul> </ul>
{% endif %} {% endif %}
<detail> <details>
<summary><h3>Suggested answers</h3></summary> <summary>
<ul> <h3>Suggested answers</h3>
{% for ans in question.get_suggested_answers %} </summary>
<li>{{ans}}</li> <ul class="suggested_answers">
{% endfor %} {% for ans in question.get_suggested_answers %}
<li data-string="{{ans}}">{{ans}}</li>
{% endfor %}
</ul> </ul>
</div>
</details>
<details>
<summary>
<h3>Image viewer</h3>
</summary>
<div id="single-dicom-viewer" class="dicom-viewer" data-images="{{ question.get_image_urls }}" data-annotations=''>
</div> </div>
</detail> </detail>
<detail> <script>
<summary><h3>Image viewer</h3></summary> $(document).ready(function () {
<div id="single-dicom-viewer" class="dicom-viewer" data-images="{{ question.get_image_urls }}" data-annotations=''></div>
</div>
</detail>
<script> $(".suggested_answers li").each((n, el) => {
$(document).ready(function () { $(el).append($("<span class='confirm'>[Correct]</span>").on("click", function () {
// send request to change the is_private state on customSwitches toggle $.ajax({
$(".proposed-answer").each((n, el) => { url: "{% url 'answer_submit' %}",
data: {
// Add button to confirm answer is correct csrfmiddlewaretoken: "{{ csrf_token }}",
$(el).append($("<span class='confirm'>[Correct]</span>").on("click", function () { //active: this.checked // true if checked else false
$.ajax({ question_type: "rapid",
url: "{% url 'answer_suggestion_confirm' %}", qid: "{{question.pk}}",
data: { status: 2,
csrfmiddlewaretoken: "{{ csrf_token }}", answer: el.dataset.string,
//active: this.checked // true if checked else false },
question_type: "rapid", type: "POST",
aid: el.dataset.aid, dataType: "json",
status: 2, })
}, // $.ajax().done(), $.ajax().fail(), $ajax().always() are upto you. Add/change accordingly
type: "POST", .done(function (data) {
dataType: "json", console.log(data);
})
// $.ajax().done(), $.ajax().fail(), $ajax().always() are upto you. Add/change accordingly
.done(function (data) {
console.log(data);
if (data.success) { if (data.success) {
toastr.info('Answer saved') toastr.info('Answer saved')
$(el).find(".confirm").remove() $(el).find(".confirm").remove()
$(el).removeClass("proposed-answer") $(el).removeClass("proposed-answer")
} }
// show some message according to the response. // show some message according to the response.
// For eg. A message box showing that the status has been changed // For eg. A message box showing that the status has been changed
}) })
.always(function () { .always(function () {
console.log('[Done]'); console.log('[Done]');
}) })
})) }))
// Add button to confirm answer is incorrect });
$(el).append($("<span class='confirm'>[Incorrect]</span>").on("click", function () {
$.ajax({
url: "{% url 'answer_suggestion_confirm' %}",
data: {
csrfmiddlewaretoken: "{{ csrf_token }}",
//active: this.checked // true if checked else false
question_type: "rapid",
aid: el.dataset.aid,
status: 0,
},
type: "POST",
dataType: "json",
})
// $.ajax().done(), $.ajax().fail(), $ajax().always() are upto you. Add/change accordingly
.done(function (data) {
console.log(data);
if (data.success) { // send request to change the is_private state on customSwitches toggle
toastr.info('Answer saved') $(".proposed-answer").each((n, el) => {
$(el).find(".confirm").remove()
$(el).removeClass("proposed-answer") // Add button to confirm answer is correct
} $(el).append($("<span class='confirm'>[Correct]</span>").on("click", function () {
// show some message according to the response. $.ajax({
// For eg. A message box showing that the status has been changed url: "{% url 'answer_suggestion_confirm' %}",
}) data: {
.always(function () { csrfmiddlewaretoken: "{{ csrf_token }}",
console.log('[Done]'); //active: this.checked // true if checked else false
}) question_type: "rapid",
})) aid: el.dataset.aid,
}); status: 2,
}); },
type: "POST",
</script> dataType: "json",
})
// $.ajax().done(), $.ajax().fail(), $ajax().always() are upto you. Add/change accordingly
.done(function (data) {
console.log(data);
if (data.success) {
toastr.info('Answer saved')
$(el).find(".confirm").remove()
$(el).removeClass("proposed-answer")
}
// show some message according to the response.
// For eg. A message box showing that the status has been changed
})
.always(function () {
console.log('[Done]');
})
}))
// Add button to confirm answer is incorrect
$(el).append($("<span class='confirm'>[Incorrect]</span>").on("click", function () {
$.ajax({
url: "{% url 'answer_suggestion_confirm' %}",
data: {
csrfmiddlewaretoken: "{{ csrf_token }}",
//active: this.checked // true if checked else false
question_type: "rapid",
aid: el.dataset.aid,
status: 0,
},
type: "POST",
dataType: "json",
})
// $.ajax().done(), $.ajax().fail(), $ajax().always() are upto you. Add/change accordingly
.done(function (data) {
console.log(data);
if (data.success) {
toastr.info('Answer saved')
$(el).find(".confirm").remove()
$(el).removeClass("proposed-answer")
}
// show some message according to the response.
// For eg. A message box showing that the status has been changed
})
.always(function () {
console.log('[Done]');
})
}))
});
});
</script>