Commit 9eb4253f by Ehtesham

adding warning message if more than one inputtypes in one question

parent 0cfa3ff9
<% <%
var summaryMessage = validation.get("summary"); var summaryMessage = validation.get("summary");
var aggregateMessageType = summaryMessage.type; var aggregateMessageType = summaryMessage.type;
var aggregateValidationClass = aggregateMessageType === "error"? "has-errors" : "has-warnings"; var aggregateValidationClass = aggregateMessageType === "error" ? "has-errors" : "has-warnings";
%> %>
<div class="xblock-message validation <%= aggregateValidationClass %> <%= additionalClasses %>"> <div class="xblock-message validation <%= aggregateValidationClass %> <%= additionalClasses %>">
<p class="<%= aggregateMessageType %>"><i class="icon fa <%= getIcon(aggregateMessageType) %>"></i> <p class="<%= aggregateMessageType %>"><i class="icon fa <%= getIcon(aggregateMessageType) %>"></i>
<%- summaryMessage.text %> <%- summaryMessage.text %>
<% if (summaryMessage.action_class) { %> <% if (summaryMessage.action_class) { %>
<a href="#" class="button action-button <%- summaryMessage.action_class %>"> <a href="<%= summaryMessage.action_link ? summaryMessage.action_link : '#' %>" class="button action-button <%- summaryMessage.action_class %>">
<span class="action-button-text"><%- summaryMessage.action_label %></span> <span class="action-button-text"><%- summaryMessage.action_label %></span>
<% if (summaryMessage.action_class === 'external-link') { %>
<i class="fa fa-external-link-square" aria-hidden="true"></i>
<% } %>
</a> </a>
<% } else if (summaryMessage.action_runtime_event) {%> <% } else if (summaryMessage.action_runtime_event) {%>
<a href="#" class="button action-button notification-action-button" data-notification-action="<%- summaryMessage.action_runtime_event %>"> <a href="#" class="button action-button notification-action-button" data-notification-action="<%- summaryMessage.action_runtime_event %>">
......
...@@ -8,6 +8,8 @@ from lxml import etree ...@@ -8,6 +8,8 @@ from lxml import etree
from pkg_resources import resource_string from pkg_resources import resource_string
import dogstats_wrapper as dog_stats_api import dogstats_wrapper as dog_stats_api
from xmodule.validation import StudioValidation, StudioValidationMessage
from .capa_base import CapaMixin, CapaFields, ComplexEncoder from .capa_base import CapaMixin, CapaFields, ComplexEncoder
from capa import responsetypes from capa import responsetypes
from .progress import Progress from .progress import Progress
...@@ -128,6 +130,15 @@ class CapaModule(CapaMixin, XModule): ...@@ -128,6 +130,15 @@ class CapaModule(CapaMixin, XModule):
return json.dumps(result, cls=ComplexEncoder) return json.dumps(result, cls=ComplexEncoder)
def validate(self):
"""
Message for either error or warning validation message/s.
Returns message and type. Priority given to error type message.
"""
return self.descriptor.validate()
class CapaDescriptor(CapaFields, RawDescriptor): class CapaDescriptor(CapaFields, RawDescriptor):
""" """
...@@ -256,6 +267,48 @@ class CapaDescriptor(CapaFields, RawDescriptor): ...@@ -256,6 +267,48 @@ class CapaDescriptor(CapaFields, RawDescriptor):
) )
return False return False
def validate(self):
"""
Validates the xml for correct question separation. There must be only one inputtype in every <question>.
This is the override of the general XBlock method.
"""
validation = super(CapaDescriptor, self).validate()
validation = StudioValidation.copy(validation)
# validate xml to check questions are correctly separated
is_valid = self.validate_xml()
if not is_valid:
validation.set_summary(
StudioValidationMessage(
StudioValidationMessage.WARNING,
u'Incorrect problem format detected!',
action_label=u"Please see docs.",
action_class=u"external-link",
action_link=u"http://docs.edx.org/"
)
)
return validation
def validate_xml(self):
input_tags = ['choiceresponse', 'optionresponse', 'multiplechoiceresponse', 'stringresponse',
'numericalresponse', 'schematicresponse', 'imageresponse', 'formularesponse']
xmltree = etree.fromstring(self.data)
questions = xmltree.findall(".//question")
for question in questions:
for tag in input_tags:
tag_elements = question.findall(".//" + tag)
if len(tag_elements) > 1:
print("more choices")
return False
return True
# Proxy to CapaModule for access to any of its attributes # Proxy to CapaModule for access to any of its attributes
answer_available = module_attr('answer_available') answer_available = module_attr('answer_available')
check_button_name = module_attr('check_button_name') check_button_name = module_attr('check_button_name')
......
...@@ -15,12 +15,13 @@ class StudioValidationMessage(ValidationMessage): ...@@ -15,12 +15,13 @@ class StudioValidationMessage(ValidationMessage):
TYPES = [ValidationMessage.WARNING, ValidationMessage.ERROR, NOT_CONFIGURED] TYPES = [ValidationMessage.WARNING, ValidationMessage.ERROR, NOT_CONFIGURED]
def __init__(self, message_type, message_text, action_label=None, action_class=None, action_runtime_event=None): def __init__(self, message_type, message_text, action_label=None, action_class=None, action_runtime_event=None,
action_link=None):
""" """
Create a new message. Create a new message.
Args: Args:
message_type (str): The type associated with this message. Most be `WARNING` or `ERROR`. message_type (str): The type associated with this message. Must be `WARNING` or `ERROR`.
message_text (unicode): The textual message. message_text (unicode): The textual message.
action_label (unicode): Text to show on a "fix-up" action (optional). If present, either `action_class` action_label (unicode): Text to show on a "fix-up" action (optional). If present, either `action_class`
or `action_runtime_event` should be specified. or `action_runtime_event` should be specified.
...@@ -43,6 +44,10 @@ class StudioValidationMessage(ValidationMessage): ...@@ -43,6 +44,10 @@ class StudioValidationMessage(ValidationMessage):
if not isinstance(action_runtime_event, basestring): if not isinstance(action_runtime_event, basestring):
raise TypeError("Action runtime event must be a string.") raise TypeError("Action runtime event must be a string.")
self.action_runtime_event = action_runtime_event self.action_runtime_event = action_runtime_event
if action_link is not None:
if not isinstance(action_link, basestring):
raise TypeError("Action link must be a string.")
self.action_link = action_link
def to_json(self): def to_json(self):
""" """
...@@ -58,6 +63,8 @@ class StudioValidationMessage(ValidationMessage): ...@@ -58,6 +63,8 @@ class StudioValidationMessage(ValidationMessage):
serialized["action_class"] = self.action_class serialized["action_class"] = self.action_class
if hasattr(self, "action_runtime_event"): if hasattr(self, "action_runtime_event"):
serialized["action_runtime_event"] = self.action_runtime_event serialized["action_runtime_event"] = self.action_runtime_event
if hasattr(self, "action_link"):
serialized["action_link"] = self.action_link
return serialized return serialized
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment