Commit 0290f4ff by Xavier Antoviaque

Merge pull request #1 from FiloSottile/xblock

XBlock
parents 0fe52737 7dca95f7
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.cache
nosetests.xml
coverage.xml
# Translations
*.mo
*.pot
# Django stuff:
*.log
# Sphinx documentation
docs/_build/
# PyBuilder
target/
from .drag_and_drop_v2 import DragAndDropBlock
# -*- coding: utf-8 -*-
#
# Imports ###########################################################
import logging
import textwrap
import json
import webob
from xblock.core import XBlock
from xblock.fields import Scope, String
from xblock.fragment import Fragment
from .utils import render_template, load_resource
# Globals ###########################################################
log = logging.getLogger(__name__)
# Classes ###########################################################
class DragAndDropBlock(XBlock):
"""
XBlock providing a Drag and Drop question
"""
display_name = String(
display_name="Title",
help="The title of the Drag and Drop that is displayed to the user",
scope=Scope.settings,
default="Drag and Drop"
)
question_text = String(
display_name="Question text",
help="The question text that is displayed to the user",
scope=Scope.settings
)
data = String(
display_name="Drag and Drop",
help="JSON spec as generated by the builder",
scope=Scope.content,
default='{"feedback":{"start":"Intro","finish":"Final"},"items":[{"displayName":"A","zone":"Uno","id":0,"feedback":{"correct":"Si","incorrect":"No"},"size":{"width":"190px","height":"auto"},"backgroundImage":""},{"displayName":"B","zone":"none","id":1,"feedback":{"correct":"","incorrect":""},"size":{"width":"190px","height":"auto"},"backgroundImage":""}],"zones":[{"title":"Uno","id":"zone-1","active":true,"index":1,"width":200,"height":100,"x":0,"y":0},{"title":"Due","id":"zone-2","active":true,"index":2,"width":200,"height":100,"x":"300","y":"210"}],"targetImg":"https://i.imgur.com/PoI27ox.png"}'
# default=textwrap.dedent("""
# {
# feedback: {},
# items: [],
# zones: [],
# targetImg: 'img/triangle.png'
# }
# """)
)
def student_view(self, context):
"""
Player view, displayed to the student
"""
context = {
'title': self.display_name,
'question_text': self.question_text
}
fragment = Fragment()
fragment.add_content(render_template('/templates/html/drag_and_drop.html', context))
fragment.add_css(load_resource('public/css/drag_and_drop.css'))
fragment.add_javascript(load_resource('public/js/vendor/jquery.html5-placeholder-shim.js'))
fragment.add_javascript(load_resource('public/js/vendor/underscore1.6.0.js'))
fragment.add_javascript(load_resource('public/js/drag_and_drop.js'))
fragment.initialize_js('DragAndDropBlock')
return fragment
def studio_view(self, context):
"""
Editing view in Studio
"""
context = {}
fragment = Fragment()
fragment.add_content(render_template('/templates/html/drag_and_drop_edit.html', context))
fragment.add_css(load_resource('public/css/drag_and_drop_edit.css'))
fragment.add_javascript(load_resource('public/js/vendor/jquery.html5-placeholder-shim.js'))
fragment.add_javascript(load_resource('public/js/vendor/underscore1.6.0.js'))
fragment.add_javascript(load_resource('public/js/drag_and_drop_edit.js'))
fragment.initialize_js('DragAndDropEditBlock')
return fragment
@XBlock.json_handler
def studio_submit(self, submissions, suffix=''):
self.display_name = submissions['display_name']
self.question_text = submissions['question_text']
data = submissions['data']
try:
json.loads(data)
self.data = data
except ValueError as e:
return {
'result': 'error',
'message': e.message
}
return {
'result': 'success',
}
@XBlock.handler
def get_data(self, request, suffix=''):
return webob.response.Response(body=self.data)
.xblock--drag-and-drop {
width: 770px;
margin: 0;
padding: 0;
background: #fff;
}
.xblock--drag-and-drop .problem-header {
display: inline-block;
margin: 0 0 15px 0;
}
.xblock--drag-and-drop .problem-progress {
display: inline-block;
padding-left: 5px;
color: #666;
font-weight: 100;
font-size: 1em;
}
.xblock--drag-and-drop .problem p {
margin-bottom: 1.41575em;
}
.xblock--drag-and-drop .drag-container {
width: 760px;
background: #ebf0f2;
position: relative;
}
.xblock--drag-and-drop .clear {
clear: both;
}
/** Draggable Items **/
.xblock--drag-and-drop .drag-container .items {
width: 210px;
margin: 10px;
padding: 0 !important; /* LMS tries to override this */
font-size: 14px;
position: relative;
display: inline;
float: left;
list-style-type: none;
}
.xblock--drag-and-drop .drag-container .items .option {
width: 190px;
background: #2e83cd;
color: #fff;
position: relative;
float: left;
display: inline;
z-index: 100;
margin-bottom: 5px;
padding: 10px;
}
.xblock--drag-and-drop .option.hover { background: #ccc; }
.xblock--drag-and-drop .option.fade { opacity: 0.6; }
/*** Drop Target ***/
.xblock--drag-and-drop .target {
width: 515px;
height: 510px;
position: relative;
display: inline;
float: left;
margin: 10px 0 15px 5px;
background: #fff;
z-index: 1;
}
.xblock--drag-and-drop .target-img {
width: 100%;
height: 100%;
}
.xblock--drag-and-drop .zone {
/*border: 1px solid #000;*/
position: absolute;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
/* Internet Explorer 10 */
-ms-flex-pack:center;
-ms-flex-align:center;
/* Firefox */
-moz-box-pack:center;
-moz-box-align:center;
/* Safari, Opera, and Chrome */
-webkit-box-pack:center;
-webkit-box-align:center;
/* W3C */
box-pack:center;
box-align:center;
}
.xblock--drag-and-drop .zone p {
width: 100%;
font-family: Arial;
font-size: 16px;
font-weight: bold;
text-align: center;
text-transform: uppercase;
margin-top: auto;
margin-bottom: auto;
}
.xblock--drag-and-drop .zone.one {
height: 75px;
width: 115px;
top: 130px;
left: 200px;
}
.xblock--drag-and-drop .zone.two {
height: 120px;
width: 200px;
top: 220px;
left: 157px;
}
.xblock--drag-and-drop .zone.three {
height: 120px;
width: 200px;
bottom: 30px;
left: 157px;
}
/*** IE9 alignment fix ***/
.lt-ie10 .xblock--drag-and-drop .zone {
display: table;
}
.lt-ie10 .xblock--drag-and-drop .zone p {
display: table-cell;
vertical-align: middle;
text-align: center;
}
/*** FEEDBACK ***/
.xblock--drag-and-drop .feedback p {
line-height: 1.5em;
font-weight: bold;
margin-bottom: 1.41575em;
}
.no-close .ui-dialog-titlebar-close {
display: none;
}
/*** xBlock styles ***/
.xblock--drag-and-drop {
width: 770px;
width: 100%;
margin: 0;
padding: 0;
background: #fff;
......@@ -86,6 +86,7 @@
}
.xblock--drag-and-drop .target-img {
background: url(../img/triangle.png) no-repeat;
width: 100%;
height: 100%;
}
......@@ -161,17 +162,29 @@
/*** FEEDBACK ***/
.xblock--drag-and-drop .feedback {
line-height: 1.5em;
font-weight: bold;
width: 740px;
border-top: #ccc 1px solid;
margin: 20px 10px;
padding-top: 10px;
}
.xblock--drag-and-drop .feedback .message {
margin: 5px 0 0;
}
/** Builder **/
.xblock--drag-and-drop .hidden {
display: none!important;
display: none !important;
}
.xblock--drag-and-drop .drag-builder {
/* TODO */
height: 375px;
overflow: scroll;
}
.xblock--drag-and-drop .drag-builder .tab {
width: 98%;
width: 100%;
background: #eee;
padding: 3px 0;
position: relative;
......@@ -218,10 +231,6 @@
margin-left: 0;
}
.xblock--drag-and-drop .drag-builder .target-image-form input {
width: 400px;
}
.xblock--drag-and-drop .zones-form .zone-row label {
display: inline-block;
width: 18%;
......@@ -278,6 +287,11 @@
width: 35%;
}
.xblock--drag-and-drop .items-form .item-width,
.xblock--drag-and-drop .items-form .item-height {
width: 40px;
}
.xblock--drag-and-drop .items-form textarea {
width: 97%;
margin: 0 1%;
......@@ -287,12 +301,6 @@
margin-bottom: 20px;
}
.xblock--drag-and-drop .items-form .item-width,
.xblock--drag-and-drop .items-form .item-height {
width: 30px;
margin-right: 50px;
}
/** Buttons **/
.xblock--drag-and-drop .btn {
......@@ -407,18 +415,3 @@
.xblock--drag-and-drop .remove-item .icon.remove:after {
background: #2e83cd;
}
/*** Temp. styles for surrounding area & dev ***/
body,
.container {
margin: 0;
padding: 0;
background: #e5ebee;
}
.xblock--drag-and-drop {
margin: 20px auto 0;
padding: 10px 0 10px 10px;
}
.reset { margin: 0 0 15px 700px; }
......@@ -283,7 +283,6 @@
};
// Shuffle an array, using the modern version of the
// [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
_.shuffle = function(obj) {
var rand;
var index = 0;
......
<section class="xblock--drag-and-drop">
<link rel="stylesheet" href="https://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
<h2 class="problem-header">
{{ title }}
</h2>
<div class="problem-progress">(1 point possible)</div>
<section class="problem" role="application">
<p>
{{ question_text }}
</p>
</section>
<section class="feedback">
<p class="message"></p>
</section>
<section class="drag-container">
<ul class="items"></ul>
<div class="target">
<div class="target-img"></div>
</div>
<div class="clear"></div>
</section>
</section>
<!doctype html>
<!--[if lt IE 7 ]> <html class="lt-ie10"> <![endif]-->
<!--[if IE 7 ]> <html class="lt-ie10"> <![endif]-->
<!--[if IE 8 ]> <html class="lt-ie10"> <![endif]-->
<!--[if IE 9 ]> <html class="lt-ie10"> <![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--> <html> <!--<![endif]-->
<head>
<meta charset="utf-8">
<title>draggable demo</title>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
<link rel="stylesheet" href="css/draggable_builder.css">
</head>
<body>
<div class="container">
<section class="xblock--drag-and-drop">
<header class="hidden">
<h1>Title <span class="small">(1 point possible)</span></h1>
<p>Lorem ipsum?</p>
</header>
{% load i18n %}
<section class="feedback hidden">
<p class="message"></p>
</section>
<div class="xblock--drag-and-drop editor-with-buttons">
<link rel="stylesheet" href="https://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
<section class="drag-builder">
<div class="tab feedback-tab">
<section class="tab-content">
<form class="feedback-form">
<h3>Question title</h3>
<input class="display-name" />
<h3>Question text</h3>
<textarea class="question-text"></textarea>
<h3>Introduction Feedback</h3>
<textarea class="intro-feedback"></textarea>
......@@ -37,20 +21,15 @@
<textarea class="final-feedback"></textarea>
</form>
</section>
<footer class="tab-footer">
<!-- <footer class="tab-footer">
<button class="btn continue goto-zones">Continue</button>
</footer>
</footer> -->
</div>
<div class="tab zones-tab hidden">
<header class="tab-header">
<h3>Zone Positions</h3>
</header>
<section class="tab-content target-image-form">
<label>New background URL:</label>
<input type="text">
<button class="btn">Change background</button>
</section>
<section class="tab-content">
<div class="items">
<form class="zones-form"></form>
......@@ -60,9 +39,9 @@
<div class="target-img"></div>
</div>
</section>
<footer class="tab-footer">
<!-- <footer class="tab-footer">
<button class="btn continue goto-items">Continue</button>
</footer>
</footer> -->
</div>
<div class="tab items-tab hidden">
......@@ -74,29 +53,26 @@
</section>
<footer class="tab-footer">
<a href="#" class="add-item add-element"><div class="icon add"></div>Add an item</a>
<button class="btn continue goto-exercise">Finish</button>
<!-- <button class="btn continue goto-exercise">Finish</button> -->
</footer>
</div>
</section>
<section class="drag-container hidden">
<ul class="items"></ul>
<div class="xblock-actions">
<span class="xblock-editor-error-message"></span>
<ul>
<li class="action-item">
<a href="#" class="button action-primary continue-button">{% trans "Continue" %}</a>
</li>
<div class="target">
<div class="target-img"></div>
</div>
<li class="action-item hidden">
<a href="#" class="button action-primary save-button">{% trans "Save" %}</a>
</li>
<!-- Only added for testing purposes -->
<button class="btn reset">Reset</button>
</section>
</section>
<li class="action-item">
<a href="#" class="button cancel-button">{% trans "Cancel" %}</a>
</li>
</ul>
</div>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script type="text/javascript" src="https://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<script type="text/javascript" src="js/vendor/jquery.html5-placeholder-shim.js"></script>
<script type="text/javascript" src="js/vendor/underscore1.6.0.js"></script>
<script type="text/javascript" src="js/draggable_builder.js"></script>
</body>
</html>
</div>
# -*- coding: utf-8 -*-
#
# Imports ###########################################################
import logging
import pkg_resources
from django.template import Context, Template
# Globals ###########################################################
log = logging.getLogger(__name__)
# Functions #########################################################
def load_resource(resource_path):
"""
Gets the content of a resource
"""
resource_content = pkg_resources.resource_string(__name__, resource_path)
return resource_content
def render_template(template_path, context={}):
"""
Evaluate a template by resource path, applying the provided context
"""
template_str = load_resource(template_path)
template = Template(template_str)
return template.render(Context(context))
# -*- coding: utf-8 -*-
# Imports ###########################################################
import os
from setuptools import setup
# Functions #########################################################
def package_data(pkg, root_list):
"""Generic function to find package_data for `pkg` under `root`."""
data = []
for root in root_list:
for dirname, _, files in os.walk(os.path.join(pkg, root)):
for fname in files:
data.append(os.path.relpath(os.path.join(dirname, fname), pkg))
return {pkg: data}
# Main ##############################################################
setup(
name='xblock-drag-and-drop-v2',
version='0.1',
description='XBlock - Drag-and-Drop v2',
packages=['drag_and_drop_v2'],
install_requires=[
'XBlock',
],
entry_points={
'xblock.v1': 'drag-and-drop-v2 = drag_and_drop_v2:DragAndDropBlock',
},
package_data=package_data("drag_and_drop_v2", ["static", "templates", "public"]),
)
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