Numerous improvements to case questions
This commit is contained in:
@@ -3,14 +3,25 @@
|
||||
|
||||
|
||||
{% block content %}
|
||||
<h2>{{case_detail.collection.name}} / {{case_detail.case.pk}}</h2>
|
||||
|
||||
<div>
|
||||
|
||||
<p>Collection: <a href="{% url 'atlas:collection_detail' case_detail.collection.pk %}">{{case_detail.collection.name}}</a>, Case: <a href="{% url 'atlas:case_detail' case_detail.case.pk %}">{{case_detail.case.title}}</a></p>
|
||||
{% if previous %}
|
||||
<a href="{% url 'atlas:collection_case_details' collection.id previous.id %}">Previous question</a>
|
||||
{% endif %}
|
||||
Viewing question as part of collection: <a href="{% url 'atlas:collection_detail' collection.id %}">{{collection.name}}</a> [{{case_number|add:1}}/{{collection_length}}]
|
||||
{% if next %}
|
||||
<a href="{% url 'atlas:collection_case_details' collection.id next.id %}">Next question</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
|
||||
<h2>Case: <a href="{% url 'atlas:case_detail' case_detail.case.pk %}">{{case_detail.case.title}}</a></h2>
|
||||
|
||||
<p>This form allows you to add questions to a case. A example of how the quesiton will be displayed is shown below.</p>
|
||||
<p>If answers are supplied the question will be automarked</p>
|
||||
|
||||
<p>See https://django-jsonform.readthedocs.io/en/latest/guide/inputs.html for formatting</p>
|
||||
<p>The question system is built using https://github.com/json-editor/json-editor, this allows for highly flexible forms / question design at a cost of some complexity. To help with this a number of preset questions are avalible to choose from (these can then be edited if needed). It is also possible to copy questions from other cases in the collection. </p>
|
||||
|
||||
Import schema from:
|
||||
<button class="btn btn-primary btn-sm" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasRight" aria-controls="offcanvasRight"
|
||||
@@ -44,14 +55,17 @@
|
||||
{{ blank_form}}
|
||||
</form> {% endcomment %}
|
||||
|
||||
<h2>Question display</h2>
|
||||
This shows the form as it will be displayed (with the correct answers). If you wish to edit a correct answer you can change it below.
|
||||
|
||||
<form method="POST" class="post-form">
|
||||
{% csrf_token %}
|
||||
{{example_form}}
|
||||
<button type="submit" value="answer" name="submit">Save Correct Answers</button>
|
||||
</form>
|
||||
{% if case_detail.question_schema %}
|
||||
<h2>Question display</h2>
|
||||
This shows the form as it will be displayed (with the correct answers). If you wish to edit a correct answer you can change it below.
|
||||
|
||||
<form method="POST" class="post-form">
|
||||
{% csrf_token %}
|
||||
{{example_form}}
|
||||
<button type="submit" value="answer" name="submit">Save Correct Answers</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if completed %}
|
||||
{% if question_completed %}
|
||||
<span class="stamp-white">REVIEW</span>
|
||||
{% endif %}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
|
||||
|
||||
{% if not completed %}
|
||||
{% if not question_completed %}
|
||||
{% if resources %}
|
||||
<h5>Resources</h4>
|
||||
<ul class="no-list-style">
|
||||
@@ -109,7 +109,7 @@
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
{% if completed %}
|
||||
{% if question_completed %}
|
||||
{% if resources %}
|
||||
<h5>Resources</h4>
|
||||
<ul class="no-list-style">
|
||||
@@ -127,15 +127,15 @@
|
||||
|
||||
{% endif %}
|
||||
<form method="POST" class="post-form">{% csrf_token %}
|
||||
{% if collection.collection_type == "REP" %}
|
||||
{% if collection.collection_type == "REP" or collection.collection_type == "QUE" %}
|
||||
{{form.json.errors}}
|
||||
<div class="form-contents">
|
||||
<fieldset {% if completed %}disabled="disabled"{% endif %}>
|
||||
<fieldset {% if question_completed %}disabled="disabled"{% endif %}>
|
||||
{{form}}
|
||||
</fieldset>
|
||||
</div>
|
||||
<p>
|
||||
{% if completed %}
|
||||
{% if question_completed %}
|
||||
|
||||
{% if collection.self_review %}
|
||||
{% if self_review %}
|
||||
@@ -167,7 +167,7 @@
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if collection.self_review and not completed %}
|
||||
{% if collection.self_review and not collection.feedback_once_collection_complete and not question_completed %}
|
||||
<button type="submit" name="complete_case" class="save btn btn-default">Finish Case</button>
|
||||
{% endif %}
|
||||
|
||||
@@ -202,6 +202,7 @@
|
||||
{% endblock %}
|
||||
{% block js %}
|
||||
{{ form.media }}
|
||||
{% comment %} <script src="https://cdn.jsdelivr.net/npm/@json-editor/json-editor@latest/dist/jsoneditor.min.js"></script> {% endcomment %}
|
||||
<script type="text/javascript">
|
||||
window.images = {
|
||||
{% for series in series_list %}
|
||||
@@ -214,6 +215,92 @@
|
||||
window.loadDicomViewer(window.images[0])
|
||||
}, 500);
|
||||
})
|
||||
</script>
|
||||
|
||||
{% comment %} $('document').ready(function() {
|
||||
|
||||
// Get value from either a json string or url pointing to a json file
|
||||
function process(value) {
|
||||
var isjson=true;
|
||||
var result;
|
||||
|
||||
try {
|
||||
result = JSON.parse(value);
|
||||
} catch(e) {
|
||||
isjson=false;
|
||||
}
|
||||
|
||||
if (isjson) {
|
||||
return result;
|
||||
} else {
|
||||
return $.getJSON(value)
|
||||
.then(function (response) {
|
||||
return response;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$('.editor_holder').each(function() {
|
||||
// Get the DOM Element
|
||||
var element = $(this).get(0);
|
||||
console.log("el", element)
|
||||
|
||||
var options_text = $(this).attr('options')
|
||||
var schema_text = $(this).attr('schema')
|
||||
|
||||
var schema = process(schema_text);
|
||||
var options = process(options_text);
|
||||
|
||||
var name = $(this).attr('name');
|
||||
var hidden_identifier = 'input[name=' + name + ']';
|
||||
var initial = $(hidden_identifier).val();
|
||||
|
||||
// Check if editor is within form
|
||||
var form = $(this).closest('form')
|
||||
console.log("form", form)
|
||||
|
||||
//Wait for any ajax requests to complete
|
||||
$.when(schema, options).done(function(schemaresult, optionsresult) {
|
||||
optionsresult.form_name_root = name;
|
||||
|
||||
// Pass initial value though to editor
|
||||
if (initial) {
|
||||
optionsresult.startval = JSON.parse(initial);
|
||||
}
|
||||
|
||||
optionsresult.schema = schemaresult;
|
||||
// console.log(options);
|
||||
var editor = new JSONEditor(element, optionsresult);
|
||||
|
||||
console.log("editor", editor)
|
||||
if (form) {
|
||||
$(form).submit(function(e) {
|
||||
console.log("submitting")
|
||||
// Set the hidden field value to the editors value
|
||||
$(hidden_identifier).val(JSON.stringify(editor.getValue()));
|
||||
// Disable the editor so it's values wont be submitted
|
||||
//editor.disable();
|
||||
// Validate the editor's current value against the schema
|
||||
const errors = editor.validate();
|
||||
|
||||
if (errors.length) {
|
||||
// errors is an array of objects, each with a `path`, `property`, and `message` parameter
|
||||
// `property` is the schema keyword that triggered the validation error (e.g. "minLength")
|
||||
// `path` is a dot separated path into the JSON object (e.g. "root.path.to.field")
|
||||
console.log(errors);
|
||||
}
|
||||
else {
|
||||
console.log("valid");
|
||||
}
|
||||
console.log(editor.getValue());
|
||||
//e.preventDefault();
|
||||
})
|
||||
} else {
|
||||
console.log("No form found")
|
||||
}
|
||||
})
|
||||
});
|
||||
})
|
||||
{% endcomment %}
|
||||
</script>
|
||||
|
||||
{% endblock js %}
|
||||
|
||||
@@ -15,7 +15,11 @@
|
||||
<ol id="full-question-list" class="sortable">
|
||||
{% for casedetail in casesdetails %}
|
||||
<li data-question_pk={{casedetail.case.pk}}><a title="sort_order: {{casedetail.sort_order}}" href="{% url 'atlas:collection_case_view' pk=collection.pk case_number=forloop.counter0 %}">Case {{forloop.counter}}</a>
|
||||
: {{casedetail.case.title}} (<a href='{% url "atlas:collection_case_details" casedetail.collection.pk casedetail.case.pk %}'>edit</a>)
|
||||
: {{casedetail.case.title}}
|
||||
|
||||
{% if collection.collection_type == "QUE" %}
|
||||
(<a href='{% url "atlas:collection_case_details" casedetail.collection.pk casedetail.case.pk %}'>edit</a>)
|
||||
{% endif %}
|
||||
</li>
|
||||
|
||||
{% endfor %}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<h2>Case: {{ case_detail.case.title }}</h2>
|
||||
|
||||
{% if case_detail.question_schema %}
|
||||
<button class="btn btn-sm btn-secondary use-layout">Use layout</button>
|
||||
<button class="btn btn-sm btn-secondary use-layout">Use schema</button>
|
||||
<details><summary>Schema:</summary>
|
||||
<div class="schema" data-schema='{{ case_detail.get_question_schema }}'>{{ case_detail.question_schema }}</div>
|
||||
</details>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
{% for schema in schemas %}
|
||||
|
||||
<li class="schemas">
|
||||
<button class="btn btn-sm btn-secondary use-layout">Use layout</button>
|
||||
<button class="btn btn-sm btn-secondary use-layout">Use schema</button>
|
||||
<details><summary>Schema:</summary>
|
||||
<div class="schema" data-schema='{{schema|safe}}'>{{schema}}</div>
|
||||
</details>
|
||||
|
||||
Reference in New Issue
Block a user