Esempio n. 1
0
class TextInputBlock(InputBlock):
    """An XBlock that accepts text input."""

    input_type = String(help="Type of conversion to attempt on input string")
    student_input = Any(help="Last input submitted by the student",
                        default="",
                        scope=Scope.user_state)

    def student_view(self, context=None):  # pylint: disable=W0613
        """Returns default student view."""
        return Fragment(u"<p>I can only appear inside problems.</p>")

    def problem_view(self, context=None):  # pylint: disable=W0613
        """Returns a view of the problem - a javascript text input field."""
        html = u"<input type='text' name='input' value='{0}'><span class='message'></span>".format(
            self.student_input)
        result = Fragment(html)
        result.add_javascript(u"""
            function TextInputBlock(runtime, element) {
                return {
                    submit: function() {
                        return $(element).find(':input').serializeArray();
                    },
                    handleSubmit: function(result) {
                        $(element).find('.message').text((result || {}).error || '');
                    }
                }
            }
            """)
        result.initialize_js('TextInputBlock')
        return result

    def submit(self, submission):
        self.student_input = submission[0]['value']
        if self.input_type == 'int':
            try:
                self.student_input = int(submission[0]['value'])
            except ValueError:
                return {
                    'error': u'"%s" is not an integer' % self.student_input
                }
        return None
Esempio n. 2
0
class EqualityCheckerBlock(CheckerBlock):
    """An XBlock that checks the equality of two student data fields."""

    # Content: the problem will hook us up with our data.
    content = String(help="Message describing the equality test",
                     scope=Scope.content,
                     default="Equality test")

    # Student data
    left = Any(scope=Scope.user_state)
    right = Any(scope=Scope.user_state)
    attempted = Boolean(scope=Scope.user_state)

    def problem_view(self, context=None):
        """Renders the problem view.

        The view is specific to whether or not this problem was attempted, and, if so,
        if it was answered correctly.

        """
        correct = self.left == self.right

        # TODO: I originally named this class="data", but that conflicted with
        # the CSS on the page! :(  We might have to do something to namespace
        # things.
        # TODO: Should we have a way to spit out JSON islands full of data?
        # Note the horror of mixed Python-Javascript data below...
        content = string.Template(self.content).substitute(**context)
        result = Fragment(u"""
            <span class="mydata" data-attempted='{self.attempted}' data-correct='{correct}'>
                {content}
                <span class='indicator'></span>
            </span>
            """.format(self=self, content=content, correct=correct))
        # TODO: This is a runtime-specific URL.  But if each XBlock ships their
        # own copy of underscore.js, we won't be able to uniquify them.
        # Perhaps runtimes can offer a palette of popular libraries so that
        # XBlocks can refer to them in XBlock-standard ways?
        result.add_javascript_url(
            self.runtime.resource_url("js/vendor/underscore-min.js"))

        # TODO: The image tag here needs a magic URL, not a hard-coded one.
        format_data = {
            'correct':
            self.runtime.local_resource_url(self,
                                            'public/images/correct-icon.png'),
            'incorrect':
            self.runtime.local_resource_url(
                self, 'public/images/incorrect-icon.png'),
        }
        result.add_resource(
            u"""
            <script type="text/template" id="xblock-equality-template">
                <% if (attempted !== "True") {{ %>
                    (Not attempted)
                <% }} else if (correct === "True") {{ %>
                    <img src="{correct}">
                <% }} else {{ %>
                    <img src="{incorrect}">
                <% }} %>
            </script>
            """.format(**format_data), "text/html")

        result.add_javascript("""
            function EqualityCheckerBlock(runtime, element) {
                var template = _.template($("#xblock-equality-template").html());
                function render() {
                    var data = $("span.mydata", element).data();
                    $("span.indicator", element).html(template(data));
                }
                render();
                return {
                    handleCheck: function(result) {
                        $("span.mydata", element)
                              .data("correct", result ? "True" : "False")
                              .data("attempted", "True");
                        render();
                    }
                }
            }
            """)

        result.initialize_js('EqualityCheckerBlock')
        return result

    def check(self, left, right):  # pylint: disable=W0221
        self.attempted = True
        self.left = left
        self.right = right

        event_data = {'value': 1 if left == right else 0, 'max_value': 1}
        self.runtime.publish(self, 'grade', event_data)

        return left == right