Convert Problem Block Mako Templates to Django Templates (#37570)
* fix: convert mako to django templates for problem block * fix: pylint issues
This commit is contained in:
@@ -319,6 +319,7 @@ MAKO_TEMPLATE_DIRS_BASE = [
|
||||
OPENEDX_ROOT / 'core' / 'djangoapps' / 'dark_lang' / 'templates',
|
||||
OPENEDX_ROOT / 'core' / 'lib' / 'license' / 'templates',
|
||||
CMS_ROOT / 'djangoapps' / 'pipeline_js' / 'templates',
|
||||
XMODULE_ROOT / 'capa' / 'templates',
|
||||
]
|
||||
|
||||
CONTEXT_PROCESSORS = (
|
||||
|
||||
@@ -1,169 +0,0 @@
|
||||
<%page expression_filter="h"/>
|
||||
<%!
|
||||
from django.utils.translation import ngettext, gettext as _
|
||||
from openedx.core.djangolib.markup import HTML, Text
|
||||
%>
|
||||
|
||||
<%namespace name='static' file='static_content.html'/>
|
||||
<h3 class="hd hd-3 problem-header" id="${ short_id }-problem-title" aria-describedby="${ id }-problem-progress" tabindex="-1">
|
||||
${ problem['name'] }
|
||||
</h3>
|
||||
|
||||
<div class="problem-progress" id="${ id }-problem-progress"></div>
|
||||
|
||||
<div class="problem">
|
||||
${ HTML(problem['html']) }
|
||||
<div class="action">
|
||||
<input type="hidden" name="problem_id" value="${ problem['name'] }" />
|
||||
% if demand_hint_possible:
|
||||
<div class="problem-hint">
|
||||
<%include file="problem_notifications.html" args="
|
||||
notification_name='hint',
|
||||
notification_type='problem-hint',
|
||||
notification_icon='fa-question',
|
||||
notification_message=''"
|
||||
/>
|
||||
</div>
|
||||
% endif
|
||||
|
||||
<div class="problem-action-buttons-wrapper">
|
||||
% if demand_hint_possible:
|
||||
<span class="problem-action-button-wrapper">
|
||||
<button type="button" class="hint-button problem-action-btn btn-link btn-small" data-value="${_('Hint')}" ${'' if should_enable_next_hint else 'disabled'}>${_('Hint')}</button>
|
||||
</span>
|
||||
% endif
|
||||
% if save_button:
|
||||
<span class="problem-action-button-wrapper">
|
||||
<button type="button" class="save problem-action-btn btn-link btn-small" data-value="${_('Save')}">
|
||||
<span aria-hidden="true">${_('Save')}</span>
|
||||
<span class="sr">${_("Save your answer")}</span>
|
||||
</button>
|
||||
</span>
|
||||
% endif
|
||||
% if attempts_used and reset_button:
|
||||
<span class="problem-action-button-wrapper">
|
||||
<button type="button" class="reset problem-action-btn btn-link btn-small" data-value="${_('Reset')}"><span aria-hidden="true">${_('Reset')}</span><span class="sr">${_("Reset your answer")}</span></button>
|
||||
</span>
|
||||
% endif
|
||||
% if answer_available:
|
||||
<span class="problem-action-button-wrapper">
|
||||
<button type="button" class="show problem-action-btn btn-link btn-small" aria-describedby="${ short_id }-problem-title"><span class="show-label">${_('Show answer')}</span></button>
|
||||
</span>
|
||||
% endif
|
||||
</div>
|
||||
<div class="submit-attempt-container">
|
||||
<button type="button" class="submit btn-brand" data-submitting="${ submit_button_submitting }" data-value="${ submit_button }" data-should-enable-submit-button="${ should_enable_submit_button }" aria-describedby="submission_feedback_${short_id}" ${'' if should_enable_submit_button else 'disabled'}>
|
||||
<span class="submit-label">${ submit_button }</span>
|
||||
</button>
|
||||
|
||||
% if submit_disabled_cta:
|
||||
% if submit_disabled_cta.get('event_data'):
|
||||
<button class="submit-cta-link-button btn-link btn-small" onclick="emit_event(${submit_disabled_cta['event_data']})">
|
||||
${submit_disabled_cta['link_name']}
|
||||
</button>
|
||||
<span class="submit-cta-description" tabindex="0" role="note" aria-label="description">
|
||||
<span data-tooltip="${submit_disabled_cta['description']}" data-tooltip-show-on-click="true"
|
||||
class="fa fa-info-circle fa-lg" aria-hidden="true">
|
||||
</span>
|
||||
</span>
|
||||
<span class="sr">(${submit_disabled_cta['description']})</span>
|
||||
% else:
|
||||
<form class="submit-cta" method="post" action="${submit_disabled_cta.get('link')}">
|
||||
% if submit_disabled_cta.get('link'):
|
||||
<input type="hidden" id="csrf_token" name="csrfmiddlewaretoken" value="${csrf_token}">
|
||||
% for form_name, form_value in submit_disabled_cta['form_values'].items():
|
||||
<input type="hidden" name="${form_name}" value="${form_value}">
|
||||
% endfor
|
||||
<button class="submit-cta-link-button btn-link btn-small">
|
||||
${submit_disabled_cta['link_name']}
|
||||
</button>
|
||||
% endif
|
||||
<span class="submit-cta-description" tabindex="0" role="note" aria-label="description">
|
||||
<span data-tooltip="${submit_disabled_cta['description']}" data-tooltip-show-on-click="true"
|
||||
class="fa fa-info-circle fa-lg" aria-hidden="true">
|
||||
</span>
|
||||
</span>
|
||||
<span class="sr">(${submit_disabled_cta['description']})</span>
|
||||
</form>
|
||||
% endif
|
||||
% endif
|
||||
<div class="submission-feedback ${'cta-enabled' if submit_disabled_cta else ''}" id="submission_feedback_${short_id}">
|
||||
## When attempts are not 0, the CTA above will contain a message about the number of used attempts
|
||||
% if attempts_allowed and (not submit_disabled_cta or attempts_used == 0):
|
||||
${ngettext("You have used {num_used} of {num_total} attempt", "You have used {num_used} of {num_total} attempts", attempts_allowed).format(num_used=attempts_used, num_total=attempts_allowed)}
|
||||
% endif
|
||||
% if grading_method:
|
||||
<div>${Text(_("Grading method: {grading_method}")).format(grading_method=grading_method)}</div>
|
||||
% endif
|
||||
<span class="sr">${_("Some problems have options such as save, reset, hints, or show answer. These options follow the Submit button.")}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<%include file="problem_notifications.html" args="
|
||||
notification_type='warning',
|
||||
notification_icon='fa-exclamation-circle',
|
||||
notification_name='gentle-alert',
|
||||
notification_message=''"
|
||||
/>
|
||||
% if answer_notification_type:
|
||||
% if 'correct' == answer_notification_type:
|
||||
<%include file="problem_notifications.html" args="
|
||||
notification_type='success',
|
||||
notification_icon='fa-check',
|
||||
notification_name='submit',
|
||||
is_hidden=False,
|
||||
notification_message=answer_notification_message"
|
||||
/>
|
||||
% endif
|
||||
% if 'incorrect' == answer_notification_type:
|
||||
<%include file="problem_notifications.html" args="
|
||||
notification_type='error',
|
||||
notification_icon='fa-close',
|
||||
notification_name='submit',
|
||||
is_hidden=False,
|
||||
notification_message=answer_notification_message"
|
||||
/>
|
||||
% endif
|
||||
% if 'partially-correct' == answer_notification_type:
|
||||
<%include file="problem_notifications.html" args="
|
||||
notification_type='success',
|
||||
notification_icon='fa-asterisk',
|
||||
notification_name='submit',
|
||||
is_hidden=False,
|
||||
notification_message=answer_notification_message"
|
||||
/>
|
||||
% endif
|
||||
% if 'submitted' == answer_notification_type:
|
||||
<%include file="problem_notifications.html" args="
|
||||
notification_type='general',
|
||||
notification_icon='fa-info-circle',
|
||||
notification_name='submit',
|
||||
is_hidden=False,
|
||||
notification_message=answer_notification_message"
|
||||
/>
|
||||
% endif
|
||||
% endif
|
||||
<%include file="problem_notifications.html" args="
|
||||
notification_type='warning',
|
||||
notification_icon='fa-save',
|
||||
notification_name='save',
|
||||
notification_message=save_message,
|
||||
is_hidden=not has_saved_answers"
|
||||
/>
|
||||
<%
|
||||
notification_message=_('Answers are displayed within the problem')
|
||||
%>
|
||||
<%include file="problem_notifications.html" args="
|
||||
notification_type='general',
|
||||
notification_icon='fa-info-circle',
|
||||
notification_name='show-answer',
|
||||
notification_message=notification_message,
|
||||
is_hidden=True"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function emit_event(message) {
|
||||
parent.postMessage(message, '*');
|
||||
}
|
||||
</script>
|
||||
@@ -1,13 +0,0 @@
|
||||
<div id="problem_${element_id}" class="problems-wrapper" role="group"
|
||||
aria-labelledby="${element_id}-problem-title"
|
||||
data-problem-id="${id}" data-url="${ajax_url}"
|
||||
data-problem-score="${current_score}"
|
||||
data-problem-total-possible="${total_possible}"
|
||||
data-attempts-used="${attempts_used}"
|
||||
data-content="${content | h}"
|
||||
data-graded="${graded}">
|
||||
<p class="loading-spinner">
|
||||
<i class="fa fa-spinner fa-pulse fa-2x fa-fw"></i>
|
||||
<span class="sr">Loading…</span>
|
||||
</p>
|
||||
</div>
|
||||
@@ -1,19 +0,0 @@
|
||||
<%page expression_filter="h" args="notification_name, notification_type, notification_icon,
|
||||
notification_message, should_enable_next_hint, is_hidden=True"/>
|
||||
<%! from django.utils.translation import gettext as _ %>
|
||||
|
||||
<div class="notification ${notification_type} ${'notification-'}${notification_name}
|
||||
${'' if not is_hidden else 'is-hidden' }"
|
||||
tabindex="-1">
|
||||
<span class="icon fa ${notification_icon}" aria-hidden="true"></span>
|
||||
<span class="notification-message" aria-describedby="${ short_id }-problem-title">${notification_message}
|
||||
</span>
|
||||
<div class="notification-btn-wrapper">
|
||||
% if notification_name == 'hint':
|
||||
<button type="button" class="btn btn-default btn-small notification-btn hint-button">
|
||||
${_('Next Hint')}
|
||||
</button>
|
||||
% endif
|
||||
<button type="button" class="btn btn-default btn-small notification-btn review-btn sr">${_('Review')}</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1476,6 +1476,7 @@ class DjangoTemplateLinter(BaseLinter):
|
||||
django_trans_missing_escape='django-trans-missing-escape',
|
||||
django_trans_invalid_escape_filter='django-trans-invalid-escape-filter',
|
||||
django_trans_escape_variable_mismatch='django-trans-escape-variable-mismatch',
|
||||
django_trans_escape_filter_parse_error='django-trans-escape-filter-parse-error',
|
||||
django_blocktrans_missing_escape_filter='django-blocktrans-missing-escape-filter',
|
||||
django_blocktrans_parse_error='django-blocktrans-parse-error',
|
||||
django_blocktrans_escape_filter_parse_error='django-blocktrans-escape-filter-parse-error',
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"django-html-interpolation-missing-safe-filter": 0,
|
||||
"django-trans-escape-variable-mismatch": 0,
|
||||
"django-trans-invalid-escape-filter": 0,
|
||||
"django-trans-escape-filter-parse-error": 0,
|
||||
"django-trans-missing-escape": 0,
|
||||
"javascript-concat-html": 2,
|
||||
"javascript-escape": 1,
|
||||
|
||||
@@ -10,8 +10,7 @@ import sys
|
||||
from io import BytesIO
|
||||
|
||||
from calc import UndefinedVariable
|
||||
from mako.lookup import TemplateLookup
|
||||
from path import Path as path
|
||||
from django.template.loader import get_template
|
||||
|
||||
from xmodule.capa.capa_problem import LoncapaProblem
|
||||
|
||||
@@ -21,14 +20,13 @@ log = logging.getLogger("capa.checker")
|
||||
|
||||
class DemoSystem(object): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
def __init__(self):
|
||||
self.lookup = TemplateLookup(directories=[path(__file__).dirname() / "templates"])
|
||||
self.DEBUG = True
|
||||
|
||||
def render_template(self, template_filename, dictionary):
|
||||
"""
|
||||
Render the specified template with the given dictionary of context data.
|
||||
"""
|
||||
return self.lookup.get_template(template_filename).render(**dictionary)
|
||||
return get_template(template_filename).render(dictionary)
|
||||
|
||||
|
||||
def main(): # lint-amnesty, pylint: disable=missing-function-docstring
|
||||
|
||||
@@ -18,7 +18,7 @@ Module containing the problem elements which render into input objects
|
||||
- formulaequationinput
|
||||
- chemicalequationinput
|
||||
|
||||
These are matched by *.html files templates/*.html which are mako templates with the
|
||||
These are matched by *.html files templates/*.html which are django templates with the
|
||||
actual html.
|
||||
|
||||
Each input type takes the xml tree as 'element', the previous answer as 'value', and the
|
||||
|
||||
@@ -1,62 +1,62 @@
|
||||
<%! from openedx.core.djangolib.markup import HTML %>
|
||||
{% load static %}
|
||||
<div class="annotation-input">
|
||||
<div class="script_placeholder" data-src="${STATIC_URL}js/capa/annotationinput.js"/>
|
||||
<div class="script_placeholder" data-src="{% static 'js/capa/annotationinput.js' %}"/>
|
||||
|
||||
<div class="annotation-header">
|
||||
${title}
|
||||
{{ title|safe }}
|
||||
|
||||
% if return_to_annotation:
|
||||
{% if return_to_annotation %}
|
||||
<a class="annotation-return" href="javascript:void(0)">Return to Annotation</a><br/>
|
||||
% endif
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="annotation-body">
|
||||
|
||||
<div class="block block-highlight">${text}</div>
|
||||
<div class="block block-comment">${comment}</div>
|
||||
<div class="block block-highlight">{{ text|safe }}</div>
|
||||
<div class="block block-comment">{{ comment|safe }}</div>
|
||||
|
||||
<div class="block">${comment_prompt}</div>
|
||||
<textarea class="comment" id="input_${id}_comment" name="input_${id}_comment" aria-describedby="answer_${id}">${comment_value|h}</textarea>
|
||||
<div class="block">{{ comment_prompt|safe }}</div>
|
||||
<textarea class="comment" id="input_{{ id }}_comment" name="input_{{ id }}_comment" aria-describedby="answer_{{ id }}">{{ comment_value|safe }}</textarea>
|
||||
|
||||
<div class="block" id="label_${id}">${tag_prompt}</div>
|
||||
<div class="block" id="label_{{ id }}">{{ tag_prompt|safe }}</div>
|
||||
<ul class="tags">
|
||||
% for option in options:
|
||||
{% for option in options %}
|
||||
<li>
|
||||
% if has_options_value:
|
||||
% if all(c == status.classname for c in (option['choice'], status)):
|
||||
<span class="tag-status ${status.classname}" aria-describedby="input_${id}_comment">
|
||||
<%include file="status_span.html" args="status=status"/>
|
||||
{% if has_options_value %}
|
||||
{% if option.choice == status.classname and status == status.classname %}
|
||||
<span class="tag-status {{ status.classname }}" aria-describedby="input_{{ id }}_comment">
|
||||
{% include "status_span.html" with status=status %}
|
||||
</span>
|
||||
% endif
|
||||
% endif
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
<span class="tag
|
||||
% if option['id'] in options_value:
|
||||
{% if option.id in options_value %}
|
||||
selected
|
||||
% endif
|
||||
" data-id="${option['id']}">
|
||||
${option['description']}
|
||||
{% endif %}
|
||||
" data-id="{{ option.id }}">
|
||||
{{ option.description|safe }}
|
||||
</span>
|
||||
</li>
|
||||
% endfor
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
% if debug:
|
||||
{% if debug %}
|
||||
<div class="debug-value">
|
||||
Rendered with value:<br/>
|
||||
<pre>${value|h}</pre>
|
||||
<pre>{{ value|safe }}</pre>
|
||||
Current input value:<br/>
|
||||
<input type="text" class="value" name="input_${id}" id="input_${id}" value="${value|h}" />
|
||||
<input type="text" class="value" name="input_{{ id }}" id="input_{{ id }}" value="{{ value }}" />
|
||||
</div>
|
||||
% else:
|
||||
<input type="hidden" class="value" name="input_${id}" id="input_${id}" value="${value|h}" />
|
||||
% endif
|
||||
{% else %}
|
||||
<input type="hidden" class="value" name="input_{{ id }}" id="input_{{ id }}" value="{{ value }}" />
|
||||
{% endif %}
|
||||
|
||||
<%include file="status_span.html" args="status=status, status_id=id"/>
|
||||
{% include "status_span.html" with status=status status_id=id %}
|
||||
|
||||
<p id="answer_${id}" class="answer answer-annotation"></p>
|
||||
<p id="answer_{{ id }}" class="answer answer-annotation"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
% if msg:
|
||||
<span class="message" aria-describedby="label_${id}" tabindex="-1">${HTML(msg)}</span>
|
||||
% endif
|
||||
{% if msg %}
|
||||
<span class="message" aria-describedby="label_{{ id }}" tabindex="-1">{{ msg|safe }}</span>
|
||||
{% endif %}
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
<%! from xmodule.capa.util import remove_markup %>
|
||||
<div id="chemicalequationinput_${id}" class="chemicalequationinput">
|
||||
<div class="script_placeholder" data-src="${previewer}"/>
|
||||
<div id="chemicalequationinput_{{ id }}" class="chemicalequationinput">
|
||||
<div class="script_placeholder" data-src="{{ previewer }}"/>
|
||||
|
||||
<div class="${status.classname}">
|
||||
<div class="{{ status.classname }}">
|
||||
|
||||
<input type="text" name="input_${id}" id="input_${id}" aria-label="${remove_markup(response_data['label'])}"
|
||||
aria-describedby="answer_${id}" data-input-id="${id}" value="${value|h}"
|
||||
% if size:
|
||||
size="${size}"
|
||||
% endif
|
||||
<input type="text" name="input_{{ id }}" id="input_{{ id }}" aria-label="{{ response_data.label|striptags }}"
|
||||
aria-describedby="answer_{{ id }}" data-input-id="{{ id }}" value="{{ value }}"
|
||||
{% if size %}
|
||||
size="{{ size }}"
|
||||
{% endif %}
|
||||
/>
|
||||
|
||||
<p class="indicator-container">
|
||||
${value|h}
|
||||
<%include file="status_span.html" args="status=status, status_id=id"/>
|
||||
{{ value }}
|
||||
{% include "status_span.html" with status=status status_id=id %}
|
||||
</p>
|
||||
|
||||
<div id="input_${id}_preview" class="equation"></div>
|
||||
<p id="answer_${id}" class="answer"></p>
|
||||
<div id="input_{{ id }}_preview" class="equation"></div>
|
||||
<p id="answer_{{ id }}" class="answer"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,64 +1,46 @@
|
||||
<%page expression_filter="h"/>
|
||||
<%!
|
||||
from openedx.core.djangolib.markup import HTML
|
||||
%>
|
||||
<%
|
||||
def is_radio_input(choice_id):
|
||||
return input_type == 'radio' and ((isinstance(value, str) and (choice_id == value)) or (
|
||||
not isinstance(value, str) and choice_id in value
|
||||
))
|
||||
%>
|
||||
<div class="choicegroup capa_inputtype" id="inputtype_${id}">
|
||||
<fieldset ${describedby_html}>
|
||||
% if response_data['label']:
|
||||
<legend id="${id}-legend" class="response-fieldset-legend field-group-hd">${response_data['label']}</legend>
|
||||
% endif
|
||||
% for description_id, description_text in response_data['descriptions'].items():
|
||||
<p class="question-description" id="${description_id}">${description_text}</p>
|
||||
% endfor
|
||||
% for choice_id, choice_label in choices:
|
||||
<%
|
||||
label_class = 'response-label field-label label-inline'
|
||||
input_class = 'field-input input-' + input_type
|
||||
input_checked = ''
|
||||
|
||||
if is_radio_input(choice_id) or (input_type != 'radio' and choice_id in value):
|
||||
input_class += ' submitted'
|
||||
if status.classname and not show_correctness == 'never':
|
||||
label_class += ' choicegroup_' + status.classname
|
||||
%>
|
||||
<div class="choicegroup capa_inputtype" id="inputtype_{{ id }}">
|
||||
<fieldset {{ describedby_html }}>
|
||||
{% if response_data.label %}
|
||||
<legend id="{{ id }}-legend" class="response-fieldset-legend field-group-hd">{{ response_data.label }}</legend>
|
||||
{% endif %}
|
||||
{% for description_id, description_text in response_data.descriptions.items %}
|
||||
<p class="question-description" id="{{ description_id }}">{{ description_text|safe }}</p>
|
||||
{% endfor %}
|
||||
{% for choice_id, choice_label in choices %}
|
||||
<div class="field">
|
||||
<input type="${input_type}" name="input_${id}${name_array_suffix}" id="input_${id}_${choice_id}"
|
||||
class="${input_class}" value="${choice_id}"
|
||||
## If the student selected this choice...
|
||||
% if is_radio_input(choice_id):
|
||||
<input type="{{ input_type }}" name="input_{{ id }}{{ name_array_suffix }}" id="input_{{ id }}_{{ choice_id }}"
|
||||
class="field-input input-{{ input_type }}{% if input_type == 'radio' and choice_id == value or input_type != 'radio' and choice_id in value %} submitted{% endif %}" value="{{ choice_id }}"
|
||||
{# If the student selected this choice... #}
|
||||
{% if input_type == 'radio' and choice_id == value or input_type != 'radio' and choice_id in value %}
|
||||
checked="true"
|
||||
% elif input_type != 'radio' and choice_id in value:
|
||||
{% elif input_type != 'radio' and choice_id in value %}
|
||||
checked="true"
|
||||
% endif
|
||||
/><label id="${id}-${choice_id}-label" for="input_${id}_${choice_id}"
|
||||
class="${label_class}"
|
||||
${describedby_html}
|
||||
{% endif %}
|
||||
/><label id="{{ id }}-{{ choice_id }}-label" for="input_{{ id }}_{{ choice_id }}"
|
||||
class="response-label field-label label-inline{% if choice_id in value and status.classname and show_correctness != 'never' %} choicegroup_{{ status.classname }}{% endif %}"
|
||||
{{ describedby_html }}
|
||||
>
|
||||
<div>
|
||||
${HTML(choice_label)}
|
||||
{{ choice_label|safe }}
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
% endfor
|
||||
<span id="answer_${id}"></span>
|
||||
{% endfor %}
|
||||
<span id="answer_{{ id }}"></span>
|
||||
</fieldset>
|
||||
<div class="indicator-container">
|
||||
% if show_correctness != 'never':
|
||||
<%include file="status_span.html" args="status=status, status_id=id"/>
|
||||
% else:
|
||||
<%include file="status_span.html" args="status=status, status_id=id, hide_correctness=True"/>
|
||||
% endif
|
||||
{% if show_correctness != 'never' %}
|
||||
{% include "status_span.html" with status=status status_id=id %}
|
||||
{% else %}
|
||||
{% include "status_span.html" with status=status status_id=id hide_correctness=True %}
|
||||
{% endif %}
|
||||
</div>
|
||||
% if show_correctness == "never" and (value or status not in ['unsubmitted']):
|
||||
<div class="capa_alert">${submitted_message}</div>
|
||||
%endif
|
||||
% if msg:
|
||||
<span class="message" aria-describedby="${id}-legend" tabindex="-1">${HTML(msg)}</span>
|
||||
% endif
|
||||
{% if show_correctness == "never" %}
|
||||
{% if value or status != "unsubmitted" %}
|
||||
<div class="capa_alert">{{ submitted_message|safe }}</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if msg %}
|
||||
<span class="message" aria-describedby="{{ id }}-legend" tabindex="-1">{{ msg|safe }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
@@ -1,70 +1,72 @@
|
||||
<%! from xmodule.capa.util import remove_markup
|
||||
from django.utils.translation import gettext as _
|
||||
from openedx.core.djangolib.markup import HTML
|
||||
%>
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
|
||||
<% element_checked = False %>
|
||||
% for choice_id, _ in choices:
|
||||
<% choice_id = choice_id %>
|
||||
%if choice_id in value:
|
||||
<% element_checked = True %>
|
||||
%endif
|
||||
% endfor
|
||||
<section id="choicetextinput_${id}" class="choicetextinput">
|
||||
<div class="choicetextgroup capa_inputtype" id="inputtype_${id}">
|
||||
<div class="script_placeholder" data-src="${STATIC_URL}js/capa/choicetextinput.js"/>
|
||||
{% with element_checked=False %}
|
||||
{% for choice_id, _ in choices %}
|
||||
{% if choice_id in value %}
|
||||
{% with element_checked=True %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<section id="choicetextinput_{{ id }}" class="choicetextinput">
|
||||
<div class="choicetextgroup capa_inputtype" id="inputtype_{{ id }}">
|
||||
<div class="script_placeholder" data-src="{% static 'js/capa/choicetextinput.js' %}"/>
|
||||
|
||||
<fieldset aria-label="${remove_markup(response_data['label'])}">
|
||||
% for choice_id, choice_description in choices:
|
||||
<% choice_id = choice_id %>
|
||||
<section id="forinput${choice_id}"
|
||||
% if input_type == 'radio' and choice_id in value :
|
||||
% if status.classname:
|
||||
class="choicetextgroup_${status.classname}"
|
||||
% endif
|
||||
% endif
|
||||
<fieldset aria-label="{{ response_data.label|striptags }}">
|
||||
{% for choice_id, choice_description in choices %}
|
||||
<section id="forinput{{ choice_id }}"
|
||||
{% if input_type == 'radio' and choice_id in value %}
|
||||
{% if status.classname %}
|
||||
class="choicetextgroup_{{ status.classname }}"
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
>
|
||||
<input class="ctinput" type="${input_type}" name="choiceinput_${id}" id="${choice_id}" value="${choice_id}"
|
||||
<input class="ctinput" type="{{ input_type }}" name="choiceinput_{{ id }}" id="{{ choice_id }}" value="{{ choice_id }}"
|
||||
|
||||
% if choice_id in value:
|
||||
{% if choice_id in value %}
|
||||
checked="true"
|
||||
% endif
|
||||
{% endif %}
|
||||
/>
|
||||
|
||||
% for content_node in choice_description:
|
||||
% if content_node['type'] == 'text':
|
||||
{% for content_node in choice_description %}
|
||||
{% if content_node.type == 'text' %}
|
||||
<span class="mock_label">
|
||||
${content_node['contents']}
|
||||
{{ content_node.contents }}
|
||||
</span>
|
||||
% else:
|
||||
<% my_id = content_node.get('contents','') %>
|
||||
<% my_val = value.get(my_id,'') %>
|
||||
<input class="ctinput" type="text" name="${content_node['contents']}" id="${content_node['contents']}" value="${my_val|h}"/>
|
||||
%endif
|
||||
{% else %}
|
||||
{% with my_id=content_node.contents|default:'' %}
|
||||
{% with my_val=value.my_id|default:'' %}
|
||||
<input class="ctinput" type="text" name="{{ content_node.contents }}" id="{{ content_node.contents }}" value="{{ my_val }}"/>
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
<span class="mock_label">
|
||||
${content_node['tail_text']}
|
||||
{{ content_node.tail_text }}
|
||||
</span>
|
||||
|
||||
% endfor
|
||||
<p id="answer_${choice_id}" class="answer"></p>
|
||||
{% endfor %}
|
||||
<p id="answer_{{ choice_id }}" class="answer"></p>
|
||||
</section>
|
||||
|
||||
% endfor
|
||||
<span id="answer_${id}"></span>
|
||||
{% endfor %}
|
||||
<span id="answer_{{ id }}"></span>
|
||||
</fieldset>
|
||||
<input class= "choicetextvalue" type="hidden" name="input_${id}{}" id="input_${id}" value="${value|h}" />
|
||||
<input class= "choicetextvalue" type="hidden" name="input_{{ id }}{}" id="input_{{ id }}" value="{{ value }}" />
|
||||
|
||||
<div class="indicator-container">
|
||||
% if input_type == 'checkbox' or not element_checked:
|
||||
<%include file="status_span.html" args="status=status, status_id=id"/>
|
||||
% endif
|
||||
{% if input_type == 'checkbox' or not value or status.classname == 'incomplete' or status.classname == 'unsubmitted' or status.classname == 'unanswered' %}
|
||||
{% include "status_span.html" with status=status status_id=id %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
% if show_correctness == "never" and (value or status not in ['unsubmitted']):
|
||||
<div class="capa_alert">${_(submitted_message)}</div>
|
||||
%endif
|
||||
% if msg:
|
||||
<span class="message" tabindex="-1">${HTML(msg)}</span>
|
||||
% endif
|
||||
{% if show_correctness == "never" %}
|
||||
{% if value or status != "unsubmitted" %}
|
||||
<div class="capa_alert">{{ submitted_message }}</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if msg %}
|
||||
<span class="message" tabindex="-1">{{ msg|safe }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
{% endwith %}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<span class="clarification" tabindex="0" role="note" aria-label="Clarification">
|
||||
<span data-tooltip="${clarification | h}" data-tooltip-show-on-click="true"
|
||||
<span data-tooltip="{{ clarification }}" data-tooltip-show-on-click="true"
|
||||
class="fa fa-info-circle" aria-hidden="true"></span>
|
||||
<span class="sr">(${clarification})</span>
|
||||
<span class="sr">({{ clarification }})</span>
|
||||
</span>
|
||||
|
||||
@@ -1,50 +1,46 @@
|
||||
<%page expression_filter="h"/>
|
||||
<%!
|
||||
from django.utils.translation import gettext as _
|
||||
from openedx.core.djangolib.markup import HTML
|
||||
%>
|
||||
<div id="textbox_${id}" class="capa_inputtype textbox cminput">
|
||||
% if response_data['label']:
|
||||
<label class="problem-group-label" for="cm-textarea-${id}">${response_data['label']}</label>
|
||||
% else:
|
||||
<label class="sr problem-group-label" for="cm-textarea-${id}">${_('Code Editor')}</label>
|
||||
% endif
|
||||
<textarea rows="${rows}" cols="${cols}" name="input_${id}"
|
||||
aria-label="${aria_label}"
|
||||
aria-describedby="answer_${id}"
|
||||
id="input_${id}"
|
||||
{% load i18n %}
|
||||
<div id="textbox_{{ id }}" class="capa_inputtype textbox cminput">
|
||||
{% if response_data.label %}
|
||||
<label class="problem-group-label" for="cm-textarea-{{ id }}">{{ response_data.label }}</label>
|
||||
{% else %}
|
||||
<label class="sr problem-group-label" for="cm-textarea-{{ id }}">{% trans "Code Editor" as editor_label %}{{ editor_label|force_escape }}</label>
|
||||
{% endif %}
|
||||
<textarea rows="{{ rows }}" cols="{{ cols }}" name="input_{{ id }}"
|
||||
aria-label="{{ aria_label }}"
|
||||
aria-describedby="answer_{{ id }}"
|
||||
id="input_{{ id }}"
|
||||
tabindex="0"
|
||||
data-mode="${mode}"
|
||||
data-tabsize="${tabsize}"
|
||||
% if linenumbers:
|
||||
data-mode="{{ mode }}"
|
||||
data-tabsize="{{ tabsize }}"
|
||||
{% if linenumbers %}
|
||||
data-linenums="true"
|
||||
% endif
|
||||
% if hidden:
|
||||
{% endif %}
|
||||
{% if hidden %}
|
||||
style="display:none;"
|
||||
% endif
|
||||
>${value}</textarea>
|
||||
<span class="cm-editor-exit-message capa-message" id="cm-editor-exit-message-${id}">
|
||||
${code_mirror_exit_message}
|
||||
{% endif %}
|
||||
>{{ value }}</textarea>
|
||||
<span class="cm-editor-exit-message capa-message" id="cm-editor-exit-message-{{ id }}">
|
||||
{{ code_mirror_exit_message }}
|
||||
</span>
|
||||
|
||||
<div class="grader-status" tabindex="-1">
|
||||
|
||||
<%include file="status_span.html" args="status=status, status_id=id"/>
|
||||
{% include "status_span.html" with status=status status_id=id %}
|
||||
|
||||
% if status == 'queued':
|
||||
<span style="display:none;" class="xqueue" id="${id}">${queue_len}</span>
|
||||
% endif
|
||||
{% if status == 'queued' %}
|
||||
<span style="display:none;" class="xqueue" id="{{ id }}">{{ queue_len }}</span>
|
||||
{% endif %}
|
||||
|
||||
% if hidden:
|
||||
<div style="display:none;" name="${hidden}" inputid="input_${id}" />
|
||||
% endif
|
||||
{% if hidden %}
|
||||
<div style="display:none;" name="{{ hidden }}" inputid="input_{{ id }}" />
|
||||
{% endif %}
|
||||
|
||||
<p class="debug">${status.display_name}</p>
|
||||
<p class="debug">{{ status.display_name }}</p>
|
||||
</div>
|
||||
|
||||
<span id="answer_${id}"></span>
|
||||
<span id="answer_{{ id }}"></span>
|
||||
|
||||
<div class="external-grader-message">
|
||||
${HTML(msg)}
|
||||
{{ msg|safe }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<%! from openedx.core.djangolib.markup import HTML %>
|
||||
<section id="inputtype_${id}" class="capa_inputtype" >
|
||||
<div class="crystalography_problem" style="width:${width};height:${height}"></div>
|
||||
<section id="inputtype_{{ id }}" class="capa_inputtype" >
|
||||
<div class="crystalography_problem" style="width:{{ width }};height:{{ height }}"></div>
|
||||
|
||||
<div class="input_lattice">
|
||||
Lattice: <select></select>
|
||||
@@ -10,21 +9,21 @@
|
||||
<div class="script_placeholder" data-src="/static/js/sylvester.js"></div>
|
||||
<div class="script_placeholder" data-src="/static/js/crystallography.js"></div>
|
||||
|
||||
% if status in ['unsubmitted', 'correct', 'incorrect', 'partially-correct', 'incomplete']:
|
||||
<div class="status ${status.classname}" id="status_${id}">
|
||||
% endif
|
||||
{% if status == 'unsubmitted' or status == 'correct' or status == 'incorrect' or status == 'partially-correct' or status == 'incomplete' %}
|
||||
<div class="status {{ status.classname }}" id="status_{{ id }}">
|
||||
{% endif %}
|
||||
|
||||
<input type="text" name="input_${id}" aria-describedby="answer_${id}" id="input_${id}" value="${value|h}" style="display:none;"/>
|
||||
<input type="text" name="input_{{ id }}" aria-describedby="answer_{{ id }}" id="input_{{ id }}" value="{{ value }}" style="display:none;"/>
|
||||
|
||||
<%include file="status_span.html" args="status=status, status_id=id"/>
|
||||
{% include "status_span.html" with status=status status_id=id %}
|
||||
|
||||
<p id="answer_${id}" class="answer"></p>
|
||||
<p id="answer_{{ id }}" class="answer"></p>
|
||||
|
||||
% if msg:
|
||||
<span class="message" tabindex="-1">${HTML(msg)}</span>
|
||||
% endif
|
||||
{% if msg %}
|
||||
<span class="message" tabindex="-1">{{ msg|safe }}</span>
|
||||
{% endif %}
|
||||
|
||||
% if status in ['unsubmitted', 'correct', 'incorrect', 'partially-correct', 'incomplete']:
|
||||
{% if status == 'unsubmitted' or status == 'correct' or status == 'incorrect' or status == 'partially-correct' or status == 'incomplete' %}
|
||||
</div>
|
||||
% endif
|
||||
{% endif %}
|
||||
</section>
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<section id="designprotein2dinput_${id}" class="designprotein2dinput">
|
||||
<section id="designprotein2dinput_{{ id }}" class="designprotein2dinput">
|
||||
<div class="script_placeholder" data-src="/static/js/capa/protex/protex.nocache.js?raw"/>
|
||||
<div class="script_placeholder" data-src="${applet_loader}"/>
|
||||
<div class="script_placeholder" data-src="{{ applet_loader }}"/>
|
||||
|
||||
% if status in ['unsubmitted', 'correct', 'incorrect', 'partially-correct', 'incomplete']:
|
||||
<div class="${status.classname}" id="status_${id}">
|
||||
% endif
|
||||
{% if status == 'unsubmitted' or status == 'correct' or status == 'incorrect' or status == 'partially-correct' or status == 'incomplete' %}
|
||||
<div class="{{ status.classname }}" id="status_{{ id }}">
|
||||
{% endif %}
|
||||
|
||||
<div id="protex_container"></div>
|
||||
<input type="hidden" name="target_shape" id="target_shape" value ="${target_shape}"></input>
|
||||
<input type="hidden" name="input_${id}" id="input_${id}" aria-describedby="answer_${id}" value="${value|h}"/>
|
||||
<input type="hidden" name="target_shape" id="target_shape" value ="{{ target_shape }}"></input>
|
||||
<input type="hidden" name="input_{{ id }}" id="input_{{ id }}" aria-describedby="answer_{{ id }}" value="{{ value }}"/>
|
||||
|
||||
<%include file="status_span.html" args="status=status, status_id=id"/>
|
||||
{% include "status_span.html" with status=status status_id=id %}
|
||||
|
||||
<p id="answer_${id}" class="answer"></p>
|
||||
% if status in ['unsubmitted', 'correct', 'incorrect', 'partially-correct', 'incomplete']:
|
||||
<p id="answer_{{ id }}" class="answer"></p>
|
||||
{% if status == 'unsubmitted' or status == 'correct' or status == 'incorrect' or status == 'partially-correct' or status == 'incomplete' %}
|
||||
</div>
|
||||
% endif
|
||||
{% endif %}
|
||||
</section>
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
<%! from openedx.core.djangolib.markup import HTML %>
|
||||
<div id="inputtype_${id}" class="capa_inputtype">
|
||||
<div class="drag_and_drop_problem_div" id="drag_and_drop_div_${id}"
|
||||
data-plain-id="${id}">
|
||||
{% load static %}
|
||||
<div id="inputtype_{{ id }}" class="capa_inputtype">
|
||||
<div class="drag_and_drop_problem_div" id="drag_and_drop_div_{{ id }}"
|
||||
data-plain-id="{{ id }}">
|
||||
</div>
|
||||
|
||||
<div class="drag_and_drop_problem_json" id="drag_and_drop_json_${id}"
|
||||
style="display:none;">${drag_and_drop_json}</div>
|
||||
<div class="drag_and_drop_problem_json" id="drag_and_drop_json_{{ id }}"
|
||||
style="display:none;">{{ drag_and_drop_json|safe }}</div>
|
||||
|
||||
<div class="script_placeholder" data-src="${STATIC_URL}js/capa/drag_and_drop.js"></div>
|
||||
<div class="script_placeholder" data-src="{% static 'js/capa/drag_and_drop.js' %}"></div>
|
||||
|
||||
% if status in ['unsubmitted', 'correct', 'incorrect', 'partially-correct', 'incomplete']:
|
||||
<div class="${status.classname}" id="status_${id}">
|
||||
% endif
|
||||
{% if status == 'unsubmitted' or status == 'correct' or status == 'incorrect' or status == 'partially-correct' or status == 'incomplete' %}
|
||||
<div class="{{ status.classname }}" id="status_{{ id }}">
|
||||
{% endif %}
|
||||
|
||||
|
||||
<input type="text" name="input_${id}" id="input_${id}" aria-describedby="answer_${id}" value="${value|h}"
|
||||
<input type="text" name="input_{{ id }}" id="input_{{ id }}" aria-describedby="answer_{{ id }}" value="{{ value }}"
|
||||
style="display:none;"/>
|
||||
|
||||
|
||||
<p class="indicator-container drag-and-drop--status" aria-describedby="input_${id}">
|
||||
<%include file="status_span.html" args="status=status, status_id=id"/>
|
||||
<p class="indicator-container drag-and-drop--status" aria-describedby="input_{{ id }}">
|
||||
{% include "status_span.html" with status=status status_id=id %}
|
||||
</p>
|
||||
|
||||
<p id="answer_${id}" class="answer"></p>
|
||||
<p id="answer_{{ id }}" class="answer"></p>
|
||||
|
||||
% if msg:
|
||||
<span class="message" tabindex="-1">${HTML(msg)}</span>
|
||||
% endif
|
||||
{% if msg %}
|
||||
<span class="message" tabindex="-1">{{ msg|safe }}</span>
|
||||
{% endif %}
|
||||
|
||||
% if status in ['unsubmitted', 'correct', 'incorrect', 'partially-correct', 'incomplete']:
|
||||
{% if status == 'unsubmitted' or status == 'correct' or status == 'incorrect' or status == 'partially-correct' or status == 'incomplete' %}
|
||||
</div>
|
||||
% endif
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
<section id="editageneinput_${id}" class="editageneinput">
|
||||
<section id="editageneinput_{{ id }}" class="editageneinput">
|
||||
<div class="script_placeholder" data-src="/static/js/capa/genex/genex.nocache.js?raw"/>
|
||||
<div class="script_placeholder" data-src="${applet_loader}"/>
|
||||
<div class="script_placeholder" data-src="{{ applet_loader }}"/>
|
||||
|
||||
% if status in ['unsubmitted', 'correct', 'incorrect', 'partially-correct', 'incomplete']:
|
||||
<div class="${status.classname}">
|
||||
% endif
|
||||
{% if status == 'unsubmitted' or status == 'correct' or status == 'incorrect' or status == 'partially-correct' or status == 'incomplete' %}
|
||||
<div class="{{ status.classname }}">
|
||||
{% endif %}
|
||||
|
||||
<div id="genex_container"></div>
|
||||
<input type="hidden" name="genex_dna_sequence" id="genex_dna_sequence" value ="${genex_dna_sequence}"></input>
|
||||
<input type="hidden" name="genex_problem_number" id="genex_problem_number" value ="${genex_problem_number}"></input>
|
||||
<input type="hidden" name="input_${id}" aria-describedby="answer_${id}" id="input_${id}" value="${value|h}"/>
|
||||
<input type="hidden" name="genex_dna_sequence" id="genex_dna_sequence" value ="{{ genex_dna_sequence }}"></input>
|
||||
<input type="hidden" name="genex_problem_number" id="genex_problem_number" value ="{{ genex_problem_number }}"></input>
|
||||
<input type="hidden" name="input_{{ id }}" aria-describedby="answer_{{ id }}" id="input_{{ id }}" value="{{ value }}"/>
|
||||
|
||||
<p class="indicator-container" aria-describedby="input_${id}">
|
||||
<%include file="status_span.html" args="status=status, status_id=id"/>
|
||||
<p class="indicator-container" aria-describedby="input_{{ id }}">
|
||||
{% include "status_span.html" with status=status status_id=id %}
|
||||
</p>
|
||||
|
||||
<p id="answer_${id}" class="answer"></p>
|
||||
% if status in ['unsubmitted', 'correct', 'incorrect', 'partially-correct', 'incomplete']:
|
||||
<p id="answer_{{ id }}" class="answer"></p>
|
||||
{% if status == 'unsubmitted' or status == 'correct' or status == 'incorrect' or status == 'partially-correct' or status == 'incomplete' %}
|
||||
</div>
|
||||
% endif
|
||||
{% endif %}
|
||||
</section>
|
||||
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
<section id="editamoleculeinput_${id}" class="editamoleculeinput">
|
||||
<div class="script_placeholder" data-src="${applet_loader}"/>
|
||||
<section id="editamoleculeinput_{{ id }}" class="editamoleculeinput">
|
||||
<div class="script_placeholder" data-src="{{ applet_loader }}"/>
|
||||
|
||||
% if status in ['unsubmitted', 'correct', 'incorrect', 'partially-correct', 'incomplete']:
|
||||
<div class="${status.classname}">
|
||||
% endif
|
||||
{% if status == 'unsubmitted' or status == 'correct' or status == 'incorrect' or status == 'partially-correct' or status == 'incomplete' %}
|
||||
<div class="{{ status.classname }}">
|
||||
{% endif %}
|
||||
|
||||
<div id="applet_${id}" class="applet" data-molfile-src="${file}" style="display:block;width:500px;height:400px">
|
||||
<div id="applet_{{ id }}" class="applet" data-molfile-src="{{ file }}" style="display:block;width:500px;height:400px">
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
|
||||
<input type="hidden" name="input_${id}" id="input_${id}" aria-describedby="answer_${id}" value="${value|h}"/>
|
||||
<input type="hidden" name="input_{{ id }}" id="input_{{ id }}" aria-describedby="answer_{{ id }}" value="{{ value }}"/>
|
||||
|
||||
<button id="reset_${id}" class="reset">Reset</button>
|
||||
<button id="reset_{{ id }}" class="reset">Reset</button>
|
||||
|
||||
<p id="answer_${id}" class="answer"></p>
|
||||
<p id="answer_{{ id }}" class="answer"></p>
|
||||
|
||||
<p class="indicator-container" aria-describedby="input_${id}">
|
||||
<%include file="status_span.html" args="status=status, status_id=id"/>
|
||||
<p class="indicator-container" aria-describedby="input_{{ id }}">
|
||||
{% include "status_span.html" with status=status status_id=id %}
|
||||
</p>
|
||||
|
||||
<div class="error_message" style="padding: 5px 5px 5px 5px; background-color:#FA6666; height:60px;width:400px; display: none"></div>
|
||||
|
||||
% if status in ['unsubmitted', 'correct', 'incorrect', 'partially-correct', 'incomplete']:
|
||||
{% if status == 'unsubmitted' or status == 'correct' or status == 'incorrect' or status == 'partially-correct' or status == 'incomplete' %}
|
||||
</div>
|
||||
% endif
|
||||
{% endif %}
|
||||
</section>
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
<%! from openedx.core.djangolib.markup import HTML %>
|
||||
<section id="filesubmission_${id}" class="filesubmission">
|
||||
<section id="filesubmission_{{ id }}" class="filesubmission">
|
||||
<div class="grader-status file">
|
||||
|
||||
<span class="${status.classname}" id="status_${id}">${status.display_name}</span>
|
||||
% if status == 'queued':
|
||||
<span style="display:none;" class="xqueue" id="${id}">${queue_len}</span>
|
||||
% endif
|
||||
<p class="debug">${status}</p>
|
||||
<span class="{{ status.classname }}" id="status_{{ id }}">{{ status.display_name }}</span>
|
||||
{% if status == 'queued' %}
|
||||
<span style="display:none;" class="xqueue" id="{{ id }}">{{ queue_len }}</span>
|
||||
{% endif %}
|
||||
<p class="debug">{{ status }}</p>
|
||||
|
||||
<input type="file" name="input_${id}" id="input_${id}" value="${value}" multiple="multiple" data-required_files="${required_files|h}" data-allowed_files="${allowed_files|h}" aria-label="${response_data['label']}"/>
|
||||
<input type="file" name="input_{{ id }}" id="input_{{ id }}" value="{{ value }}" multiple="multiple" data-required_files="{{ required_files }}" data-allowed_files="{{ allowed_files }}" aria-label="{{ response_data.label }}"/>
|
||||
</div>
|
||||
<div class="message" tabindex="-1">${HTML(msg)}</div>
|
||||
<div class="message" tabindex="-1">{{ msg|safe }}</div>
|
||||
</section>
|
||||
|
||||
@@ -1,36 +1,34 @@
|
||||
<%page expression_filter="h"/>
|
||||
<%! from openedx.core.djangolib.markup import HTML %>
|
||||
<% doinline = 'style="display:inline-block;vertical-align:top"' if inline else "" %>
|
||||
<div id="formulaequationinput_${id}" class="inputtype formulaequationinput" ${doinline | n, decode.utf8}>
|
||||
<div class="${status.classname}">
|
||||
% if response_data['label']:
|
||||
<label class="problem-group-label" for="input_${id}" id="label_${id}">${response_data['label']}</label>
|
||||
% endif
|
||||
% for description_id, description_text in response_data['descriptions'].items():
|
||||
<p class="question-description" id="${description_id}">${description_text}</p>
|
||||
% endfor
|
||||
<input type="text" name="input_${id}" id="input_${id}"
|
||||
data-input-id="${id}" value="${value}"
|
||||
${describedby_html}
|
||||
% if size:
|
||||
size="${size}"
|
||||
% endif
|
||||
{% load static %}
|
||||
<div id="formulaequationinput_{{ id }}" class="inputtype formulaequationinput" {% if inline %}style="display:inline-block;vertical-align:top"{% endif %}>
|
||||
<div class="{{ status.classname }}">
|
||||
{% if response_data.label %}
|
||||
<label class="problem-group-label" for="input_{{ id }}" id="label_{{ id }}">{{ response_data.label }}</label>
|
||||
{% endif %}
|
||||
{% for description_id, description_text in response_data.descriptions.items %}
|
||||
<p class="question-description" id="{{ description_id }}">{{ description_text }}</p>
|
||||
{% endfor %}
|
||||
<input type="text" name="input_{{ id }}" id="input_{{ id }}"
|
||||
data-input-id="{{ id }}" value="{{ value }}"
|
||||
{{ describedby_html }}
|
||||
{% if size %}
|
||||
size="{{ size }}"
|
||||
{% endif %}
|
||||
/>
|
||||
<span class="trailing_text" id="trailing_text_${id}">${trailing_text}</span>
|
||||
<span class="trailing_text" id="trailing_text_{{ id }}">{{ trailing_text }}</span>
|
||||
|
||||
<%include file="status_span.html" args="status=status, status_id=id"/>
|
||||
{% include "status_span.html" with status=status status_id=id %}
|
||||
|
||||
<p id="answer_${id}" class="answer"></p>
|
||||
<p id="answer_{{ id }}" class="answer"></p>
|
||||
|
||||
<div id="input_${id}_preview" class="equation">
|
||||
<div id="input_{{ id }}_preview" class="equation">
|
||||
\(\)
|
||||
<img src="${STATIC_URL}images/spinner.gif" class="loading" alt="Loading"/>
|
||||
<img src="{% static 'images/spinner.gif' %}" class="loading" alt="Loading"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="script_placeholder" data-src="${previewer}"/>
|
||||
<div class="script_placeholder" data-src="{{ previewer }}"/>
|
||||
|
||||
% if msg:
|
||||
<span class="message" aria-describedby="label_${id}" tabindex="-1">${HTML(msg)}</span>
|
||||
% endif
|
||||
{% if msg %}
|
||||
<span class="message" aria-describedby="label_{{ id }}" tabindex="-1">{{ msg|safe }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
<%page expression_filter="h"/>
|
||||
<div class="imageinput capa_inputtype" id="inputtype_${id}">
|
||||
{% load static %}
|
||||
<div class="imageinput capa_inputtype" id="inputtype_{{ id }}">
|
||||
<input
|
||||
type="hidden"
|
||||
class="imageinput"
|
||||
src="${src}"
|
||||
name="input_${id}"
|
||||
id="input_${id}"
|
||||
value="${value}"
|
||||
src="{{ src }}"
|
||||
name="input_{{ id }}"
|
||||
id="input_{{ id }}"
|
||||
value="{{ value }}"
|
||||
/>
|
||||
<div style="position:relative;">
|
||||
<div
|
||||
id="imageinput_${id}"
|
||||
id="imageinput_{{ id }}"
|
||||
style="
|
||||
background-image: url('${src}');
|
||||
width: ${width}px;
|
||||
height: ${height}px;
|
||||
background-image: url('{{ src }}');
|
||||
width: {{ width }}px;
|
||||
height: {{ height }}px;
|
||||
position: relative;
|
||||
left: 0;
|
||||
top: 0;"
|
||||
>
|
||||
<img
|
||||
src="${STATIC_URL}images/green-pointer.png"
|
||||
id="cross_${id}"
|
||||
style="position: absolute; top: ${gy}px; left: ${gx}px;"
|
||||
src="{% static 'images/green-pointer.png' %}"
|
||||
id="cross_{{ id }}"
|
||||
style="position: absolute; top: {{ gy }}px; left: {{ gx }}px;"
|
||||
alt="Selection indicator"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
data-width="${width}"
|
||||
data-height="${height}"
|
||||
id="answer_${id}"
|
||||
data-width="{{ width }}"
|
||||
data-height="{{ height }}"
|
||||
id="answer_{{ id }}"
|
||||
style="
|
||||
position: absolute;
|
||||
left: 0;
|
||||
@@ -38,8 +38,8 @@
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
(new ImageInput('${id | n, decode.utf8}'));
|
||||
(new ImageInput('{{ id }}'));
|
||||
</script>
|
||||
|
||||
<%include file="status_span.html" args="status=status, status_id=id"/>
|
||||
{% include "status_span.html" with status=status status_id=id %}
|
||||
</div>
|
||||
|
||||
@@ -1,59 +1,57 @@
|
||||
<%page expression_filter="h"/>
|
||||
<%! from openedx.core.djangolib.markup import HTML %>
|
||||
<div id="inputtype_${id}" class="jsinput"
|
||||
data="${gradefn}"
|
||||
% if saved_state:
|
||||
data-stored="${saved_state}"
|
||||
% endif
|
||||
% if initial_state:
|
||||
data-initial-state="${initial_state}"
|
||||
% endif
|
||||
% if get_statefn:
|
||||
data-getstate="${get_statefn}"
|
||||
% endif
|
||||
% if set_statefn:
|
||||
data-setstate="${set_statefn}"
|
||||
% endif
|
||||
% if sop:
|
||||
data-sop="${sop}"
|
||||
% endif
|
||||
<div id="inputtype_{{ id }}" class="jsinput"
|
||||
data="{{ gradefn }}"
|
||||
{% if saved_state %}
|
||||
data-stored="{{ saved_state }}"
|
||||
{% endif %}
|
||||
{% if initial_state %}
|
||||
data-initial-state="{{ initial_state }}"
|
||||
{% endif %}
|
||||
{% if get_statefn %}
|
||||
data-getstate="{{ get_statefn }}"
|
||||
{% endif %}
|
||||
{% if set_statefn %}
|
||||
data-setstate="{{ set_statefn }}"
|
||||
{% endif %}
|
||||
{% if sop %}
|
||||
data-sop="{{ sop }}"
|
||||
{% endif %}
|
||||
data-processed="false"
|
||||
>
|
||||
|
||||
<div class="script_placeholder" data-src="${jschannel_loader}"/>
|
||||
<div class="script_placeholder" data-src="${jsinput_loader}"/>
|
||||
% if status in ['unsubmitted', 'submitted', 'correct', 'incorrect', 'partially-correct', 'incomplete']:
|
||||
<div class="${status.classname}">
|
||||
% endif
|
||||
<div class="script_placeholder" data-src="{{ jschannel_loader }}"/>
|
||||
<div class="script_placeholder" data-src="{{ jsinput_loader }}"/>
|
||||
{% if status == 'unsubmitted' or status == 'submitted' or status == 'correct' or status == 'incorrect' or status == 'partially-correct' or status == 'incomplete' %}
|
||||
<div class="{{ status.classname }}">
|
||||
{% endif %}
|
||||
|
||||
<iframe name="iframe_${id}"
|
||||
id="iframe_${id}"
|
||||
<iframe name="iframe_{{ id }}"
|
||||
id="iframe_{{ id }}"
|
||||
sandbox="allow-scripts allow-popups allow-same-origin allow-forms allow-pointer-lock allow-downloads"
|
||||
seamless="seamless"
|
||||
frameborder="0"
|
||||
src="${html_file}"
|
||||
height="${height}"
|
||||
width="${width}"
|
||||
title="${title}"
|
||||
src="{{ html_file }}"
|
||||
height="{{ height }}"
|
||||
width="{{ width }}"
|
||||
title="{{ title }}"
|
||||
/>
|
||||
<input type="hidden" name="input_${id}" id="input_${id}"
|
||||
<input type="hidden" name="input_{{ id }}" id="input_{{ id }}"
|
||||
waitfor=""
|
||||
value="${value}"/>
|
||||
value="{{ value }}"/>
|
||||
|
||||
<br/>
|
||||
<p id="answer_${id}" class="answer"></p>
|
||||
<p id="answer_{{ id }}" class="answer"></p>
|
||||
|
||||
<div class="indicator-container">
|
||||
<%include file="status_span.html" args="status=status, status_id=id"/>
|
||||
{% include "status_span.html" with status=status status_id=id %}
|
||||
</div>
|
||||
|
||||
<div class="error_message" style="padding: 5px 5px 5px 5px; background-color:#FA6666; height:60px;width:400px; display: none"></div>
|
||||
|
||||
% if status in ['unsubmitted', 'submitted', 'correct', 'incorrect', 'partially-correct', 'incomplete']:
|
||||
{% if status == 'unsubmitted' or status == 'submitted' or status == 'correct' or status == 'incorrect' or status == 'partially-correct' or status == 'incomplete' %}
|
||||
</div>
|
||||
% endif
|
||||
{% endif %}
|
||||
|
||||
% if msg:
|
||||
<span class="message" tabindex="-1">${HTML(msg)}</span>
|
||||
% endif
|
||||
{% if msg %}
|
||||
<span class="message" tabindex="-1">{{ msg|safe }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<section class="math-string">
|
||||
% if isinline:
|
||||
<span>[mathjaxinline]${mathstr}[/mathjaxinline]</span>
|
||||
% else:
|
||||
<span>[mathjax]${mathstr}[/mathjax]</span>
|
||||
% endif
|
||||
<span>${tail}</span>
|
||||
{% if isinline %}
|
||||
<span>[mathjaxinline]{{ mathstr }}[/mathjaxinline]</span>
|
||||
{% else %}
|
||||
<span>[mathjax]{{ mathstr }}[/mathjax]</span>
|
||||
{% endif %}
|
||||
<span>{{ tail|safe }}</span>
|
||||
</section>
|
||||
|
||||
@@ -1,51 +1,50 @@
|
||||
<%page expression_filter="h"/>
|
||||
<section id="textbox_${id}" class="capa_inputtype cminput">
|
||||
<div class="script_placeholder" data-src="${matlab_editor_js}"></div>
|
||||
<section id="textbox_{{ id }}" class="capa_inputtype cminput">
|
||||
<div class="script_placeholder" data-src="{{ matlab_editor_js }}"></div>
|
||||
<textarea
|
||||
rows="${rows}"
|
||||
cols="${cols}"
|
||||
name="input_${id}"
|
||||
aria-describedby="answer_${id}"
|
||||
id="input_${id}"
|
||||
data-tabsize="${tabsize}"
|
||||
rows="{{ rows }}"
|
||||
cols="{{ cols }}"
|
||||
name="input_{{ id }}"
|
||||
aria-describedby="answer_{{ id }}"
|
||||
id="input_{{ id }}"
|
||||
data-tabsize="{{ tabsize }}"
|
||||
data-mode="octave"
|
||||
% if linenumbers:
|
||||
{% if linenumbers %}
|
||||
data-linenums="true"
|
||||
% endif
|
||||
% if hidden:
|
||||
{% endif %}
|
||||
{% if hidden %}
|
||||
style="display:none;"
|
||||
% endif
|
||||
>${value}</textarea>
|
||||
{% endif %}
|
||||
>{{ value }}</textarea>
|
||||
|
||||
<div class="grader-status" tabindex="-1">
|
||||
|
||||
<%include file="status_span.html" args="status=status, status_id=id"/>
|
||||
{% include "status_span.html" with status=status status_id=id %}
|
||||
|
||||
% if status == 'queued':
|
||||
<span style="display:none;" class="xqueue" id="${id}">${queue_len}</span>
|
||||
% endif
|
||||
{% if status == 'queued' %}
|
||||
<span style="display:none;" class="xqueue" id="{{ id }}">{{ queue_len }}</span>
|
||||
{% endif %}
|
||||
|
||||
% if hidden:
|
||||
<div style="display:none;" name="${hidden}" inputid="input_${id}" />
|
||||
% endif
|
||||
{% if hidden %}
|
||||
<div style="display:none;" name="{{ hidden }}" inputid="input_{{ id }}" />
|
||||
{% endif %}
|
||||
|
||||
<p class="debug">${status.display_name}</p>
|
||||
<p class="debug">{{ status.display_name }}</p>
|
||||
</div>
|
||||
|
||||
<span id="answer_${id}"></span>
|
||||
<span id="answer_{{ id }}"></span>
|
||||
|
||||
<div class="external-grader-message" aria-live="polite">
|
||||
${msg|n, decode.utf8}
|
||||
{{ msg|safe }}
|
||||
</div>
|
||||
<div class="ungraded-matlab-result" aria-live="polite">
|
||||
${queue_msg|n, decode.utf8}
|
||||
{{ queue_msg|safe }}
|
||||
</div>
|
||||
|
||||
% if button_enabled:
|
||||
{% if button_enabled %}
|
||||
<div class="plot-button">
|
||||
<input type="button" class="save" name="plot-button" id="plot_${id}" value="Run Code" />
|
||||
<input type="button" class="save" name="plot-button" id="plot_{{ id }}" value="Run Code" />
|
||||
</div>
|
||||
%endif
|
||||
{% endif %}
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function(){
|
||||
@@ -67,7 +66,7 @@
|
||||
var plot = function(event) {
|
||||
var problem_elt = $(event.target).closest('.problems-wrapper');
|
||||
url = $(event.target).closest('.problems-wrapper').data('url');
|
||||
input_id = "${id|n, decode.utf8}";
|
||||
input_id = "{{ id|safe }}";
|
||||
|
||||
// save the codemirror text to the textarea
|
||||
// since there could be multiple codemirror instances on the page,
|
||||
@@ -75,7 +74,7 @@
|
||||
$('.CodeMirror').each(function(i, el){
|
||||
el.CodeMirror.save();
|
||||
});
|
||||
var input = $("#input_${id|n, decode.utf8}");
|
||||
var input = $("#input_{{ id|safe }}");
|
||||
|
||||
// pull out the coded text
|
||||
submission = input.val();
|
||||
@@ -134,7 +133,7 @@
|
||||
// save the answer
|
||||
$.postWithPrefix(url + '/problem_save', answer, save_callback);
|
||||
};
|
||||
$('#plot_${id|n, decode.utf8}').click(plot);
|
||||
$('#plot_{{ id|safe }}').click(plot);
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -1,32 +1,28 @@
|
||||
<%page expression_filter="h"/>
|
||||
<%! from openedx.core.djangolib.markup import HTML %>
|
||||
<% doinline = "inline" if inline else "" %>
|
||||
<div class="inputtype option-input {% if inline %}inline{% endif %}">
|
||||
{% if response_data.label %}
|
||||
<label class="problem-group-label" for="input_{{ id }}" id="label_{{ id }}">{{ response_data.label }}</label>
|
||||
{% endif %}
|
||||
|
||||
<div class="inputtype option-input ${doinline}">
|
||||
% if response_data['label']:
|
||||
<label class="problem-group-label" for="input_${id}" id="label_${id}">${response_data['label']}</label>
|
||||
% endif
|
||||
{% for description_id, description_text in response_data.descriptions.items %}
|
||||
<p class="question-description" id="{{ description_id }}">{{ description_text|safe }}</p>
|
||||
{% endfor %}
|
||||
|
||||
% for description_id, description_text in response_data['descriptions'].items():
|
||||
<p class="question-description" id="${description_id}">${description_text}</p>
|
||||
% endfor
|
||||
|
||||
<select name="input_${id}" id="input_${id}" ${describedby_html}>
|
||||
<option value="option_${id}_dummy_default">${default_option_text}</option>
|
||||
% for option_id, option_description in options:
|
||||
<option value="${option_id}"
|
||||
% if (option_id == value or option_id == answervariable):
|
||||
<select name="input_{{ id }}" id="input_{{ id }}" {{ describedby_html }}>
|
||||
<option value="option_{{ id }}_dummy_default">{{ default_option_text }}</option>
|
||||
{% for option_id, option_description in options %}
|
||||
<option value="{{ option_id }}"
|
||||
{% if option_id == value or option_id == answervariable %}
|
||||
selected="true"
|
||||
% endif
|
||||
> ${option_description}</option>
|
||||
% endfor
|
||||
{% endif %}
|
||||
> {{ option_description }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
||||
<div class="indicator-container">
|
||||
<%include file="status_span.html" args="status=status, status_id=id"/>
|
||||
{% include "status_span.html" with status=status status_id=id %}
|
||||
</div>
|
||||
<p class="answer" id="answer_${id}"></p>
|
||||
% if msg:
|
||||
<span class="message" aria-describedby="label_${id}" tabindex="-1">${HTML(msg)}</span>
|
||||
% endif
|
||||
<p class="answer" id="answer_{{ id }}"></p>
|
||||
{% if msg %}
|
||||
<span class="message" aria-describedby="label_{{ id }}" tabindex="-1">{{ msg|safe }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
123
xmodule/capa/templates/problem.html
Normal file
123
xmodule/capa/templates/problem.html
Normal file
@@ -0,0 +1,123 @@
|
||||
{% load i18n %}
|
||||
|
||||
<h3 class="hd hd-3 problem-header" id="{{ short_id }}-problem-title" aria-describedby="{{ id }}-problem-progress" tabindex="-1">
|
||||
{{ problem.name }}
|
||||
</h3>
|
||||
|
||||
<div class="problem-progress" id="{{ id }}-problem-progress"></div>
|
||||
|
||||
<div class="problem">
|
||||
{{ problem.html|safe }}
|
||||
<div class="action">
|
||||
<input type="hidden" name="problem_id" value="{{ problem.name }}" />
|
||||
{% if demand_hint_possible %}
|
||||
<div class="problem-hint">
|
||||
{% include "problem_notifications.html" with notification_name='hint' notification_type='problem-hint' notification_icon='fa-question' notification_message='' %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="problem-action-buttons-wrapper">
|
||||
{% if demand_hint_possible %}
|
||||
<span class="problem-action-button-wrapper">
|
||||
<button type="button" class="hint-button problem-action-btn btn-link btn-small" data-value="{% trans 'Hint' as hint_val %}{{ hint_val|force_escape }}" {% if not should_enable_next_hint %}disabled{% endif %}>{% trans "Hint" as hint_text %}{{ hint_text|force_escape }}</button>
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if save_button %}
|
||||
<span class="problem-action-button-wrapper">
|
||||
<button type="button" class="save problem-action-btn btn-link btn-small" data-value="{% trans 'Save' as save_val %}{{ save_val|force_escape }}">
|
||||
<span aria-hidden="true">{% trans "Save" as save_text %}{{ save_text|force_escape }}</span>
|
||||
<span class="sr">{% trans "Save your answer" as save_sr %}{{ save_sr|force_escape }}</span>
|
||||
</button>
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if attempts_used and reset_button %}
|
||||
<span class="problem-action-button-wrapper">
|
||||
<button type="button" class="reset problem-action-btn btn-link btn-small" data-value="{% trans 'Reset' as reset_val %}{{ reset_val|force_escape }}"><span aria-hidden="true">{% trans "Reset" as reset_text %}{{ reset_text|force_escape }}</span><span class="sr">{% trans "Reset your answer" as reset_sr %}{{ reset_sr|force_escape }}</span></button>
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if answer_available %}
|
||||
<span class="problem-action-button-wrapper">
|
||||
<button type="button" class="show problem-action-btn btn-link btn-small" aria-describedby="{{ short_id }}-problem-title"><span class="show-label">{% trans "Show answer" as show_ans %}{{ show_ans|force_escape }}</span></button>
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="submit-attempt-container">
|
||||
<button type="button" class="submit btn-brand" data-submitting="{{ submit_button_submitting }}" data-value="{{ submit_button }}" data-should-enable-submit-button="{{ should_enable_submit_button }}" aria-describedby="submission_feedback_{{ short_id }}"{% if not should_enable_submit_button %}disabled{% endif %}>
|
||||
<span class="submit-label">{{ submit_button }}</span>
|
||||
</button>
|
||||
|
||||
{% if submit_disabled_cta %}
|
||||
{% if submit_disabled_cta.event_data %}
|
||||
<button class="submit-cta-link-button btn-link btn-small" onclick="emit_event('{{ submit_disabled_cta.event_data }}')">
|
||||
{{ submit_disabled_cta.link_name }}
|
||||
</button>
|
||||
<span class="submit-cta-description" tabindex="0" role="note" aria-label="description">
|
||||
<span data-tooltip="{{ submit_disabled_cta.description }}" data-tooltip-show-on-click="true"
|
||||
class="fa fa-info-circle fa-lg" aria-hidden="true">
|
||||
</span>
|
||||
</span>
|
||||
<span class="sr">({{ submit_disabled_cta.description }})</span>
|
||||
{% else %}
|
||||
<form class="submit-cta" method="post" action="{{ submit_disabled_cta.link }}">
|
||||
{% if submit_disabled_cta.link %}
|
||||
<input type="hidden" id="csrf_token" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
|
||||
{% for form_name, form_value in submit_disabled_cta.form_values.items %}
|
||||
<input type="hidden" name="{{ form_name }}" value="{{ form_value }}">
|
||||
{% endfor %}
|
||||
<button class="submit-cta-link-button btn-link btn-small">
|
||||
{{ submit_disabled_cta.link_name }}
|
||||
</button>
|
||||
{% endif %}
|
||||
<span class="submit-cta-description" tabindex="0" role="note" aria-label="description">
|
||||
<span data-tooltip="{{ submit_disabled_cta.description }}" data-tooltip-show-on-click="true"
|
||||
class="fa fa-info-circle fa-lg" aria-hidden="true">
|
||||
</span>
|
||||
</span>
|
||||
<span class="sr">({{ submit_disabled_cta.description }})</span>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<div class="submission-feedback {% if submit_disabled_cta %}cta-enabled{% endif %}" id="submission_feedback_{{ short_id }}">
|
||||
{% comment %} When attempts are not 0, the CTA above will contain a message about the number of used attempts {% endcomment %}
|
||||
{% if attempts_allowed and not submit_disabled_cta or attempts_allowed and attempts_used == 0 %}
|
||||
{% filter force_escape %}{% blocktrans count num_total=attempts_allowed %}You have used {{ attempts_used }} of {{ num_total }} attempt.{% plural %}You have used {{ attempts_used }} of {{ num_total }} attempts{% endblocktrans %}{% endfilter %}
|
||||
{% endif %}
|
||||
{% if grading_method %}
|
||||
<div>{% trans "Grading method:" as grading_text %}{{ grading_text|force_escape }} {{ grading_method }}</div>
|
||||
{% endif %}
|
||||
<span class="sr">{% trans "Some problems have options such as save, reset, hints, or show answer. These options follow the Submit button." as options_sr %}{{ options_sr|force_escape }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% include "problem_notifications.html" with notification_type='warning' notification_icon='fa-exclamation-circle' notification_name='gentle-alert' notification_message='' %}
|
||||
{% if answer_notification_type %}
|
||||
{% if answer_notification_type == 'correct' %}
|
||||
{% include "problem_notifications.html" with notification_type='success' notification_icon='fa-check' notification_name='submit' is_hidden=False notification_message=answer_notification_message %}
|
||||
{% endif %}
|
||||
{% if answer_notification_type == 'incorrect' %}
|
||||
{% include "problem_notifications.html" with notification_type='error' notification_icon='fa-close' notification_name='submit' is_hidden=False notification_message=answer_notification_message %}
|
||||
{% endif %}
|
||||
{% if answer_notification_type == 'partially-correct' %}
|
||||
{% include "problem_notifications.html" with notification_type='success' notification_icon='fa-asterisk' notification_name='submit' is_hidden=False notification_message=answer_notification_message %}
|
||||
{% endif %}
|
||||
{% if answer_notification_type == 'submitted' %}
|
||||
{% include "problem_notifications.html" with notification_type='general' notification_icon='fa-info-circle' notification_name='submit' is_hidden=False notification_message=answer_notification_message %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if has_saved_answers %}
|
||||
{% include "problem_notifications.html" with notification_type='warning' notification_icon='fa-save' notification_name='save' notification_message=save_message is_hidden=False %}
|
||||
{% else %}
|
||||
{% include "problem_notifications.html" with notification_type='warning' notification_icon='fa-save' notification_name='save' notification_message=save_message is_hidden=True %}
|
||||
{% endif %}
|
||||
{# xss-lint: disable=django-trans-missing-escape #}
|
||||
{% trans "Answers are displayed within the problem" as notification_message %}
|
||||
{% with notification_message=notification_message|force_escape %}
|
||||
{% include "problem_notifications.html" with notification_type='general' notification_icon='fa-info-circle' notification_name='show-answer' notification_message=notification_message is_hidden=True %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function emit_event(message) {
|
||||
parent.postMessage(message, '*');
|
||||
}
|
||||
</script>
|
||||
13
xmodule/capa/templates/problem_ajax.html
Normal file
13
xmodule/capa/templates/problem_ajax.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<div id="problem_{{ element_id }}" class="problems-wrapper" role="group"
|
||||
aria-labelledby="{{ element_id }}-problem-title"
|
||||
data-problem-id="{{ id }}" data-url="{{ ajax_url }}"
|
||||
data-problem-score="{{ current_score }}"
|
||||
data-problem-total-possible="{{ total_possible }}"
|
||||
data-attempts-used="{{ attempts_used }}"
|
||||
data-content="{{ content }}"
|
||||
data-graded="{{ graded }}">
|
||||
<p class="loading-spinner">
|
||||
<i class="fa fa-spinner fa-pulse fa-2x fa-fw"></i>
|
||||
<span class="sr">Loading…</span>
|
||||
</p>
|
||||
</div>
|
||||
17
xmodule/capa/templates/problem_notifications.html
Normal file
17
xmodule/capa/templates/problem_notifications.html
Normal file
@@ -0,0 +1,17 @@
|
||||
{% load i18n %}
|
||||
|
||||
<div class="notification {{ notification_type }} notification-{{ notification_name }}
|
||||
{% if is_hidden != False %}is-hidden{% endif %}"
|
||||
tabindex="-1">
|
||||
<span class="icon fa {{ notification_icon }}" aria-hidden="true"></span>
|
||||
<span class="notification-message" aria-describedby="{{ short_id }}-problem-title">{{ notification_message }}
|
||||
</span>
|
||||
<div class="notification-btn-wrapper">
|
||||
{% if notification_name == 'hint' %}
|
||||
<button type="button" class="btn btn-default btn-small notification-btn hint-button">
|
||||
{% trans "Next Hint" as next_hint_text %}{{ next_hint_text|force_escape }}
|
||||
</button>
|
||||
{% endif %}
|
||||
<button type="button" class="btn btn-default btn-small notification-btn review-btn sr">{% trans "Review" as review_text %}{{ review_text|force_escape }}</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,24 +1,23 @@
|
||||
<%! from xmodule.capa.util import remove_markup %>
|
||||
<div>
|
||||
<div class="script_placeholder" data-src="${setup_script}"/>
|
||||
<div class="script_placeholder" data-src="{{ setup_script }}"/>
|
||||
<input type="hidden"
|
||||
class="schematic"
|
||||
height="${height}"
|
||||
width="${width}"
|
||||
parts="${parts}"
|
||||
analyses="${analyses}"
|
||||
name="input_${id}"
|
||||
id="input_${id}"
|
||||
aria-label="${remove_markup(response_data['label'])}"
|
||||
aria-describedby="answer_${id}"
|
||||
value="${value|h}"
|
||||
initial_value="${initial_value|h}"
|
||||
submit_analyses="${submit_analyses|h}"
|
||||
height="{{ height }}"
|
||||
width="{{ width }}"
|
||||
parts="{{ parts }}"
|
||||
analyses="{{ analyses }}"
|
||||
name="input_{{ id }}"
|
||||
id="input_{{ id }}"
|
||||
aria-label="{{ response_data.label|striptags }}"
|
||||
aria-describedby="answer_{{ id }}"
|
||||
value="{{ value }}"
|
||||
initial_value="{{ initial_value }}"
|
||||
submit_analyses="{{ submit_analyses }}"
|
||||
/>
|
||||
|
||||
<span id="answer_${id}"></span>
|
||||
<span id="answer_{{ id }}"></span>
|
||||
<div class="indicator-container">
|
||||
<%include file="status_span.html" args="status=status, status_id=id"/>
|
||||
{% include "status_span.html" with status=status status_id=id %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
<%page expression_filter="h"/>
|
||||
<div class="solution-span">
|
||||
<span id="solution_${id}"></span>
|
||||
<span id="solution_{{ id }}"></span>
|
||||
</div>
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
<%page expression_filter="h" args="status, status_id='', hide_correctness=False"/>
|
||||
|
||||
% if status_id == '':
|
||||
<span class="status ${'' if hide_correctness == True else status.classname}"
|
||||
data-tooltip="${'' if hide_correctness == True else status.display_tooltip}">
|
||||
% else:
|
||||
<span class="status ${'' if hide_correctness == True else status.classname}" id="status_${status_id}"
|
||||
data-tooltip="${'' if hide_correctness == True else status.display_tooltip}">
|
||||
% endif
|
||||
% if hide_correctness == False:
|
||||
<span class="sr">${status.display_name}</span><span class="status-icon" aria-hidden="true"></span>
|
||||
% endif
|
||||
{% if status_id == '' %}
|
||||
<span class="status {% if hide_correctness == True %}{% else %}{{ status.classname }}{% endif %}"
|
||||
data-tooltip="{% if hide_correctness == True %}{% else %}{{ status.display_tooltip }}{% endif %}">
|
||||
{% else %}
|
||||
<span class="status {% if hide_correctness == True %}{% else %}{{ status.classname }}{% endif %}" id="status_{{ status_id }}"
|
||||
data-tooltip="{% if hide_correctness == True %}{% else %}{{ status.display_tooltip }}{% endif %}">
|
||||
{% endif %}
|
||||
{% if not hide_correctness %}
|
||||
<span class="sr">{{ status.display_name }}</span><span class="status-icon" aria-hidden="true"></span>
|
||||
{% endif %}
|
||||
</span>
|
||||
|
||||
@@ -1,53 +1,49 @@
|
||||
<%page expression_filter="h"/>
|
||||
<%! from openedx.core.djangolib.markup import HTML %>
|
||||
<% doinline = "inline" if inline else "" %>
|
||||
<div id="inputtype_{{ id }}" {% if do_math and inline %} class="text-input-dynamath capa_inputtype inline textline" {% elif do_math %} class="text-input-dynamath capa_inputtype textline" {% elif inline %} class=" capa_inputtype inline textline" {% else %} class=" capa_inputtype textline" {% endif %}>
|
||||
{% if preprocessor is not None %}
|
||||
<div class="text-input-dynamath_data {% if inline %}inline{% endif %}" data-preprocessor="{{ preprocessor.class_name }}"/>
|
||||
<div class="script_placeholder" data-src="{{ preprocessor.script_src }}"/>
|
||||
{% endif %}
|
||||
|
||||
<div id="inputtype_${id}" class="${'text-input-dynamath' if do_math else ''} capa_inputtype ${doinline} textline">
|
||||
% if preprocessor is not None:
|
||||
<div class="text-input-dynamath_data ${doinline}" data-preprocessor="${preprocessor['class_name']}"/>
|
||||
<div class="script_placeholder" data-src="${preprocessor['script_src']}"/>
|
||||
% endif
|
||||
{% if status == 'unsubmitted' or status == 'submitted' or status == 'correct' or status == 'incorrect' or status == 'partially-correct' or status == 'incomplete' %}
|
||||
<div class="{{ status.classname }} {% if inline %}inline{% endif %}">
|
||||
{% endif %}
|
||||
|
||||
% if status in ('unsubmitted', 'submitted', 'correct', 'incorrect', 'partially-correct', 'incomplete'):
|
||||
<div class="${status.classname} ${doinline}">
|
||||
% endif
|
||||
{% if hidden %}
|
||||
<div style="display:none;" name="{{ hidden }}" inputid="input_{{ id }}" />
|
||||
{% endif %}
|
||||
|
||||
% if hidden:
|
||||
<div style="display:none;" name="${hidden}" inputid="input_${id}" />
|
||||
% endif
|
||||
{% if response_data.label %}
|
||||
<label class="problem-group-label" for="input_{{ id }}" id="label_{{ id }}">{{ response_data.label }}</label>
|
||||
{% endif %}
|
||||
|
||||
% if response_data['label']:
|
||||
<label class="problem-group-label" for="input_${id}" id="label_${id}">${response_data['label']}</label>
|
||||
% endif
|
||||
|
||||
% for description_id, description_text in response_data['descriptions'].items():
|
||||
<p class="question-description" id="${description_id}">${description_text}</p>
|
||||
% endfor
|
||||
<input type="text" class="mw-100 ${'math' if do_math else ''}" name="input_${id}" id="input_${id}" ${describedby_html} value="${value}"
|
||||
% if size:
|
||||
size="${size}"
|
||||
% endif
|
||||
% if hidden:
|
||||
{% for description_id, description_text in response_data.descriptions.items %}
|
||||
<p class="question-description" id="{{ description_id }}">{{ description_text|safe }}</p>
|
||||
{% endfor %}
|
||||
<input type="text" class="mw-100 {% if do_math %}math{% endif %}" name="input_{{ id }}" id="input_{{ id }}" {{ describedby_html }} value="{{ value }}"
|
||||
{% if size %}
|
||||
size="{{ size }}"
|
||||
{% endif %}
|
||||
{% if hidden %}
|
||||
style="display:none;"
|
||||
% endif
|
||||
{% endif %}
|
||||
/>
|
||||
<span class="trailing_text" id="trailing_text_${id}">${trailing_text}</span>
|
||||
<span class="trailing_text" id="trailing_text_{{ id }}">{{ trailing_text }}</span>
|
||||
|
||||
<%include file="status_span.html" args="status=status, status_id=id"/>
|
||||
{% include "status_span.html" with status=status status_id=id %}
|
||||
|
||||
<p id="answer_${id}" class="answer"></p>
|
||||
<p id="answer_{{ id }}" class="answer"></p>
|
||||
|
||||
% if do_math:
|
||||
<div id="display_${id}" class="equation">`{::}`</div>
|
||||
<textarea style="display:none" id="input_${id}_dynamath" name="input_${id}_dynamath"></textarea>
|
||||
% endif
|
||||
{% if do_math %}
|
||||
<div id="display_{{ id }}" class="equation">`{::}`</div>
|
||||
<textarea style="display:none" id="input_{{ id }}_dynamath" name="input_{{ id }}_dynamath"></textarea>
|
||||
{% endif %}
|
||||
|
||||
% if status in ('unsubmitted', 'submitted', 'correct', 'incorrect', 'partially-correct', 'incomplete'):
|
||||
{% if status == 'unsubmitted' or status == 'submitted' or status == 'correct' or status == 'incorrect' or status == 'partially-correct' or status == 'incomplete' %}
|
||||
</div>
|
||||
% endif
|
||||
{% endif %}
|
||||
|
||||
% if msg:
|
||||
<span class="message" aria-describedby="label_${id}" tabindex="-1">${HTML(msg)}</span>
|
||||
% endif
|
||||
{% if msg %}
|
||||
<span class="message" aria-describedby="label_{{ id }}" tabindex="-1">{{ msg|safe }}</span>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,35 +1,34 @@
|
||||
<%! from openedx.core.djangolib.markup import HTML %>
|
||||
<section id="inputtype_${id}" class="capa_inputtype" >
|
||||
<section id="inputtype_{{ id }}" class="capa_inputtype" >
|
||||
<table><tr><td height='600'>
|
||||
<div id="vsepr_div_${id}" style="position:relative;" data-molecules="${molecules}" data-geometries="${geometries}">
|
||||
<canvas id="vsepr_canvas_${id}" width="${width}" height="${height}">
|
||||
<div id="vsepr_div_{{ id }}" style="position:relative;" data-molecules="{{ molecules }}" data-geometries="{{ geometries }}">
|
||||
<canvas id="vsepr_canvas_{{ id }}" width="{{ width }}" height="{{ height }}">
|
||||
</canvas>
|
||||
</div>
|
||||
</td><td valign ='top'>
|
||||
<select class="molecule_select" id="molecule_select_${id}" size="18">
|
||||
<select class="molecule_select" id="molecule_select_{{ id }}" size="18">
|
||||
</select>
|
||||
</td></tr></table>
|
||||
|
||||
<div class="script_placeholder" data-src="/static/js/vsepr/vsepr.js"></div>
|
||||
|
||||
% if status in ['unsubmitted', 'correct', 'incorrect', 'partially-correct', 'incomplete']:
|
||||
<div class="${status.classname}" id="status_${id}">
|
||||
% endif
|
||||
{% if status == 'unsubmitted' or status == 'correct' or status == 'incorrect' or status == 'partially-correct' or status == 'incomplete' %}
|
||||
<div class="{{ status.classname }}" id="status_{{ id }}">
|
||||
{% endif %}
|
||||
|
||||
<input type="text" name="input_${id}" id="input_${id}" aria-describedby="answer_${id}" value="${value|h}"
|
||||
<input type="text" name="input_{{ id }}" id="input_{{ id }}" aria-describedby="answer_{{ id }}" value="{{ value }}"
|
||||
style="display:none;"
|
||||
/>
|
||||
|
||||
<p class="status">
|
||||
<span class="sr">${status.display_name}</span>
|
||||
<span class="sr">{{ status.display_name }}</span>
|
||||
</p>
|
||||
|
||||
<p id="answer_${id}" class="answer"></p>
|
||||
<p id="answer_{{ id }}" class="answer"></p>
|
||||
|
||||
% if msg:
|
||||
<span class="message" tabindex="-1">${HTML(msg)}</span>
|
||||
% endif
|
||||
% if status in ['unsubmitted', 'correct', 'incorrect', 'partially-correct', 'incomplete']:
|
||||
{% if msg %}
|
||||
<span class="message" tabindex="-1">{{ msg|safe }}</span>
|
||||
{% endif %}
|
||||
{% if status == 'unsubmitted' or status == 'correct' or status == 'incorrect' or status == 'partially-correct' or status == 'incomplete' %}
|
||||
</div>
|
||||
% endif
|
||||
{% endif %}
|
||||
</section>
|
||||
|
||||
@@ -8,8 +8,7 @@ import xml.sax.saxutils as saxutils
|
||||
from unittest.mock import MagicMock, Mock
|
||||
|
||||
import fs.osfs
|
||||
from mako.lookup import TemplateLookup
|
||||
from path import Path
|
||||
from django.template.loader import get_template as django_get_template
|
||||
|
||||
from xmodule.capa.capa_problem import LoncapaProblem, LoncapaSystem
|
||||
from xmodule.capa.inputtypes import Status
|
||||
@@ -21,16 +20,14 @@ def get_template(template_name):
|
||||
"""
|
||||
Return template for a capa inputtype.
|
||||
"""
|
||||
return TemplateLookup(
|
||||
directories=[Path(__file__).dirname().dirname() / "templates"], default_filters=["decode.utf8"]
|
||||
).get_template(template_name)
|
||||
return django_get_template(template_name)
|
||||
|
||||
|
||||
def capa_render_template(template, context):
|
||||
"""
|
||||
Render template for a capa inputtype.
|
||||
"""
|
||||
return get_template(template).render_unicode(**context)
|
||||
return get_template(template).render(context)
|
||||
|
||||
|
||||
def tst_render_template(template, context): # pylint: disable=unused-argument
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
"""
|
||||
Tests for the logic in input type mako templates.
|
||||
~Tests for the logic in input type Django templates.
|
||||
"""
|
||||
|
||||
import json
|
||||
import traceback
|
||||
import unittest
|
||||
from collections import OrderedDict
|
||||
|
||||
from lxml import etree
|
||||
from mako import exceptions
|
||||
from six.moves import range
|
||||
|
||||
from openedx.core.djangolib.markup import HTML
|
||||
@@ -18,7 +18,7 @@ from xmodule.stringify import stringify_children
|
||||
|
||||
class TemplateError(Exception):
|
||||
"""
|
||||
Error occurred while rendering a Mako template.
|
||||
Error occurred while rendering a Django template.
|
||||
"""
|
||||
|
||||
pass # lint-amnesty, pylint: disable=unnecessary-pass
|
||||
@@ -57,10 +57,8 @@ class TemplateTestCase(unittest.TestCase):
|
||||
context_dict.setdefault("STATIC_URL", "/dummy-static/")
|
||||
try:
|
||||
xml_str = capa_render_template(self.TEMPLATE_NAME, context_dict)
|
||||
except:
|
||||
raise TemplateError( # lint-amnesty, pylint: disable=raise-missing-from
|
||||
exceptions.text_error_template().render()
|
||||
)
|
||||
except Exception as exc:
|
||||
raise TemplateError(f"<pre>{traceback.format_exc()}</pre>") from exc
|
||||
|
||||
# Attempt to construct an XML tree from the template
|
||||
# This makes it easy to use XPath to make assertions, rather
|
||||
@@ -232,7 +230,7 @@ class TemplateTestCase(unittest.TestCase):
|
||||
|
||||
class ChoiceGroupTemplateTest(TemplateTestCase):
|
||||
"""
|
||||
Test mako template for `<choicegroup>` input.
|
||||
Test django template for `<choicegroup>` input.
|
||||
"""
|
||||
|
||||
TEMPLATE_NAME = "choicegroup.html"
|
||||
@@ -462,7 +460,7 @@ class ChoiceGroupTemplateTest(TemplateTestCase):
|
||||
|
||||
class TextlineTemplateTest(TemplateTestCase):
|
||||
"""
|
||||
Test mako template for `<textline>` input.
|
||||
Test django template for `<textline>` input.
|
||||
"""
|
||||
|
||||
TEMPLATE_NAME = "textline.html"
|
||||
@@ -641,7 +639,7 @@ class FormulaEquationInputTemplateTest(TemplateTestCase):
|
||||
|
||||
class AnnotationInputTemplateTest(TemplateTestCase):
|
||||
"""
|
||||
Test mako template for `<annotationinput>` input.
|
||||
Test django template for `<annotationinput>` input.
|
||||
"""
|
||||
|
||||
TEMPLATE_NAME = "annotationinput.html"
|
||||
@@ -766,7 +764,7 @@ class AnnotationInputTemplateTest(TemplateTestCase):
|
||||
|
||||
class MathStringTemplateTest(TemplateTestCase):
|
||||
"""
|
||||
Test mako template for `<mathstring>` input.
|
||||
Test django template for `<mathstring>` input.
|
||||
"""
|
||||
|
||||
TEMPLATE_NAME = "mathstring.html"
|
||||
@@ -806,7 +804,7 @@ class MathStringTemplateTest(TemplateTestCase):
|
||||
|
||||
class OptionInputTemplateTest(TemplateTestCase):
|
||||
"""
|
||||
Test mako template for `<optioninput>` input.
|
||||
Test django template for `<optioninput>` input.
|
||||
"""
|
||||
|
||||
TEMPLATE_NAME = "optioninput.html"
|
||||
@@ -866,7 +864,7 @@ class OptionInputTemplateTest(TemplateTestCase):
|
||||
|
||||
class DragAndDropTemplateTest(TemplateTestCase):
|
||||
"""
|
||||
Test mako template for `<draganddropinput>` input.
|
||||
Test django template for `<draganddropinput>` input.
|
||||
"""
|
||||
|
||||
TEMPLATE_NAME = "drag_and_drop_input.html"
|
||||
@@ -911,7 +909,7 @@ class DragAndDropTemplateTest(TemplateTestCase):
|
||||
|
||||
|
||||
class ChoiceTextGroupTemplateTest(TemplateTestCase):
|
||||
"""Test mako template for `<choicetextgroup>` input"""
|
||||
"""Test django template for `<choicetextgroup>` input"""
|
||||
|
||||
TEMPLATE_NAME = "choicetext.html"
|
||||
VALUE_DICT = {
|
||||
@@ -1093,7 +1091,7 @@ class ChoiceTextGroupTemplateTest(TemplateTestCase):
|
||||
|
||||
|
||||
class ChemicalEquationTemplateTest(TemplateTestCase):
|
||||
"""Test mako template for `<chemicalequationinput>` input"""
|
||||
"""Test django template for `<chemicalequationinput>` input"""
|
||||
|
||||
TEMPLATE_NAME = "chemicalequationinput.html"
|
||||
|
||||
@@ -1114,7 +1112,7 @@ class ChemicalEquationTemplateTest(TemplateTestCase):
|
||||
|
||||
|
||||
class SchematicInputTemplateTest(TemplateTestCase):
|
||||
"""Test mako template for `<schematic>` input"""
|
||||
"""Test django template for `<schematic>` input"""
|
||||
|
||||
TEMPLATE_NAME = "schematicinput.html"
|
||||
|
||||
@@ -1145,7 +1143,7 @@ class SchematicInputTemplateTest(TemplateTestCase):
|
||||
|
||||
class CodeinputTemplateTest(TemplateTestCase):
|
||||
"""
|
||||
Test mako template for `<textbox>` input
|
||||
Test django template for `<textbox>` input
|
||||
"""
|
||||
|
||||
TEMPLATE_NAME = "codeinput.html"
|
||||
|
||||
@@ -18,6 +18,7 @@ import traceback
|
||||
import nh3
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.template.loader import render_to_string
|
||||
from django.utils.encoding import smart_str
|
||||
from django.utils.functional import cached_property
|
||||
from lxml import etree
|
||||
@@ -399,6 +400,7 @@ class _BuiltInProblemBlock(
|
||||
"""
|
||||
Return the studio view.
|
||||
"""
|
||||
# Not converting this to django template since this method is deprecated.
|
||||
fragment = Fragment(
|
||||
self.runtime.service(self, "mako").render_cms_template(self.mako_template, self.get_context())
|
||||
)
|
||||
@@ -896,7 +898,7 @@ class _BuiltInProblemBlock(
|
||||
get_python_lib_zip=sandbox_service.get_python_lib_zip,
|
||||
DEBUG=self.debug,
|
||||
i18n=self.runtime.service(self, "i18n"),
|
||||
render_template=self.runtime.service(self, "mako").render_template,
|
||||
render_template=render_to_string,
|
||||
resources_fs=self.runtime.resources_fs,
|
||||
seed=seed, # Why do we do this if we have self.seed?
|
||||
xqueue=None if is_studio else XQueueService(self),
|
||||
@@ -992,7 +994,7 @@ class _BuiltInProblemBlock(
|
||||
"""
|
||||
curr_score, total_possible = self.get_display_progress()
|
||||
|
||||
return self.runtime.service(self, "mako").render_lms_template(
|
||||
return render_to_string(
|
||||
"problem_ajax.html",
|
||||
{
|
||||
"element_id": self.location.html_id(),
|
||||
@@ -1339,7 +1341,7 @@ class _BuiltInProblemBlock(
|
||||
"submit_disabled_cta": submit_disabled_ctas[0] if submit_disabled_ctas else None,
|
||||
}
|
||||
|
||||
html = self.runtime.service(self, "mako").render_lms_template("problem.html", context)
|
||||
html = render_to_string("problem.html", context)
|
||||
|
||||
if encapsulate:
|
||||
html = HTML('<div id="problem_{id}" class="problem" data-url="{ajax_url}">{html}</div>').format(
|
||||
@@ -1647,7 +1649,7 @@ class _BuiltInProblemBlock(
|
||||
|
||||
return {
|
||||
"answers": new_answers,
|
||||
"correct_status_html": self.runtime.service(self, "mako").render_lms_template(
|
||||
"correct_status_html": render_to_string(
|
||||
"status_span.html", {"status": Status("correct", self.runtime.service(self, "i18n").gettext)}
|
||||
),
|
||||
}
|
||||
|
||||
@@ -2277,9 +2277,10 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
|
||||
assert html is not None
|
||||
# assert that we got here without exploding
|
||||
|
||||
def test_get_problem_html(self):
|
||||
render_template = Mock(return_value="<div>Test Template HTML</div>")
|
||||
block = CapaFactory.create(render_template=render_template)
|
||||
@patch("xmodule.capa_block.render_to_string")
|
||||
def test_get_problem_html(self, render_template):
|
||||
render_template.return_value = "<div>Test Template HTML</div>"
|
||||
block = CapaFactory.create()
|
||||
|
||||
# We've tested the show/hide button logic in other tests,
|
||||
# so here we hard-wire the values
|
||||
@@ -2337,11 +2338,12 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
|
||||
</demandhint>
|
||||
</problem>"""
|
||||
|
||||
def test_demand_hint(self):
|
||||
@patch("xmodule.capa_block.render_to_string")
|
||||
def test_demand_hint(self, render_template):
|
||||
# HTML generation is mocked out to be meaningless here, so instead we check
|
||||
# the context dict passed into HTML generation.
|
||||
render_template = Mock(return_value="<div>Test Template HTML</div>")
|
||||
block = CapaFactory.create(xml=self.demand_xml, render_template=render_template)
|
||||
render_template.return_value = "<div>Test Template HTML</div>"
|
||||
block = CapaFactory.create(xml=self.demand_xml)
|
||||
block.get_problem_html() # ignoring html result
|
||||
context = render_template.call_args[0][1]
|
||||
assert context["demand_hint_possible"]
|
||||
@@ -2360,7 +2362,8 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
|
||||
assert result["hint_index"] == 0
|
||||
assert result["should_enable_next_hint"]
|
||||
|
||||
def test_single_demand_hint(self):
|
||||
@patch("xmodule.capa_block.render_to_string")
|
||||
def test_single_demand_hint(self, render_template):
|
||||
"""
|
||||
Test the hint button enabled state when there is just a single hint.
|
||||
"""
|
||||
@@ -2378,8 +2381,8 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
|
||||
<hint>Only demand hint</hint>
|
||||
</demandhint>
|
||||
</problem>"""
|
||||
render_template = Mock(return_value="<div>Test Template HTML</div>")
|
||||
block = CapaFactory.create(xml=test_xml, render_template=render_template)
|
||||
render_template.return_value = "<div>Test Template HTML</div>"
|
||||
block = CapaFactory.create(xml=test_xml)
|
||||
block.get_problem_html() # ignoring html result
|
||||
context = render_template.call_args[0][1]
|
||||
assert context["demand_hint_possible"]
|
||||
@@ -2390,7 +2393,8 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
|
||||
assert result["hint_index"] == 0
|
||||
assert not result["should_enable_next_hint"]
|
||||
|
||||
def test_image_hint(self):
|
||||
@patch("xmodule.capa_block.render_to_string")
|
||||
def test_image_hint(self, render_template):
|
||||
"""
|
||||
Test the hint button shows an image without the static url.
|
||||
"""
|
||||
@@ -2410,8 +2414,8 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
|
||||
You can add an optional hint like this. Problems that have a hint include a hint button, and this text appears the first time learners select the button.</hint>
|
||||
</demandhint>
|
||||
</problem>"""
|
||||
render_template = Mock(return_value="<div>Test Template HTML</div>")
|
||||
block = CapaFactory.create(xml=test_xml, render_template=render_template)
|
||||
render_template.return_value = "<div>Test Template HTML</div>"
|
||||
block = CapaFactory.create(xml=test_xml)
|
||||
block.get_problem_html() # ignoring html result
|
||||
context = render_template.call_args[0][1]
|
||||
assert context["demand_hint_possible"]
|
||||
@@ -2449,14 +2453,15 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
|
||||
intersection = set(block2.input_state.keys()).intersection(set(block1.input_state.keys()))
|
||||
assert len(intersection) == 0
|
||||
|
||||
def test_get_problem_html_error(self):
|
||||
@patch("xmodule.capa_block.render_to_string")
|
||||
def test_get_problem_html_error(self, render_template):
|
||||
"""
|
||||
In production, when an error occurs with the problem HTML
|
||||
rendering, a "dummy" problem is created with an error
|
||||
message to display to the user.
|
||||
"""
|
||||
render_template = Mock(return_value="<div>Test Template HTML</div>")
|
||||
block = CapaFactory.create(render_template=render_template)
|
||||
render_template.return_value = "<div>Test Template HTML</div>"
|
||||
block = CapaFactory.create()
|
||||
|
||||
# Save the original problem so we can compare it later
|
||||
original_problem = block.lcp
|
||||
@@ -2478,12 +2483,13 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
|
||||
# Expect that the block has created a new dummy problem with the error
|
||||
assert original_problem != block.lcp
|
||||
|
||||
def test_get_problem_html_error_preview(self):
|
||||
@patch("xmodule.capa_block.render_to_string")
|
||||
def test_get_problem_html_error_preview(self, render_template):
|
||||
"""
|
||||
Test the html response when an error occurs with DEBUG off in Studio.
|
||||
"""
|
||||
render_template = Mock(return_value="<div>Test Template HTML</div>")
|
||||
block = CapaFactory.create(render_template=render_template)
|
||||
render_template.return_value = "<div>Test Template HTML</div>"
|
||||
block = CapaFactory.create()
|
||||
|
||||
# Simulate throwing an exception when the capa problem
|
||||
# is asked to render itself as HTML
|
||||
@@ -2503,12 +2509,13 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
|
||||
assert error_msg in context["problem"]["html"]
|
||||
|
||||
@override_settings(DEBUG=True)
|
||||
def test_get_problem_html_error_w_debug(self):
|
||||
@patch("xmodule.capa_block.render_to_string")
|
||||
def test_get_problem_html_error_w_debug(self, render_template):
|
||||
"""
|
||||
Test the html response when an error occurs with DEBUG on
|
||||
"""
|
||||
render_template = Mock(return_value="<div>Test Template HTML</div>")
|
||||
block = CapaFactory.create(render_template=render_template)
|
||||
render_template.return_value = "<div>Test Template HTML</div>"
|
||||
block = CapaFactory.create()
|
||||
|
||||
# Simulate throwing an exception when the capa problem
|
||||
# is asked to render itself as HTML
|
||||
@@ -2823,12 +2830,13 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
|
||||
"",
|
||||
" ",
|
||||
)
|
||||
def test_problem_no_display_name(self, display_name):
|
||||
@patch("xmodule.capa_block.render_to_string")
|
||||
def test_problem_no_display_name(self, display_name, render_template):
|
||||
"""
|
||||
Verify that if problem display name is not provided then a default name is used.
|
||||
"""
|
||||
render_template = Mock(return_value="<div>Test Template HTML</div>")
|
||||
block = CapaFactory.create(display_name=display_name, render_template=render_template)
|
||||
render_template.return_value = "<div>Test Template HTML</div>"
|
||||
block = CapaFactory.create(display_name=display_name)
|
||||
block.get_problem_html()
|
||||
render_args, _ = render_template.call_args
|
||||
context = render_args[1]
|
||||
|
||||
Reference in New Issue
Block a user