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
7dca95f7
Commit
7dca95f7
authored
Jul 03, 2014
by
Filippo Valsorda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add basic support for the builder in Studio
parent
bfd34fef
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
1125 additions
and
33 deletions
+1125
-33
drag_and_drop_v2/drag_and_drop_v2.py
+8
-4
drag_and_drop_v2/public/css/drag_and_drop_edit.css
+417
-0
drag_and_drop_v2/public/js/drag_and_drop_edit.js
+640
-4
drag_and_drop_v2/templates/html/drag_and_drop.html
+0
-3
drag_and_drop_v2/templates/html/drag_and_drop_edit.html
+60
-22
No files found.
drag_and_drop_v2/drag_and_drop_v2.py
View file @
7dca95f7
...
@@ -43,7 +43,7 @@ class DragAndDropBlock(XBlock):
...
@@ -43,7 +43,7 @@ class DragAndDropBlock(XBlock):
display_name
=
"Drag and Drop"
,
display_name
=
"Drag and Drop"
,
help
=
"JSON spec as generated by the builder"
,
help
=
"JSON spec as generated by the builder"
,
scope
=
Scope
.
content
,
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":"http
://i0.kym-cdn.com/photos/images/newsfeed/000/030/404/1260585284155.png?1318992465
"}'
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":"http
s://i.imgur.com/PoI27ox.png
"}'
# default=textwrap.dedent("""
# default=textwrap.dedent("""
# {
# {
# feedback: {},
# feedback: {},
...
@@ -79,10 +79,14 @@ class DragAndDropBlock(XBlock):
...
@@ -79,10 +79,14 @@ class DragAndDropBlock(XBlock):
"""
"""
Editing view in Studio
Editing view in Studio
"""
"""
context
=
{}
fragment
=
Fragment
()
fragment
=
Fragment
()
fragment
.
add_content
(
render_template
(
'/templates/html/drag_and_drop_edit.html'
,
{
fragment
.
add_content
(
render_template
(
'/templates/html/drag_and_drop_edit.html'
,
context
))
'self'
:
self
,
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
.
add_javascript
(
load_resource
(
'public/js/drag_and_drop_edit.js'
))
fragment
.
initialize_js
(
'DragAndDropEditBlock'
)
fragment
.
initialize_js
(
'DragAndDropEditBlock'
)
...
...
drag_and_drop_v2/public/css/drag_and_drop_edit.css
0 → 100644
View file @
7dca95f7
/*** xBlock styles ***/
.xblock--drag-and-drop
{
width
:
100%
;
margin
:
0
;
padding
:
0
;
background
:
#fff
;
}
.xblock--drag-and-drop
h1
,
.xblock--drag-and-drop
h2
,
.xblock--drag-and-drop
h3
,
.xblock--drag-and-drop
h4
,
.xblock--drag-and-drop
h5
,
.xblock--drag-and-drop
h6
,
.xblock--drag-and-drop
p
,
.xblock--drag-and-drop
li
,
.xblock--drag-and-drop
a
{
font-family
:
Arial
;
}
.xblock--drag-and-drop
h1
{
color
:
#adadad
;
}
.xblock--drag-and-drop
h2
{
color
:
#333
;
margin
:
0
;
text-transform
:
uppercase
;
}
.xblock--drag-and-drop
header
p
,
.xblock--drag-and-drop
footer
p
{
color
:
#adadad
;
line-height
:
1.5em
;
}
.xblock--drag-and-drop
.small
{
font-size
:
0.6em
;
}
.xblock--drag-and-drop
.drag-container
{
width
:
760px
;
background
:
#ebf0f2
;
position
:
relative
;
}
/** Draggable Items **/
.xblock--drag-and-drop
.items
{
width
:
210px
;
margin
:
10px
;
padding
:
0
;
font-size
:
14px
;
position
:
relative
;
display
:
inline
;
float
:
left
;
list-style-type
:
none
;
}
.xblock--drag-and-drop
.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
{
background
:
url(../img/triangle.png)
no-repeat
;
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
{
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
;
}
.xblock--drag-and-drop
.drag-builder
{
/* TODO */
height
:
375px
;
overflow
:
scroll
;
}
.xblock--drag-and-drop
.drag-builder
.tab
{
width
:
100%
;
background
:
#eee
;
padding
:
3px
0
;
position
:
relative
;
}
.xblock--drag-and-drop
.drag-builder
.tab
:after
,
.xblock--drag-and-drop
.drag-builder
.tab-footer
:after
,
.xblock--drag-and-drop
.drag-builder
.target
:after
{
content
:
""
;
display
:
table
;
clear
:
both
;
}
.xblock--drag-and-drop
.drag-builder
.tab
h3
{
margin
:
10px
0
;
}
.xblock--drag-and-drop
.drag-builder
.tab-header
,
.xblock--drag-and-drop
.drag-builder
.tab-content
,
.xblock--drag-and-drop
.drag-builder
.tab-footer
{
width
:
96%
;
margin
:
2%
;
}
.xblock--drag-and-drop
.drag-builder
.tab-footer
{
height
:
25px
;
position
:
relative
;
display
:
block
;
float
:
left
;
}
.xblock--drag-and-drop
.drag-builder
.continue
{
position
:
absolute
;
right
:
0
;
top
:
-5px
;
}
.xblock--drag-and-drop
.drag-builder
.items
{
width
:
calc
(
100%
-
515px
);
margin
:
10px
0
0
0
;
}
.xblock--drag-and-drop
.drag-builder
.target
{
margin-left
:
0
;
}
.xblock--drag-and-drop
.zones-form
.zone-row
label
{
display
:
inline-block
;
width
:
18%
;
}
.xblock--drag-and-drop
.zones-form
.zone-row
.title
{
width
:
60%
;
margin
:
0
0
5px
;
}
.xblock--drag-and-drop
.zones-form
.zone-row
.layout
{
margin-bottom
:
15px
;
}
.xblock--drag-and-drop
.zones-form
.zone-row
.layout
.size
,
.xblock--drag-and-drop
.zones-form
.zone-row
.layout
.coord
{
width
:
15%
;
margin
:
0
19px
5px
0
;
}
.xblock--drag-and-drop
.drag-builder
.target
{
margin-bottom
:
40px
;
}
.xblock--drag-and-drop
.drag-builder
.zone
{
width
:
200px
;
height
:
100px
;
border
:
1px
dotted
#666
;
}
.xblock--drag-and-drop
.feedback-form
textarea
{
width
:
99%
;
height
:
128px
;
margin-bottom
:
30px
;
}
.xblock--drag-and-drop
.items-form
{
margin-bottom
:
30px
;
}
.xblock--drag-and-drop
.items-form
.item
{
background
:
#73bde7
;
padding
:
10px
0
1px
;
margin
:
15px
0
;
}
.xblock--drag-and-drop
.items-form
label
{
margin
:
0
1%
;
}
.xblock--drag-and-drop
.items-form
input
,
.xblock--drag-and-drop
.items-form
select
{
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%
;
}
.xblock--drag-and-drop
.items-form
.row
{
margin-bottom
:
20px
;
}
/** Buttons **/
.xblock--drag-and-drop
.btn
{
background
:
#2e83cd
;
color
:
#fff
;
border
:
1px
solid
#156ab4
;
border-radius
:
6px
;
padding
:
5px
10px
;
}
.xblock--drag-and-drop
.btn
:hover
{
opacity
:
0.8
;
cursor
:
pointer
;
}
.xblock--drag-and-drop
.btn
:focus
{
outline
:
none
;
opacity
:
0.5
;
}
.xblock--drag-and-drop
.add-element
{
text-decoration
:
none
;
color
:
#2e83cd
;
}
.xblock--drag-and-drop
.remove-zone
{
float
:
right
;
margin-top
:
2px
;
margin-right
:
16px
;
}
.xblock--drag-and-drop
.remove-item
{
display
:
inline-block
;
margin-left
:
95px
;
}
.xblock--drag-and-drop
.icon
{
width
:
14px
;
height
:
14px
;
border-radius
:
7px
;
background
:
#2e83cd
;
position
:
relative
;
float
:
left
;
margin
:
0
5px
0
0
;
}
.xblock--drag-and-drop
.add-zone
:hover
,
.xblock--drag-and-drop
.add-zone
:hover
.icon
,
.xblock--drag-and-drop
.remove-zone
:hover
,
.xblock--drag-and-drop
.remove-zone
:hover
.icon
{
opacity
:
0.7
;
}
.xblock--drag-and-drop
.icon.add
:before
{
content
:
''
;
height
:
10px
;
width
:
2px
;
background
:
#fff
;
position
:
relative
;
display
:
inline
;
float
:
left
;
top
:
2px
;
left
:
6px
;
}
.xblock--drag-and-drop
.icon.add
:after
{
content
:
''
;
height
:
2px
;
width
:
10px
;
background
:
#fff
;
position
:
relative
;
display
:
inline
;
float
:
left
;
top
:
6px
;
left
:
0
;
}
.xblock--drag-and-drop
.icon.remove
:before
{
content
:
''
;
height
:
10px
;
width
:
2px
;
background
:
#fff
;
position
:
relative
;
display
:
inline
;
float
:
left
;
top
:
2px
;
left
:
6px
;
-webkit-transform
:
rotate
(
45deg
);
-ms-transform
:
rotate
(
45deg
);
transform
:
rotate
(
45deg
);
}
.xblock--drag-and-drop
.icon.remove
:after
{
content
:
''
;
height
:
2px
;
width
:
10px
;
background
:
#fff
;
position
:
relative
;
display
:
inline
;
float
:
left
;
top
:
6px
;
left
:
0
;
-webkit-transform
:
rotate
(
45deg
);
-ms-transform
:
rotate
(
45deg
);
transform
:
rotate
(
45deg
);
}
.xblock--drag-and-drop
.remove-item
.icon.remove
{
background
:
#fff
;
}
.xblock--drag-and-drop
.remove-item
.icon.remove
:before
,
.xblock--drag-and-drop
.remove-item
.icon.remove
:after
{
background
:
#2e83cd
;
}
drag_and_drop_v2/public/js/drag_and_drop_edit.js
View file @
7dca95f7
function
DragAndDropEditBlock
(
runtime
,
element
)
{
function
DragAndDropEditBlock
(
runtime
,
element
)
{
$
(
element
).
find
(
'.save-button'
).
bind
(
'click'
,
function
()
{
var
dragAndDrop
=
(
function
(
$
)
{
var
_fn
=
{
// DOM Elements
$block
:
$
(
'.xblock--drag-and-drop'
,
element
),
$app
:
$
(
'.xblock--drag-and-drop .drag-container'
,
element
),
$ul
:
$
(
'.xblock--drag-and-drop .items'
,
element
),
$target
:
$
(
'.xblock--drag-and-drop .target-img'
,
element
),
$feedback
:
$
(
'.xblock--drag-and-drop .feedback .message'
,
element
),
// Cannot set until items added to DOM
$items
:
{},
// $('.xblock--drag-and-drop .items .option'),
$zones
:
{},
// $('.xblock--drag-and-drop .target .zone'),
// jQuery UI Draggable options
options
:
{
drag
:
{
containment
:
'.xblock--drag-and-drop .drag-container'
,
cursor
:
'move'
,
stack
:
'.xblock--drag-and-drop .items .option'
},
drop
:
{
accept
:
'.xblock--drag-and-drop .items .option'
,
tolerance
:
'pointer'
}
},
// item template
tpl
:
{
item
:
function
()
{
return
[
'<li class="option" data-value="<%= id %>"'
,
'style="width: <%= size.width %>; height: <%= size.height %>">'
,
'<%= displayName %>'
,
'</li>'
].
join
(
''
);
},
image_item
:
function
()
{
return
[
'<li class="option" data-value="<%= id %>"'
,
'style="width: <%= size.width %>; height: <%= size.height %>">'
,
'<img src="<%= backgroundImage %>" />'
,
'</li>'
].
join
(
''
);
},
zoneInput
:
function
()
{
return
[
'<div class="zone-row <%= name %>">'
,
'<label>Text</label>'
,
'<input type="text" class="title" placeholder="<%= 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" />'
,
'<label>height</label>'
,
'<input type="text" class="size height" value="100" />'
,
'<br />'
,
'<label>x</label>'
,
'<input type="text" class="coord x" value="0" />'
,
'<label>y</label>'
,
'<input type="text" class="coord y" value="0" />'
,
'</div>'
,
'</div>'
].
join
(
''
);
},
zoneElement
:
function
()
{
return
[
'<div id="<%= id %>" class="zone" data-zone="<%= title %>" style="'
,
'top:<%= y %>px;'
,
'left:<%= x %>px;'
,
'width:<%= width %>px;'
,
'height:<%= height %>px;">'
,
'<p><%= title %></p>'
,
'</div>'
].
join
(
''
);
},
zoneDropdown
:
'<option value="<%= value %>"><%= value %></option>'
,
itemInput
:
function
()
{
return
[
'<div class="item">'
,
'<div class="row">'
,
'<label>Text</label>'
,
'<input type="text" class="item-text"></input>'
,
'<label>Zone</label>'
,
'<select class="zone-select"><%= dropdown %></select>'
,
'<a href="#" class="remove-item hidden">'
,
'<div class="icon remove"></div>'
,
'</a>'
,
'</div>'
,
'<div class="row">'
,
'<label>Background image URL (alternative to the text)</label>'
,
'<textarea class="background-image"></textarea>'
,
'</div>'
,
'<div class="row">'
,
'<label>Success Feedback</label>'
,
'<textarea class="success-feedback"></textarea>'
,
'</div>'
,
'<div class="row">'
,
'<label>Error Feedback</label>'
,
'<textarea class="error-feedback"></textarea>'
,
'</div>'
,
'<div class="row">'
,
'<label>Width (px - 0 for auto)</label>'
,
'<input type="text" class="item-width" value="190"></input>'
,
'<label>Height (px - 0 for auto)</label>'
,
'<input type="text" class="item-height" value="0"></input>'
,
'</div>'
,
'</div>'
].
join
(
''
);
}
},
build
:
{
$el
:
{
feedback
:
{
form
:
$
(
'.xblock--drag-and-drop .drag-builder .feedback-form'
,
element
),
tab
:
$
(
'.xblock--drag-and-drop .drag-builder .feedback-tab'
,
element
)
},
zones
:
{
form
:
$
(
'.xblock--drag-and-drop .drag-builder .zones-form'
,
element
),
tab
:
$
(
'.xblock--drag-and-drop .drag-builder .zones-tab'
,
element
)
},
items
:
{
form
:
$
(
'.xblock--drag-and-drop .drag-builder .items-form'
,
element
),
tab
:
$
(
'.xblock--drag-and-drop .drag-builder .items-tab'
,
element
)
},
target
:
$
(
'.xblock--drag-and-drop .drag-builder .target-img'
,
element
)
},
init
:
function
()
{
_fn
.
build
.
clickHandlers
();
_fn
.
build
.
form
.
zone
.
add
();
_fn
.
$target
.
css
(
'background'
,
'url('
+
_fn
.
data
.
targetImg
+
') no-repeat'
);
},
clickHandlers
:
function
()
{
var
$fbkTab
=
_fn
.
build
.
$el
.
feedback
.
tab
,
$zoneTab
=
_fn
.
build
.
$el
.
zones
.
tab
,
$itemTab
=
_fn
.
build
.
$el
.
items
.
tab
;
$
(
element
).
one
(
'click'
,
'.continue-button'
,
function
(
e
)
{
e
.
preventDefault
();
_fn
.
build
.
form
.
feedback
(
_fn
.
build
.
$el
.
feedback
.
form
);
$fbkTab
.
addClass
(
'hidden'
);
$zoneTab
.
removeClass
(
'hidden'
);
// Placeholder shim for IE9
$
.
placeholder
.
shim
();
$
(
this
).
one
(
'click'
,
function
(
e
)
{
e
.
preventDefault
();
_fn
.
build
.
form
.
zone
.
setAll
();
_fn
.
build
.
form
.
item
.
add
();
$zoneTab
.
addClass
(
'hidden'
);
$itemTab
.
removeClass
(
'hidden'
);
// Placeholder shim for IE9
$
.
placeholder
.
shim
();
$
(
this
).
addClass
(
'hidden'
);
$
(
'.save-button'
,
element
).
parent
()
.
removeClass
(
'hidden'
)
.
one
(
'click'
,
function
(
e
)
{
e
.
preventDefault
();
_fn
.
build
.
form
.
submit
();
});
});
});
$zoneTab
.
on
(
'click'
,
'.add-zone'
,
_fn
.
build
.
form
.
zone
.
add
)
.
on
(
'click'
,
'.remove-zone'
,
_fn
.
build
.
form
.
zone
.
remove
)
.
on
(
'click'
,
'.target-image-form button'
,
function
(
e
)
{
e
.
preventDefault
();
_fn
.
data
.
targetImg
=
$
(
'.target-image-form input'
,
element
).
val
();
_fn
.
$target
.
css
(
'background'
,
'url('
+
_fn
.
data
.
targetImg
+
') no-repeat'
);
// Placeholder shim for IE9
$
.
placeholder
.
shim
();
});
$itemTab
.
on
(
'click'
,
'.add-item'
,
_fn
.
build
.
form
.
item
.
add
)
.
on
(
'click'
,
'.remove-item'
,
_fn
.
build
.
form
.
item
.
remove
);
},
form
:
{
zone
:
{
count
:
0
,
formCount
:
0
,
dropdown
:
''
,
list
:
[],
obj
:
[],
add
:
function
(
e
)
{
var
inputTemplate
=
_fn
.
tpl
.
zoneInput
(),
zoneTemplate
=
_fn
.
tpl
.
zoneElement
(),
name
=
'zone-'
,
$elements
=
_fn
.
build
.
$el
,
num
,
obj
;
if
(
e
)
{
e
.
preventDefault
();
}
_fn
.
build
.
form
.
zone
.
count
++
;
_fn
.
build
.
form
.
zone
.
formCount
++
;
num
=
_fn
.
build
.
form
.
zone
.
count
;
name
+=
num
;
// Update zone obj
zoneObj
=
{
title
:
'Zone '
+
num
,
id
:
name
,
active
:
false
,
index
:
num
,
width
:
200
,
height
:
100
,
x
:
0
,
y
:
0
};
_fn
.
build
.
form
.
zone
.
obj
.
push
(
zoneObj
);
// Add fields to zone position form
$elements
.
zones
.
form
.
append
(
_
.
template
(
inputTemplate
,
{
title
:
'Zone '
+
num
,
name
:
name
}));
_fn
.
build
.
form
.
zone
.
enableDelete
();
// Add zone div to target
$elements
.
target
.
append
(
_
.
template
(
zoneTemplate
,
zoneObj
)
);
// Listen to changes in form to update zone div
_fn
.
build
.
form
.
zone
.
clickHandler
(
num
);
// Placeholder shim for IE9
$
.
placeholder
.
shim
();
},
remove
:
function
(
e
)
{
var
$el
=
$
(
e
.
currentTarget
).
closest
(
'.zone-row'
),
classes
=
$el
.
attr
(
'class'
),
id
=
classes
.
slice
(
classes
.
indexOf
(
'zone-row'
)
+
9
);
e
.
preventDefault
();
$el
.
detach
();
$
(
'#'
+
id
,
element
).
detach
();
_fn
.
build
.
form
.
zone
.
formCount
--
;
_fn
.
build
.
form
.
zone
.
disableDelete
();
// Placeholder shim for IE9
$
.
placeholder
.
shim
();
},
enableDelete
:
function
()
{
if
(
_fn
.
build
.
form
.
zone
.
formCount
>
1
)
{
_fn
.
build
.
$el
.
zones
.
form
.
find
(
'.remove-zone'
).
removeClass
(
'hidden'
);
}
},
disableDelete
:
function
()
{
if
(
_fn
.
build
.
form
.
zone
.
formCount
===
1
)
{
_fn
.
build
.
$el
.
zones
.
form
.
find
(
'.remove-zone'
).
addClass
(
'hidden'
);
}
},
setAll
:
function
()
{
var
zones
=
[],
$form
=
_fn
.
build
.
$el
.
zones
.
form
.
find
(
'.title'
);
$form
.
each
(
function
(
i
,
el
)
{
var
val
=
$
(
el
).
val
();
if
(
val
.
length
>
0
)
{
zones
.
push
(
val
);
}
});
_fn
.
build
.
form
.
zone
.
list
=
zones
;
_fn
.
build
.
form
.
createDropdown
(
zones
);
},
clickHandler
:
function
(
num
)
{
var
$div
=
$
(
'#zone-'
+
num
,
element
),
$form
=
_fn
.
build
.
$el
.
zones
.
form
.
find
(
'.zone-row.zone-'
+
num
);
// Listen to form changes and update zone div position
$form
.
on
(
'keyup'
,
'.title'
,
function
(
e
)
{
var
text
=
$
(
e
.
currentTarget
).
val
(),
record
=
_
.
findWhere
(
_fn
.
build
.
form
.
zone
.
obj
,
{
index
:
num
});
$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
=
_
.
findWhere
(
_fn
.
build
.
form
.
zone
.
obj
,
{
index
:
num
});
$div
.
css
(
'width'
,
width
+
'px'
);
record
.
width
=
width
;
}).
on
(
'keyup'
,
'.height'
,
function
(
e
)
{
var
height
=
$
(
e
.
currentTarget
).
val
(),
record
=
_
.
findWhere
(
_fn
.
build
.
form
.
zone
.
obj
,
{
index
:
num
});
$div
.
css
(
'height'
,
height
+
'px'
);
record
.
height
=
height
;
}).
on
(
'keyup'
,
'.x'
,
function
(
e
)
{
var
x
=
$
(
e
.
currentTarget
).
val
(),
record
=
_
.
findWhere
(
_fn
.
build
.
form
.
zone
.
obj
,
{
index
:
num
});
$div
.
css
(
'left'
,
x
+
'px'
);
record
.
x
=
x
;
}).
on
(
'keyup'
,
'.y'
,
function
(
e
)
{
var
y
=
$
(
e
.
currentTarget
).
val
(),
record
=
_
.
findWhere
(
_fn
.
build
.
form
.
zone
.
obj
,
{
index
:
num
});
$div
.
css
(
'top'
,
y
+
'px'
);
record
.
y
=
y
;
});
},
cleanObject
:
function
(
arr
)
{
var
clean
=
[],
i
,
len
=
arr
.
length
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
if
(
arr
[
i
].
active
)
{
clean
.
push
(
arr
[
i
]
);
}
}
return
clean
;
}
},
createDropdown
:
function
(
arr
)
{
var
tpl
=
_fn
.
tpl
.
zoneDropdown
,
i
,
len
=
arr
.
length
,
dropdown
=
[],
html
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
dropdown
.
push
(
_
.
template
(
tpl
,
{
value
:
arr
[
i
]
}
)
);
}
// Add option to include dummy answers
dropdown
.
push
(
_
.
template
(
tpl
,
{
value
:
'none'
}
)
);
html
=
dropdown
.
join
(
''
);
_fn
.
build
.
form
.
zone
.
dropdown
=
html
;
_fn
.
build
.
$el
.
items
.
form
.
find
(
'.zone-select'
).
html
(
html
);
},
feedback
:
function
(
$form
)
{
_fn
.
data
.
feedback
=
{
start
:
$form
.
find
(
'.intro-feedback'
).
val
(),
finish
:
$form
.
find
(
'.final-feedback'
).
val
()
};
},
item
:
{
count
:
0
,
add
:
function
(
e
)
{
var
$form
=
_fn
.
build
.
$el
.
items
.
form
,
tpl
=
_fn
.
tpl
.
itemInput
();
if
(
e
)
{
e
.
preventDefault
();
}
_fn
.
build
.
form
.
item
.
count
++
;
$form
.
append
(
_
.
template
(
tpl
,
{
dropdown
:
_fn
.
build
.
form
.
zone
.
dropdown
}
)
);
_fn
.
build
.
form
.
item
.
enableDelete
();
// Placeholder shim for IE9
$
.
placeholder
.
shim
();
},
remove
:
function
(
e
)
{
var
$el
=
$
(
e
.
currentTarget
).
closest
(
'.item'
);
e
.
preventDefault
();
$el
.
detach
();
_fn
.
build
.
form
.
item
.
count
--
;
_fn
.
build
.
form
.
item
.
disableDelete
();
// Placeholder shim for IE9
$
.
placeholder
.
shim
();
},
enableDelete
:
function
()
{
if
(
_fn
.
build
.
form
.
item
.
count
>
1
)
{
_fn
.
build
.
$el
.
items
.
form
.
find
(
'.remove-item'
).
removeClass
(
'hidden'
);
}
},
disableDelete
:
function
()
{
if
(
_fn
.
build
.
form
.
item
.
count
===
1
)
{
_fn
.
build
.
$el
.
items
.
form
.
find
(
'.remove-item'
).
addClass
(
'hidden'
);
}
}
},
submit
:
function
()
{
var
items
=
[],
$form
=
_fn
.
build
.
$el
.
items
.
form
.
find
(
'.item'
);
$form
.
each
(
function
(
i
,
el
)
{
var
$el
=
$
(
el
),
name
=
$el
.
find
(
'.item-text'
).
val
(),
backgroundImage
=
$el
.
find
(
'.background-image'
).
val
();
if
(
name
.
length
>
0
||
backgroundImage
.
length
>
0
)
{
var
width
=
$el
.
find
(
'.item-width'
).
val
(),
height
=
$el
.
find
(
'.item-height'
).
val
();
if
(
height
===
'0'
)
height
=
'auto'
;
else
height
=
height
+
'px'
;
if
(
width
===
'0'
)
width
=
'auto'
;
else
width
=
width
+
'px'
;
items
.
push
({
displayName
:
name
,
zone
:
$el
.
find
(
'.zone-select'
).
val
(),
id
:
i
,
feedback
:
{
correct
:
$el
.
find
(
'.success-feedback'
).
val
(),
incorrect
:
$el
.
find
(
'.error-feedback'
).
val
()
},
size
:
{
width
:
width
,
height
:
height
},
backgroundImage
:
backgroundImage
});
}
});
_fn
.
data
.
items
=
items
;
_fn
.
data
.
zones
=
_fn
.
build
.
form
.
zone
.
cleanObject
(
_fn
.
build
.
form
.
zone
.
obj
);
var
data
=
{
var
data
=
{
'display_name'
:
$
(
element
).
find
(
'.edit-
display-name'
).
val
(),
'display_name'
:
$
(
element
).
find
(
'.
display-name'
).
val
(),
'question_text'
:
$
(
element
).
find
(
'.edit-
question-text'
).
val
(),
'question_text'
:
$
(
element
).
find
(
'.
question-text'
).
val
(),
'data'
:
$
(
element
).
find
(
'.edit-data'
).
val
()
'data'
:
JSON
.
stringify
(
_fn
.
data
),
};
};
$
(
'.xblock-editor-error-message'
,
element
).
html
();
$
(
'.xblock-editor-error-message'
,
element
).
html
();
...
@@ -17,9 +466,196 @@ function DragAndDropEditBlock(runtime, element) {
...
@@ -17,9 +466,196 @@ function DragAndDropEditBlock(runtime, element) {
$
(
'.xblock-editor-error-message'
,
element
).
css
(
'display'
,
'block'
);
$
(
'.xblock-editor-error-message'
,
element
).
css
(
'display'
,
'block'
);
}
}
});
});
}
}
},
finish
:
function
()
{
// Disable any decoy items
_fn
.
$items
.
draggable
(
'disable'
);
// Show final feedback
_fn
.
feedback
.
set
(
_fn
.
data
.
feedback
.
finish
);
},
clickHandlers
:
{
init
:
function
(
$drag
,
$dropzone
)
{
var
clk
=
_fn
.
clickHandlers
;
$drag
.
on
(
'dragstart'
,
clk
.
drag
.
start
);
$drag
.
on
(
'dragstop'
,
clk
.
drag
.
stop
);
$dropzone
.
on
(
'drop'
,
clk
.
drop
.
success
);
$dropzone
.
on
(
'dropover'
,
clk
.
drop
.
hover
.
in
);
$dropzone
.
on
(
'dropout'
,
clk
.
drop
.
hover
.
out
);
},
drag
:
{
start
:
function
(
event
,
ui
)
{
$
(
event
.
currentTarget
).
removeClass
(
'within-dropzone fade'
);
},
stop
:
function
(
event
,
ui
)
{
var
$el
=
$
(
event
.
currentTarget
),
val
=
$el
.
data
(
'value'
),
zone
=
$el
.
data
(
'zone'
)
||
null
;
if
(
$el
.
hasClass
(
'within-dropzone'
)
&&
_fn
.
test
.
match
(
val
,
zone
)
)
{
$el
.
removeClass
(
'hover'
)
.
draggable
(
'disable'
);
_fn
.
test
.
completed
++
;
_fn
.
feedback
.
popup
(
_fn
.
feedback
.
get
(
val
,
true
),
true
);
if
(
_fn
.
items
.
allSubmitted
()
)
{
_fn
.
finish
();
}
}
else
{
// Return to original position
_fn
.
clickHandlers
.
drag
.
reset
(
$el
);
_fn
.
feedback
.
popup
(
_fn
.
feedback
.
get
(
val
,
false
),
false
);
}
},
reset
:
function
(
$el
)
{
$el
.
removeClass
(
'within-dropzone fade hover'
)
.
css
({
top
:
''
,
left
:
''
});
}
},
drop
:
{
hover
:
{
in
:
function
(
event
,
ui
)
{
var
zone
=
$
(
event
.
currentTarget
).
data
(
'zone'
);
ui
.
draggable
.
addClass
(
'hover'
).
data
(
'zone'
,
zone
);
},
out
:
function
(
event
,
ui
)
{
ui
.
draggable
.
removeClass
(
'hover'
);
}
},
success
:
function
(
event
,
ui
)
{
ui
.
draggable
.
addClass
(
'within-dropzone'
)
}
}
},
items
:
{
count
:
0
,
init
:
function
()
{
var
items
=
_fn
.
data
.
items
,
i
,
len
=
items
.
length
,
total
=
0
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
if
(
items
[
i
].
zone
!==
'none'
)
{
total
++
;
}
}
_fn
.
items
.
count
=
total
;
},
allSubmitted
:
function
()
{
return
_fn
.
test
.
completed
===
_fn
.
items
.
count
;
},
draw
:
function
()
{
var
list
=
[],
items
=
_fn
.
data
.
items
,
tpl
=
_fn
.
tpl
.
item
(),
img_tpl
=
_fn
.
tpl
.
image_item
();
_
.
each
(
items
,
function
(
item
)
{
if
(
item
.
backgroundImage
.
length
>
0
)
{
list
.
push
(
_
.
template
(
img_tpl
,
item
)
);
}
else
{
list
.
push
(
_
.
template
(
tpl
,
item
)
);
}
});
});
// Update DOM
_fn
.
$ul
.
html
(
list
.
join
(
''
)
);
// Set variable
_fn
.
$items
=
$
(
'.xblock--drag-and-drop .items .option'
,
element
);
}
},
zones
:
{
draw
:
function
()
{
var
html
=
[],
zones
=
_fn
.
data
.
zones
,
tpl
=
_fn
.
tpl
.
zoneElement
(),
i
,
len
=
zones
.
length
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
html
.
push
(
_
.
template
(
tpl
,
zones
[
i
]
)
);
}
// Update DOM
_fn
.
$target
.
html
(
html
.
join
(
''
)
);
// Set variable
_fn
.
$zones
=
_fn
.
$target
.
find
(
'.zone'
);
}
},
test
:
{
completed
:
0
,
match
:
function
(
id
,
zone
)
{
var
item
=
_
.
findWhere
(
_fn
.
data
.
items
,
{
id
:
id
}
);
return
item
.
zone
===
zone
;
}
},
feedback
:
{
// Returns string based on user's answer
get
:
function
(
id
,
boo
)
{
var
item
,
type
=
boo
?
'correct'
:
'incorrect'
;
// Null loses its string-ness
if
(
id
===
null
)
{
id
=
'null'
;
}
// Get object from data.items that matches val
item
=
_
.
findWhere
(
_fn
.
data
.
items
,
{
id
:
id
});
return
item
.
feedback
[
type
];
},
// Update DOM with feedback
set
:
function
(
str
)
{
return
_fn
.
$feedback
.
html
(
str
);
},
// Show a feedback popup
popup
:
function
(
str
,
boo
)
{
if
(
str
===
undefined
||
str
===
''
)
return
;
return
$
(
"<div>"
).
attr
(
'title'
,
boo
?
'Correct'
:
'Error'
).
text
(
str
).
dialog
();
}
},
data
:
{
feedback
:
{},
items
:
[],
zones
:
[],
targetImg
:
'https://i.imgur.com/PoI27ox.png'
}
};
return
{
builder
:
_fn
.
build
.
init
};
})(
jQuery
);
$
(
element
).
find
(
'.cancel-button'
).
bind
(
'click'
,
function
()
{
$
(
element
).
find
(
'.cancel-button'
).
bind
(
'click'
,
function
()
{
runtime
.
notify
(
'cancel'
,
{});
runtime
.
notify
(
'cancel'
,
{});
});
});
dragAndDrop
.
builder
();
}
}
drag_and_drop_v2/templates/html/drag_and_drop.html
View file @
7dca95f7
...
@@ -26,7 +26,4 @@
...
@@ -26,7 +26,4 @@
<div
class=
"clear"
></div>
<div
class=
"clear"
></div>
</section>
</section>
<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>
</section>
</section>
drag_and_drop_v2/templates/html/drag_and_drop_edit.html
View file @
7dca95f7
{% load i18n %}
{% load i18n %}
<!-- TODO: Replace by default edit view once available in Studio -->
<div
class=
"xblock--drag-and-drop editor-with-buttons"
>
<div
class=
"wrapper-comp-settings is-active editor-with-buttons "
id=
"settings-tab"
>
<link
rel=
"stylesheet"
href=
"https://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css"
>
<ul
class=
"list-input settings-list"
>
<li
class=
"field comp-setting-entry is-set"
>
<section
class=
"drag-builder"
>
<div
class=
"wrapper-comp-setting"
>
<label
class=
"label setting-label"
for=
"edit_display_name"
>
Title
</label>
<div
class=
"tab feedback-tab"
>
<input
class=
"input setting-input edit-display-name"
id=
"edit_display_name"
value=
"{{ self.display_name }}"
type=
"text"
>
<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>
<h3>
Final Feedback
</h3>
<textarea
class=
"final-feedback"
></textarea>
</form>
</section>
<!-- <footer class="tab-footer">
<button class="btn continue goto-zones">Continue</button>
</footer> -->
</div>
</div>
<span
class=
"tip setting-help"
>
The title of the Drag and Drop that is displayed to the user
</span>
</li>
<div
class=
"tab zones-tab hidden"
>
<li
class=
"field comp-setting-entry is-set"
>
<header
class=
"tab-header"
>
<div
class=
"wrapper-comp-setting"
>
<h3>
Zone Positions
</h3>
<label
class=
"label setting-label"
for=
"edit_question_text"
>
Question text
</label>
</header>
<input
class=
"input setting-input edit-question-text"
id=
"edit_question_text"
value=
"{{ self.question_text }}"
type=
"text"
>
<section
class=
"tab-content"
>
<div
class=
"items"
>
<form
class=
"zones-form"
></form>
<a
href=
"#"
class=
"add-zone add-element"
><div
class=
"icon add"
></div>
Add a zone
</a>
</div>
</div>
<span
class=
"tip setting-help"
>
The question text that is displayed to the user
</span>
<div
class=
"target"
>
</li>
<div
class=
"target-img"
></div>
<li
class=
"field comp-setting-entry is-set"
>
<div
class=
"wrapper-comp-setting"
>
<label
class=
"label setting-label"
for=
"edit_data"
>
Title
</label>
<input
class=
"input setting-input edit-data"
id=
"edit_data"
value=
"{{ self.data }}"
type=
"text"
>
</div>
</div>
<span
class=
"tip setting-help"
>
JSON spec as generated by the builder
</span>
</section>
</li>
<!-- <footer class="tab-footer">
</ul>
<button class="btn continue goto-items">Continue</button>
</footer> -->
</div>
<div
class=
"tab items-tab hidden"
>
<header
class=
"tab-header"
>
<h3>
Items
</h3>
</header>
<section
class=
"tab-content"
>
<form
class=
"items-form"
></form>
</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> -->
</footer>
</div>
</section>
<div
class=
"xblock-actions"
>
<div
class=
"xblock-actions"
>
<span
class=
"xblock-editor-error-message"
></span>
<span
class=
"xblock-editor-error-message"
></span>
<ul>
<ul>
<li
class=
"action-item"
>
<li
class=
"action-item"
>
<a
href=
"#"
class=
"button action-primary continue-button"
>
{% trans "Continue" %}
</a>
</li>
<li
class=
"action-item hidden"
>
<a
href=
"#"
class=
"button action-primary save-button"
>
{% trans "Save" %}
</a>
<a
href=
"#"
class=
"button action-primary save-button"
>
{% trans "Save" %}
</a>
</li>
</li>
...
...
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