Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
X
xblock-drag-and-drop-v2
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
xblock-drag-and-drop-v2
Commits
260d00f3
Commit
260d00f3
authored
Jul 07, 2014
by
Filippo Valsorda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support incremental editing in the Studio view
parent
9b1c33f0
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
94 additions
and
71 deletions
+94
-71
drag_and_drop_v2/drag_and_drop_v2.py
+3
-0
drag_and_drop_v2/public/css/drag_and_drop_edit.css
+0
-2
drag_and_drop_v2/public/js/drag_and_drop_edit.js
+63
-42
drag_and_drop_v2/templates/html/drag_and_drop_edit.html
+13
-6
drag_and_drop_v2/templates/html/js_templates.html
+13
-13
tests/test_data.json
+0
-2
tests/test_drag_and_drop_v2.py
+2
-4
tests/test_get_data.json
+0
-2
No files found.
drag_and_drop_v2/drag_and_drop_v2.py
View file @
260d00f3
...
...
@@ -7,6 +7,7 @@ import logging
import
json
import
webob
import
copy
import
urllib
from
xblock.core
import
XBlock
from
xblock.fields
import
Scope
,
String
,
Dict
,
Float
...
...
@@ -111,6 +112,8 @@ class DragAndDropBlock(XBlock):
js_templates
=
load_resource
(
'/templates/html/js_templates.html'
)
context
=
{
'js_templates'
:
js_templates
,
'self'
:
self
,
'data'
:
urllib
.
quote
(
json
.
dumps
(
self
.
data
)),
}
fragment
=
Fragment
()
...
...
drag_and_drop_v2/public/css/drag_and_drop_edit.css
View file @
260d00f3
...
...
@@ -174,8 +174,6 @@
}
.xblock--drag-and-drop
.drag-builder
.zone
{
width
:
200px
;
height
:
100px
;
border
:
1px
dotted
#666
;
}
...
...
drag_and_drop_v2/public/js/drag_and_drop_edit.js
View file @
260d00f3
...
...
@@ -39,7 +39,6 @@ function DragAndDropEditBlock(runtime, element) {
_fn
.
tpl
.
init
();
_fn
.
build
.
clickHandlers
();
_fn
.
build
.
form
.
zone
.
add
();
},
clickHandlers
:
function
()
{
var
$fbkTab
=
_fn
.
build
.
$el
.
feedback
.
tab
,
...
...
@@ -47,8 +46,20 @@ function DragAndDropEditBlock(runtime, element) {
$itemTab
=
_fn
.
build
.
$el
.
items
.
tab
;
$
(
element
).
one
(
'click'
,
'.continue-button'
,
function
(
e
)
{
// $fbkTab -> $zoneTab
e
.
preventDefault
();
_fn
.
build
.
form
.
feedback
(
_fn
.
build
.
$el
.
feedback
.
form
);
for
(
var
i
=
0
;
i
<
_fn
.
data
.
zones
.
length
;
i
++
)
{
_fn
.
build
.
form
.
zone
.
add
(
_fn
.
data
.
zones
[
i
]);
}
if
(
_fn
.
data
.
zones
.
length
===
0
)
{
_fn
.
build
.
form
.
zone
.
add
();
}
if
(
_fn
.
data
.
targetImg
)
{
_fn
.
$target
.
css
(
'background'
,
'url('
+
_fn
.
data
.
targetImg
+
') no-repeat'
);
}
$fbkTab
.
addClass
(
'hidden'
);
$zoneTab
.
removeClass
(
'hidden'
);
...
...
@@ -57,9 +68,16 @@ function DragAndDropEditBlock(runtime, element) {
$
.
placeholder
.
shim
();
$
(
this
).
one
(
'click'
,
function
(
e
)
{
// $zoneTab -> $itemTab
e
.
preventDefault
();
_fn
.
build
.
form
.
zone
.
setAll
();
_fn
.
build
.
form
.
item
.
add
();
for
(
var
i
=
0
;
i
<
_fn
.
data
.
items
.
length
;
i
++
)
{
_fn
.
build
.
form
.
item
.
add
(
_fn
.
data
.
items
[
i
]);
}
if
(
_fn
.
data
.
items
.
length
===
0
)
{
_fn
.
build
.
form
.
item
.
add
();
}
$zoneTab
.
addClass
(
'hidden'
);
$itemTab
.
removeClass
(
'hidden'
);
...
...
@@ -71,6 +89,8 @@ function DragAndDropEditBlock(runtime, element) {
$
(
'.save-button'
,
element
).
parent
()
.
removeClass
(
'hidden'
)
.
one
(
'click'
,
function
(
e
)
{
// $itemTab -> submit
e
.
preventDefault
();
_fn
.
build
.
form
.
submit
();
});
...
...
@@ -78,7 +98,9 @@ function DragAndDropEditBlock(runtime, element) {
});
$zoneTab
.
on
(
'click'
,
'.add-zone'
,
_fn
.
build
.
form
.
zone
.
add
)
.
on
(
'click'
,
'.add-zone'
,
function
(
e
)
{
_fn
.
build
.
form
.
zone
.
add
();
})
.
on
(
'click'
,
'.remove-zone'
,
_fn
.
build
.
form
.
zone
.
remove
)
.
on
(
'click'
,
'.target-image-form button'
,
function
(
e
)
{
e
.
preventDefault
();
...
...
@@ -91,14 +113,15 @@ function DragAndDropEditBlock(runtime, element) {
});
$itemTab
.
on
(
'click'
,
'.add-item'
,
_fn
.
build
.
form
.
item
.
add
)
.
on
(
'click'
,
'.add-item'
,
function
(
e
)
{
_fn
.
build
.
form
.
item
.
add
();
})
.
on
(
'click'
,
'.remove-item'
,
_fn
.
build
.
form
.
item
.
remove
);
},
form
:
{
zone
:
{
count
:
0
,
formCount
:
0
,
dropdown
:
''
,
list
:
[],
obj
:
[],
getObjByIndex
:
function
(
num
)
{
...
...
@@ -107,7 +130,7 @@ function DragAndDropEditBlock(runtime, element) {
return
_fn
.
build
.
form
.
zone
.
obj
[
i
];
}
},
add
:
function
(
e
)
{
add
:
function
(
oldZon
e
)
{
var
inputTemplate
=
_fn
.
tpl
.
zoneInput
,
zoneTemplate
=
_fn
.
tpl
.
zoneElement
,
name
=
'zone-'
,
...
...
@@ -115,9 +138,7 @@ function DragAndDropEditBlock(runtime, element) {
num
,
obj
;
if
(
e
)
{
e
.
preventDefault
();
}
if
(
!
oldZone
)
oldZone
=
{};
_fn
.
build
.
form
.
zone
.
count
++
;
_fn
.
build
.
form
.
zone
.
formCount
++
;
...
...
@@ -126,23 +147,19 @@ function DragAndDropEditBlock(runtime, element) {
// Update zone obj
zoneObj
=
{
title
:
'Zone '
+
num
,
title
:
oldZone
.
title
||
'Zone '
+
num
,
id
:
name
,
active
:
false
,
index
:
num
,
width
:
200
,
height
:
100
,
x
:
0
,
y
:
0
width
:
oldZone
.
width
||
200
,
height
:
oldZone
.
height
||
100
,
x
:
oldZone
.
x
||
0
,
y
:
oldZone
.
y
||
0
};
_fn
.
build
.
form
.
zone
.
obj
.
push
(
zoneObj
);
// Add fields to zone position form
$elements
.
zones
.
form
.
append
(
inputTemplate
({
title
:
'Zone '
+
num
,
name
:
name
}));
$elements
.
zones
.
form
.
append
(
inputTemplate
(
zoneObj
));
_fn
.
build
.
form
.
zone
.
enableDelete
();
// Add zone div to target
...
...
@@ -192,7 +209,6 @@ function DragAndDropEditBlock(runtime, element) {
});
_fn
.
build
.
form
.
zone
.
list
=
zones
;
_fn
.
build
.
form
.
createDropdown
(
zones
);
},
clickHandler
:
function
(
num
)
{
var
$div
=
$
(
'#zone-'
+
num
,
element
),
...
...
@@ -205,10 +221,6 @@ function DragAndDropEditBlock(runtime, element) {
$div
.
find
(
'p'
).
html
(
text
);
record
.
title
=
text
;
if
(
!
record
.
active
)
{
record
.
active
=
true
;
}
}).
on
(
'keyup'
,
'.width'
,
function
(
e
)
{
var
width
=
$
(
e
.
currentTarget
).
val
(),
record
=
_fn
.
build
.
form
.
zone
.
getObjByIndex
(
num
);
...
...
@@ -241,31 +253,31 @@ function DragAndDropEditBlock(runtime, element) {
len
=
arr
.
length
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
if
(
arr
[
i
].
active
)
{
clean
.
push
(
arr
[
i
]);
}
clean
.
push
(
arr
[
i
]);
}
return
clean
;
}
},
createDropdown
:
function
(
arr
)
{
createDropdown
:
function
(
selected
)
{
var
tpl
=
_fn
.
tpl
.
zoneDropdown
,
i
,
len
=
arr
.
length
,
is_sel
,
arr
=
_fn
.
build
.
form
.
zone
.
list
,
dropdown
=
[],
html
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
dropdown
.
push
(
tpl
({
value
:
arr
[
i
]
}));
for
(
i
=
0
;
i
<
arr
.
length
;
i
++
)
{
if
(
arr
[
i
]
==
selected
)
is_sel
=
'selected'
;
else
is_sel
=
''
;
dropdown
.
push
(
tpl
({
value
:
arr
[
i
],
selected
:
is_sel
}));
}
// Add option to include dummy answers
dropdown
.
push
(
tpl
({
value
:
'none'
}));
html
=
dropdown
.
join
(
''
);
_fn
.
build
.
form
.
zone
.
dropdown
=
new
Handlebars
.
SafeString
(
html
);
_fn
.
build
.
$el
.
items
.
form
.
find
(
'.zone-select'
).
html
(
html
);
return
new
Handlebars
.
SafeString
(
html
);
},
feedback
:
function
(
$form
)
{
_fn
.
data
.
feedback
=
{
...
...
@@ -275,16 +287,27 @@ function DragAndDropEditBlock(runtime, element) {
},
item
:
{
count
:
0
,
add
:
function
(
e
)
{
add
:
function
(
oldItem
)
{
var
$form
=
_fn
.
build
.
$el
.
items
.
form
,
tpl
=
_fn
.
tpl
.
itemInput
;
tpl
=
_fn
.
tpl
.
itemInput
,
ctx
=
{};
if
(
e
)
{
e
.
preventDefault
();
}
if
(
oldItem
)
ctx
=
oldItem
;
ctx
.
dropdown
=
_fn
.
build
.
form
.
createDropdown
(
ctx
.
zone
);
if
(
!
oldItem
)
ctx
.
width
=
'190'
;
else
ctx
.
width
=
oldItem
.
size
.
width
.
substr
(
0
,
oldItem
.
size
.
width
.
length
-
2
);
if
(
ctx
.
width
==
'au'
)
ctx
.
width
=
'0'
;
if
(
!
oldItem
)
ctx
.
height
=
'0'
;
else
ctx
.
height
=
oldItem
.
size
.
height
.
substr
(
0
,
oldItem
.
size
.
height
.
length
-
2
);
if
(
ctx
.
height
==
'au'
)
ctx
.
height
=
'0'
;
_fn
.
build
.
form
.
item
.
count
++
;
$form
.
append
(
tpl
(
{
dropdown
:
_fn
.
build
.
form
.
zone
.
dropdown
}
));
$form
.
append
(
tpl
(
ctx
));
_fn
.
build
.
form
.
item
.
enableDelete
();
// Placeholder shim for IE9
...
...
@@ -386,7 +409,5 @@ function DragAndDropEditBlock(runtime, element) {
runtime
.
notify
(
'cancel'
,
{});
});
$
.
ajax
(
runtime
.
handlerUrl
(
element
,
'get_data'
)).
done
(
function
(
data
){
dragAndDrop
.
builder
(
data
);
});
dragAndDrop
.
builder
(
window
.
DragAndDropV2BlockPreviousData
);
}
drag_and_drop_v2/templates/html/drag_and_drop_edit.html
View file @
260d00f3
...
...
@@ -3,25 +3,32 @@
<div
class=
"xblock--drag-and-drop editor-with-buttons"
>
{{ js_templates|safe }}
<section
class=
"drag-builder"
>
<script
type=
"text/javascript"
>
var
DragAndDropV2BlockPreviousData
=
JSON
.
parse
(
decodeURIComponent
(
'{{ data|safe }}'
));
</script>
<section
class=
"drag-builder"
>
<div
class=
"tab feedback-tab"
>
<p
class=
"tab-content"
>
Note: don't edit the question if students already answered it! Delete it and create a new one.
</p>
<section
class=
"tab-content"
>
<form
class=
"feedback-form"
>
<h3>
Question title
</h3>
<input
class=
"display-name"
/>
<input
class=
"display-name"
value=
"{{ self.display_name }}"
/>
<h3>
Maximum score
</h3>
<input
class=
"weight"
value=
"1"
/>
<input
class=
"weight"
value=
"1"
value=
"{{ self.weight }}"
/>
<h3>
Question text
</h3>
<textarea
class=
"question-text"
></textarea>
<textarea
class=
"question-text"
>
{{ self.question_text }}
</textarea>
<h3>
Introduction Feedback
</h3>
<textarea
class=
"intro-feedback"
></textarea>
<textarea
class=
"intro-feedback"
>
{{ self.data.feedback.start }}
</textarea>
<h3>
Final Feedback
</h3>
<textarea
class=
"final-feedback"
></textarea>
<textarea
class=
"final-feedback"
>
{{ self.data.feedback.finish }}
</textarea>
</form>
</section>
</div>
...
...
drag_and_drop_v2/templates/html/js_templates.html
View file @
260d00f3
...
...
@@ -23,35 +23,35 @@
</script>
<script
id=
"zone-input-tpl"
type=
"text/html"
>
<
div
class
=
"zone-row {{
name
}}"
>
<
div
class
=
"zone-row {{
id
}}"
>
<
label
>
Text
<
/label
>
<
input
type
=
"text"
class
=
"title"
placeholder
=
"{{ title }}"
/>
<
input
type
=
"text"
class
=
"title"
value
=
"{{ title }}"
/>
<
a
href
=
"#"
class
=
"remove-zone hidden"
>
<
div
class
=
"icon remove"
><
/div
>
<
/a
>
<
div
class
=
"layout"
>
<
label
>
width
<
/label
>
<
input
type
=
"text"
class
=
"size width"
value
=
"
200
"
/>
<
input
type
=
"text"
class
=
"size width"
value
=
"
{{ width }}
"
/>
<
label
>
height
<
/label
>
<
input
type
=
"text"
class
=
"size height"
value
=
"
100
"
/>
<
input
type
=
"text"
class
=
"size height"
value
=
"
{{ height }}
"
/>
<
br
/>
<
label
>
x
<
/label
>
<
input
type
=
"text"
class
=
"coord x"
value
=
"
0
"
/>
<
input
type
=
"text"
class
=
"coord x"
value
=
"
{{ x }}
"
/>
<
label
>
y
<
/label
>
<
input
type
=
"text"
class
=
"coord y"
value
=
"
0
"
/>
<
input
type
=
"text"
class
=
"coord y"
value
=
"
{{ y }}
"
/>
<
/div
>
<
/div
>
</script>
<script
id=
"zone-dropdown-tpl"
type=
"text/html"
>
<
option
value
=
"{{ value }}"
>
{{
value
}}
<
/option
>
<
option
value
=
"{{ value }}"
{{
selected
}}
>
{{
value
}}
<
/option
>
</script>
<script
id=
"item-input-tpl"
type=
"text/html"
>
<
div
class
=
"item"
>
<
div
class
=
"row"
>
<
label
>
Text
<
/label
>
<
input
type
=
"text"
class
=
"item-text"
><
/input
>
<
input
type
=
"text"
class
=
"item-text"
value
=
"{{ displayName }}"
/
>
<
label
>
Zone
<
/label
>
<
select
class
=
"zone-select"
>
{{
dropdown
}}
<
/select
>
<
a
href
=
"#"
class
=
"remove-item hidden"
>
...
...
@@ -60,21 +60,21 @@
<
/div
>
<
div
class
=
"row"
>
<
label
>
Background
image
URL
(
alternative
to
the
text
)
<
/label
>
<
textarea
class
=
"background-image"
><
/textarea
>
<
textarea
class
=
"background-image"
>
{{
backgroundImage
}}
<
/textarea
>
<
/div
>
<
div
class
=
"row"
>
<
label
>
Success
Feedback
<
/label
>
<
textarea
class
=
"success-feedback"
><
/textarea
>
<
textarea
class
=
"success-feedback"
>
{{
feedback
.
correct
}}
<
/textarea
>
<
/div
>
<
div
class
=
"row"
>
<
label
>
Error
Feedback
<
/label
>
<
textarea
class
=
"error-feedback"
><
/textarea
>
<
textarea
class
=
"error-feedback"
>
{{
feedback
.
incorrect
}}
<
/textarea
>
<
/div
>
<
div
class
=
"row"
>
<
label
>
Width
(
px
-
0
for
auto
)
<
/label
>
<
input
type
=
"text"
class
=
"item-width"
value
=
"
190
"
><
/input
>
<
input
type
=
"text"
class
=
"item-width"
value
=
"
{{ width }}
"
><
/input
>
<
label
>
Height
(
px
-
0
for
auto
)
<
/label
>
<
input
type
=
"text"
class
=
"item-height"
value
=
"
0
"
><
/input
>
<
input
type
=
"text"
class
=
"item-height"
value
=
"
{{ height }}
"
><
/input
>
<
/div
>
<
/div
>
</script>
tests/test_data.json
View file @
260d00f3
...
...
@@ -5,7 +5,6 @@
"width"
:
200
,
"title"
:
"Zone A"
,
"height"
:
100
,
"active"
:
true
,
"y"
:
"200"
,
"x"
:
"100"
,
"id"
:
"zone-1"
...
...
@@ -15,7 +14,6 @@
"width"
:
200
,
"title"
:
"Zone B"
,
"height"
:
100
,
"active"
:
true
,
"y"
:
0
,
"x"
:
0
,
"id"
:
"zone-2"
...
...
tests/test_drag_and_drop_v2.py
View file @
260d00f3
...
...
@@ -45,8 +45,7 @@ def test_templates_contents():
student_fragment
=
block
.
render
(
'student_view'
,
Mock
())
assert_in
(
'<section class="xblock--drag-and-drop">'
,
student_fragment
.
content
)
assert_in
(
'<option value="{{ value }}">{{ value }}</option>'
,
student_fragment
.
content
)
assert_in
(
'{{ value }}'
,
student_fragment
.
content
)
assert_in
(
"Test Drag & Drop"
,
student_fragment
.
content
)
assert_in
(
"Question Drag & Drop"
,
student_fragment
.
content
)
assert_in
(
"(5 Points Possible)"
,
student_fragment
.
content
)
...
...
@@ -54,8 +53,7 @@ def test_templates_contents():
studio_fragment
=
block
.
render
(
'studio_view'
,
Mock
())
assert_in
(
'<div class="xblock--drag-and-drop editor-with-buttons">'
,
studio_fragment
.
content
)
assert_in
(
'<option value="{{ value }}">{{ value }}</option>'
,
studio_fragment
.
content
)
assert_in
(
'{{ value }}'
,
studio_fragment
.
content
)
def
test_studio_submit
():
block
=
make_block
()
...
...
tests/test_get_data.json
View file @
260d00f3
...
...
@@ -6,7 +6,6 @@
"id"
:
"zone-1"
,
"height"
:
100
,
"y"
:
"200"
,
"active"
:
true
,
"x"
:
"100"
,
"width"
:
200
},
...
...
@@ -16,7 +15,6 @@
"id"
:
"zone-2"
,
"height"
:
100
,
"y"
:
0
,
"active"
:
true
,
"x"
:
0
,
"width"
:
200
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment