Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
X
xblock-vectordraw
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
edx
xblock-vectordraw
Commits
9e6e0011
Commit
9e6e0011
authored
Nov 30, 2015
by
Tim Krones
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Address review comments.
parent
602d0212
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
251 additions
and
151 deletions
+251
-151
tests/integration/test_vectordraw.py
+28
-9
vectordraw/public/css/vectordraw.css
+1
-1
vectordraw/public/css/vectordraw_edit.css
+15
-1
vectordraw/public/js/vectordraw.js
+8
-4
vectordraw/public/js/vectordraw_edit.js
+101
-74
vectordraw/templates/html/vectordraw.html
+4
-4
vectordraw/templates/html/vectordraw_edit.html
+94
-58
No files found.
tests/integration/test_vectordraw.py
View file @
9e6e0011
...
...
@@ -105,20 +105,33 @@ class TestVectorDraw(StudioEditableBaseTest):
def
check_vector_properties
(
self
,
menu
,
is_present
=
False
,
expected_label
=
"Vector Properties"
,
expected_name
=
None
,
expected_tail
=
None
,
expected_length
=
None
,
expected_angle
=
None
expected_name
=
None
,
expected_tail
=
None
,
expected_length
=
None
,
expected_angle
=
None
,
input_fields_disabled
=
True
):
if
is_present
:
vector_properties
=
menu
.
find_element_by_css_selector
(
".vector-properties"
)
vector_properties_label
=
vector_properties
.
find_element_by_css_selector
(
"h3"
)
self
.
assertEquals
(
vector_properties_label
.
text
,
expected_label
)
# Name
self
.
check_vector_property
(
vector_properties
,
"name"
,
"select"
,
"name:"
,
expected_name
or
"-"
)
self
.
check_vector_property
(
vector_properties
,
"name"
,
"select"
,
"name:"
,
expected_name
or
"-"
,
field_disabled
=
input_fields_disabled
)
# Tail
self
.
check_vector_property
(
vector_properties
,
"tail"
,
"input"
,
"tail position:"
,
expected_tail
or
"-"
)
self
.
check_vector_property
(
vector_properties
,
"tail"
,
"input"
,
"tail position:"
,
expected_tail
or
""
,
field_disabled
=
input_fields_disabled
)
# Length
self
.
check_vector_property
(
vector_properties
,
"length"
,
"input"
,
"length:"
,
expected_length
or
"-"
)
self
.
check_vector_property
(
vector_properties
,
"length"
,
"input"
,
"length:"
,
expected_length
or
""
,
field_disabled
=
input_fields_disabled
)
# Angle
self
.
check_vector_property
(
vector_properties
,
"angle"
,
"input"
,
"angle:"
,
expected_angle
or
"-"
)
self
.
check_vector_property
(
vector_properties
,
"angle"
,
"input"
,
"angle:"
,
expected_angle
or
""
,
field_disabled
=
input_fields_disabled
)
# Slope
vector_slope
=
vector_properties
.
find_element_by_css_selector
(
".vector-prop-slope"
)
self
.
assertFalse
(
vector_slope
.
is_displayed
())
...
...
@@ -130,7 +143,8 @@ class TestVectorDraw(StudioEditableBaseTest):
)
def
check_vector_property
(
self
,
vector_properties
,
property_name
,
input_type
,
expected_label
,
expected_value
=
None
self
,
vector_properties
,
property_name
,
input_type
,
expected_label
,
expected_value
=
None
,
field_disabled
=
False
):
vector_property
=
vector_properties
.
find_element_by_css_selector
(
".vector-prop-{}"
.
format
(
property_name
)
...
...
@@ -145,6 +159,8 @@ class TestVectorDraw(StudioEditableBaseTest):
)
if
input_type
==
"input"
:
self
.
assertEquals
(
vector_property_input
.
get_attribute
(
"value"
),
expected_value
)
disabled
=
vector_property_input
.
get_attribute
(
"disabled"
)
self
.
assertEquals
(
bool
(
disabled
),
field_disabled
)
else
:
selected_option
=
vector_property_input
.
find_element_by_css_selector
(
'option[selected="selected"]'
)
self
.
assertEquals
(
selected_option
.
text
,
expected_value
)
...
...
@@ -297,7 +313,8 @@ class TestVectorDraw(StudioEditableBaseTest):
# "Vector Properties" should display correct info
self
.
check_vector_properties
(
menu
,
is_present
=
True
,
expected_label
=
"Custom properties label"
,
expected_name
=
"N"
,
expected_tail
=
"2.00, 2.00"
,
expected_length
=
"4.00"
,
expected_angle
=
"45.00"
expected_name
=
"N"
,
expected_tail
=
"2.00, 2.00"
,
expected_length
=
"4.00"
,
expected_angle
=
"45.00"
,
input_fields_disabled
=
False
)
self
.
check_edit_dropdown
(
menu
,
vectors
)
...
...
@@ -330,7 +347,8 @@ class TestVectorDraw(StudioEditableBaseTest):
# "Vector Properties" should display correct info
self
.
check_vector_properties
(
menu
,
is_present
=
True
,
expected_label
=
"Custom properties label"
,
expected_name
=
"N"
,
expected_tail
=
"2.00, 2.00"
,
expected_length
=
"4.00"
,
expected_angle
=
"45.00"
expected_name
=
"N"
,
expected_tail
=
"2.00, 2.00"
,
expected_length
=
"4.00"
,
expected_angle
=
"45.00"
,
input_fields_disabled
=
False
)
def
reset
(
self
,
board
,
vectors
,
points
):
...
...
@@ -552,7 +570,8 @@ class TestVectorDraw(StudioEditableBaseTest):
menu
=
self
.
exercise
.
find_element_by_css_selector
(
".menu"
)
self
.
check_vector_properties
(
menu
,
is_present
=
True
,
expected_label
=
"Custom properties label"
,
expected_name
=
"N"
,
expected_tail
=
"2.00, 2.00"
,
expected_length
=
"4.00"
,
expected_angle
=
"45.00"
expected_name
=
"N"
,
expected_tail
=
"2.00, 2.00"
,
expected_length
=
"4.00"
,
expected_angle
=
"45.00"
,
input_fields_disabled
=
False
)
@data
(
...
...
vectordraw/public/css/vectordraw.css
View file @
9e6e0011
...
...
@@ -123,7 +123,7 @@
}
.vectordraw_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-update
.update-error
{
visibility
:
hidden
;
display
:
none
;
color
:
#ff0000
;
}
...
...
vectordraw/public/css/vectordraw_edit.css
View file @
9e6e0011
...
...
@@ -14,6 +14,10 @@
margin-bottom
:
1em
;
}
.vectordraw_edit_block
#wysiwyg-description
{
display
:
none
;
}
.vectordraw_edit_block
p
{
margin-bottom
:
1em
;
font-size
:
0.9em
;
...
...
@@ -59,6 +63,11 @@
float
:
right
;
}
.vectordraw_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-update
.update-pending
{
display
:
none
;
color
:
#ffa500
;
}
.vectordraw_edit_block
h3
{
margin-top
:
5px
;
margin-bottom
:
5px
;
...
...
@@ -83,11 +92,16 @@
}
.vectordraw_edit_block
.checks
.check
span
,
.vectordraw_edit_block
.checks
.check
input
[
type
=
"
text
"
]
{
.vectordraw_edit_block
.checks
.check
input
[
type
=
"
number
"
]
{
height
:
1.5em
;
min-width
:
0px
;
margin-right
:
12px
;
}
.vectordraw_edit_block
.checks
.check
input
[
type
=
"number"
]
{
padding
:
0
0
0
5px
;
}
.vectordraw_edit_block
.checks
.check
input
[
type
=
"checkbox"
]
{
height
:
1.2em
;
width
:
20%
;
...
...
vectordraw/public/js/vectordraw.js
View file @
9e6e0011
...
...
@@ -367,6 +367,10 @@ function VectorDrawXBlock(runtime, element, init_args) {
$
(
'.vector-prop-slope input'
,
this
.
element
).
val
(
slope
.
toFixed
(
2
));
}
}
// Enable input fields
$
(
'.vector-properties input'
).
prop
(
'disabled'
,
false
);
// Hide error message
$
(
'.vector-prop-update .update-error'
,
element
).
hide
();
};
VectorDraw
.
prototype
.
resetVectorProperties
=
function
(
vector
)
{
...
...
@@ -374,8 +378,8 @@ function VectorDrawXBlock(runtime, element, init_args) {
this
.
element
.
find
(
'.menu .element-list-edit option'
).
attr
(
'selected'
,
false
);
// Select default value
$
(
'.menu .element-list-edit option[value="-"]'
,
element
).
attr
(
'selected'
,
true
);
// Reset input fields to default values
$
(
'.menu .vector-prop-list input'
,
element
).
val
(
'-
'
);
// Reset input fields to default values
and disable them
$
(
'.menu .vector-prop-list input'
,
element
).
prop
(
'disabled'
,
true
).
val
(
'
'
);
};
VectorDraw
.
prototype
.
isVectorTailDraggable
=
function
(
vector
)
{
...
...
@@ -478,7 +482,7 @@ function VectorDrawXBlock(runtime, element, init_args) {
var
values
=
[
newTail
[
0
],
newTail
[
1
],
newLength
,
newAngle
];
// Validate values
if
(
!
_
.
some
(
values
,
Number
.
isNaN
))
{
$
(
'.vector-prop-update .update-error'
,
element
).
css
(
'visibility'
,
'hidden'
);
$
(
'.vector-prop-update .update-error'
,
element
).
hide
(
);
// Use coordinates of new tail, new length, new angle to calculate new position of tip
var
radians
=
newAngle
*
Math
.
PI
/
180
;
var
newTip
=
[
...
...
@@ -491,7 +495,7 @@ function VectorDrawXBlock(runtime, element, init_args) {
board_object
.
point2
.
setPosition
(
JXG
.
COORDS_BY_USER
,
newTip
);
this
.
board
.
update
();
}
else
{
$
(
'.vector-prop-update .update-error'
,
element
).
css
(
'visibility'
,
'visible'
);
$
(
'.vector-prop-update .update-error'
,
element
).
show
(
);
}
};
...
...
vectordraw/public/js/vectordraw_edit.js
View file @
9e6e0011
...
...
@@ -4,11 +4,15 @@ function VectorDrawXBlockEdit(runtime, element, init_args) {
var
VectorDraw
=
function
(
element_id
,
settings
)
{
this
.
board
=
null
;
this
.
dragged_vector
=
null
;
this
.
selectedVector
=
null
;
this
.
drawMode
=
false
;
this
.
wasUsed
=
false
;
this
.
resultMode
=
false
;
this
.
settings
=
settings
;
this
.
numberOfVectors
=
this
.
settings
.
vectors
.
length
;
this
.
checks
=
[
'tail'
,
'tail_x'
,
'tail_y'
,
'tip'
,
'tip_x'
,
'tip_y'
,
'coords'
,
'length'
,
'angle'
];
this
.
element
=
$
(
'#'
+
element_id
,
element
);
this
.
element
.
on
(
'click'
,
'.controls .add-vector'
,
this
.
onAddVector
.
bind
(
this
));
...
...
@@ -28,17 +32,10 @@ function VectorDrawXBlockEdit(runtime, element, init_args) {
// (without making necessary adjustments in "Expected results" field)
// discard stale information about expected positions and checks
var
vectorData
=
JSON
.
parse
(
fieldEditor
.
getContents
(
'vectors'
)),
vectorNames
=
_
.
pluck
(
vectorData
,
'name'
);
_
.
each
(
_
.
keys
(
this
.
settings
.
expected_result_positions
),
function
(
key
)
{
if
(
!
_
.
contains
(
vectorNames
,
key
))
{
delete
this
.
settings
.
expected_result_positions
[
key
];
}
},
this
);
_
.
each
(
_
.
keys
(
this
.
settings
.
expected_result
),
function
(
key
)
{
if
(
!
_
.
contains
(
vectorNames
,
key
))
{
delete
this
.
settings
.
expected_result
[
key
];
}
},
this
);
vectorNames
=
this
.
getVectorNames
(
vectorData
);
var
isStale
=
function
(
key
)
{
return
!
_
.
contains
(
vectorNames
,
key
);
};
this
.
settings
.
expected_result_positions
=
_
.
omit
(
this
.
settings
.
expected_result_positions
,
isStale
);
this
.
settings
.
expected_result
=
_
.
omit
(
this
.
settings
.
expected_result
,
isStale
);
};
VectorDraw
.
prototype
.
render
=
function
()
{
...
...
@@ -112,6 +109,13 @@ function VectorDrawXBlockEdit(runtime, element, init_args) {
this
.
board
.
create
(
'point'
,
coords
,
point
.
style
);
};
VectorDraw
.
prototype
.
getVectorNames
=
function
(
vectorData
)
{
if
(
vectorData
)
{
return
_
.
pluck
(
vectorData
,
'name'
);
}
return
_
.
pluck
(
this
.
settings
.
vectors
,
'name'
);
};
VectorDraw
.
prototype
.
getVectorCoordinates
=
function
(
vec
)
{
var
coords
=
vec
.
coords
;
if
(
!
coords
)
{
...
...
@@ -232,26 +236,22 @@ function VectorDrawXBlockEdit(runtime, element, init_args) {
var
boardObject
=
this
.
board
.
elementsByName
[
vectorName
];
this
.
board
.
removeAncestors
(
boardObject
);
// 2. Mark vector as "deleted" so it will be removed from "vectors" field on save
var
vectorSettings
=
this
.
getVectorSettingsByName
(
""
+
vectorName
);
var
vectorSettings
=
this
.
getVectorSettingsByName
(
String
(
vectorName
)
);
vectorSettings
.
deleted
=
true
;
// 3. Remove entry that corresponds to selected vector from menu for selecting vector to edit
var
idx
=
_
.
indexOf
(
this
.
settings
.
vectors
,
vectorSettings
),
editOption
=
this
.
getEditMenuOption
(
"vector"
,
idx
);
editOption
.
remove
();
// 4. Discard information about expected position
var
expectedPositions
=
this
.
settings
.
expected_result_positions
;
if
(
expectedPositions
[
vectorName
])
{
delete
expectedPositions
[
vectorName
];
this
.
settings
.
expected_result_positions
=
expectedPositions
;
}
// 5. Discard information about expected result
var
expectedResults
=
this
.
settings
.
expected_result
;
if
(
expectedResults
[
vectorName
])
{
delete
expectedResults
[
vectorName
];
this
.
settings
.
expected_result
=
expectedResults
;
}
// 4. Discard information about expected position (if any)
delete
this
.
settings
.
expected_result_positions
[
vectorName
];
// 5. Discard information about expected result (if any)
delete
this
.
settings
.
expected_result
[
vectorName
];
// 6. Reset input fields for vector properties to default values
this
.
resetVectorProperties
();
// 7. Reset selected vector
this
.
selectedVector
=
null
;
// 8. Hide message about pending changes
$
(
'.vector-prop-update .update-pending'
,
element
).
hide
();
};
VectorDraw
.
prototype
.
onEditResult
=
function
(
evt
)
{
...
...
@@ -259,6 +259,9 @@ function VectorDrawXBlockEdit(runtime, element, init_args) {
this
.
resultMode
=
true
;
// Save vector positions
this
.
settings
.
vectors
=
this
.
getState
();
// Discards vectors that were removed from board
// Vector positions saved, so hide message about pending changes
this
.
selectedVector
=
null
;
$
(
'.vector-prop-update .update-pending'
,
element
).
hide
();
// Update vector positions using positions from expected result
var
expectedResultPositions
=
this
.
settings
.
expected_result_positions
;
if
(
!
_
.
isEmpty
(
expectedResultPositions
))
{
...
...
@@ -286,13 +289,17 @@ function VectorDrawXBlockEdit(runtime, element, init_args) {
this
.
resetVectorProperties
();
// Show controls for opting in and out of checks
$
(
'.checks'
,
element
).
show
();
// Disable input fields that users should not be able to interact with unless a vector is selected
_
.
each
([
'tail'
,
'length'
,
'angle'
],
function
(
propName
)
{
$
(
'.vector-prop-'
+
propName
+
' input'
,
element
).
prop
(
'disabled'
,
true
);
});
};
VectorDraw
.
prototype
.
resetVectorProperties
=
function
(
vector
)
{
// Select default value
$
(
'.menu .element-list-edit option[value="-"]'
,
element
).
attr
(
'selected'
,
true
);
// Reset input fields to default values
$
(
'.menu .vector-prop-list input'
,
element
).
val
(
'
-
'
);
$
(
'.menu .vector-prop-list input'
,
element
).
val
(
''
);
};
VectorDraw
.
prototype
.
getMouseCoords
=
function
(
evt
)
{
...
...
@@ -335,6 +342,12 @@ function VectorDrawXBlockEdit(runtime, element, init_args) {
if
(
angle
<
0
)
{
angle
+=
360
;
}
// If user selected different vector, hide message about pending changes
if
(
this
.
selectedVector
&&
vector
.
name
!==
this
.
selectedVector
.
name
)
{
$
(
'.vector-prop-update .update-pending'
,
element
).
hide
();
}
// Update selected vector
this
.
selectedVector
=
vector
;
// Update menu for selecting vector to edit
this
.
element
.
find
(
'.menu .element-list-edit option'
).
attr
(
'selected'
,
false
);
var
idx
=
_
.
indexOf
(
this
.
settings
.
vectors
,
vec_settings
),
...
...
@@ -342,7 +355,7 @@ function VectorDrawXBlockEdit(runtime, element, init_args) {
editOption
.
attr
(
'selected'
,
true
);
// Update properties
$
(
'.vector-prop-name input'
,
this
.
element
).
val
(
vector
.
name
);
$
(
'.vector-prop-label input'
,
this
.
element
).
val
(
vec_settings
.
style
.
label
||
'
-
'
);
$
(
'.vector-prop-label input'
,
this
.
element
).
val
(
vec_settings
.
style
.
label
||
''
);
$
(
'.vector-prop-angle input'
,
this
.
element
).
val
(
angle
.
toFixed
(
2
));
if
(
vector
.
elType
!==
"line"
)
{
var
tailInput
=
x1
.
toFixed
(
2
)
+
", "
+
y1
.
toFixed
(
2
);
...
...
@@ -357,14 +370,13 @@ function VectorDrawXBlockEdit(runtime, element, init_args) {
else
{
$
(
'.vector-prop-length'
,
this
.
element
).
hide
();
}
// Enable input fields
$
(
'.vector-properties input'
).
prop
(
'disabled'
,
false
);
};
VectorDraw
.
prototype
.
updateChecks
=
function
(
vector
)
{
var
expectedResult
=
this
.
settings
.
expected_result
[
vector
.
name
]
||
{};
var
checks
=
[
'tail'
,
'tail_x'
,
'tail_y'
,
'tip'
,
'tip_x'
,
'tip_y'
,
'coords'
,
'length'
,
'angle'
];
_
.
each
(
checks
,
function
(
check
)
{
_
.
each
(
this
.
checks
,
function
(
check
)
{
var
checkElement
=
$
(
'#check-'
+
check
,
element
);
// Update checkbox
if
(
expectedResult
[
check
])
{
...
...
@@ -375,10 +387,10 @@ function VectorDrawXBlockEdit(runtime, element, init_args) {
// Update tolerance
var
tolerance
=
expectedResult
[
check
+
'_tolerance'
];
if
(
tolerance
)
{
checkElement
.
find
(
'input[type="
text
"]'
).
val
(
tolerance
.
toFixed
(
1
));
checkElement
.
find
(
'input[type="
number
"]'
).
val
(
tolerance
.
toFixed
(
1
));
}
else
{
var
defaultTolerance
=
check
===
'angle'
?
2.0
:
1.0
;
checkElement
.
find
(
'input[type="
text
"]'
).
val
(
defaultTolerance
.
toFixed
(
1
));
checkElement
.
find
(
'input[type="
number
"]'
).
val
(
defaultTolerance
.
toFixed
(
1
));
}
});
};
...
...
@@ -400,16 +412,13 @@ function VectorDrawXBlockEdit(runtime, element, init_args) {
VectorDraw
.
prototype
.
saveChecks
=
function
(
vectorName
)
{
var
expectedResult
=
{};
var
checks
=
[
'tail'
,
'tail_x'
,
'tail_y'
,
'tip'
,
'tip_x'
,
'tip_y'
,
'coords'
,
'length'
,
'angle'
];
_
.
each
(
checks
,
function
(
check
)
{
_
.
each
(
this
.
checks
,
function
(
check
)
{
var
checkElement
=
$
(
'#check-'
+
check
,
element
);
if
(
checkElement
.
find
(
'input[type="checkbox"]'
).
prop
(
'checked'
))
{
// Insert (or update) check: Need current position of selected vector
expectedResult
[
check
]
=
this
.
settings
.
expected_result_positions
[
vectorName
][
check
];
// Insert (or update) tolerance
var
tolerance
=
checkElement
.
find
(
'input[type="
text
"]'
).
val
();
var
tolerance
=
checkElement
.
find
(
'input[type="
number
"]'
).
val
();
expectedResult
[
check
+
'_tolerance'
]
=
parseFloat
(
tolerance
);
}
},
this
);
...
...
@@ -457,7 +466,7 @@ function VectorDrawXBlockEdit(runtime, element, init_args) {
VectorDraw
.
prototype
.
getDefaultVector
=
function
(
coords
)
{
this
.
numberOfVectors
+=
1
;
var
name
=
""
+
this
.
numberOfVectors
,
var
name
=
String
(
this
.
numberOfVectors
)
,
description
=
"Vector "
+
name
;
return
{
name
:
name
,
...
...
@@ -504,7 +513,11 @@ function VectorDrawXBlockEdit(runtime, element, init_args) {
this
.
dragged_vector
.
point1
.
setProperty
({
fixed
:
false
});
this
.
updateVectorProperties
(
this
.
dragged_vector
);
if
(
this
.
resultMode
)
{
_
.
each
([
'name'
,
'label'
],
function
(
propName
)
{
$
(
'.vector-prop-'
+
propName
+
' input'
,
element
).
prop
(
'disabled'
,
true
);
});
this
.
updateChecks
(
this
.
dragged_vector
);
$
(
'.checks input'
,
element
).
prop
(
'disabled'
,
false
);
}
}
}
...
...
@@ -536,7 +549,11 @@ function VectorDrawXBlockEdit(runtime, element, init_args) {
var
vectorObject
=
this
.
board
.
elementsByName
[
vectorName
];
this
.
updateVectorProperties
(
vectorObject
);
if
(
this
.
resultMode
)
{
_
.
each
([
'name'
,
'label'
],
function
(
propName
)
{
$
(
'.vector-prop-'
+
propName
+
' input'
,
element
).
prop
(
'disabled'
,
true
);
});
this
.
updateChecks
(
vectorObject
);
$
(
'.checks input'
,
element
).
prop
(
'disabled'
,
false
);
}
};
...
...
@@ -544,30 +561,32 @@ function VectorDrawXBlockEdit(runtime, element, init_args) {
if
(
!
this
.
wasUsed
)
{
this
.
wasUsed
=
true
;
}
// About to save changes, so hide message about pending changes
$
(
'.vector-prop-update .update-pending'
,
element
).
hide
();
// Get name of vector that is currently "selected"
var
vectorName
=
""
+
$
(
'.element-list-edit'
,
element
).
find
(
'option:selected'
).
data
(
'vector-name'
);
var
vectorName
=
String
(
$
(
'.element-list-edit'
,
element
).
find
(
'option:selected'
).
data
(
'vector-name'
)),
editableProperties
=
[
'name'
,
'label'
,
'tail'
,
'length'
,
'angle'
],
newValues
=
{};
// Get values from input fields
var
newName
=
$
(
'.vector-prop-name input'
,
element
).
val
(),
newLabel
=
$
(
'.vector-prop-label input'
,
element
).
val
(),
newTail
=
$
(
'.vector-prop-tail input'
,
element
).
val
(),
newLength
=
$
(
'.vector-prop-length input'
,
element
).
val
(),
newAngle
=
$
(
'.vector-prop-angle input'
,
element
).
val
();
// Process values
newName
=
$
.
trim
(
newName
);
newLabel
=
$
.
trim
(
newLabel
);
newTail
=
_
.
map
(
newTail
.
split
(
/ *, */
),
function
(
coord
)
{
return
parseFloat
(
coord
);
_
.
each
(
editableProperties
,
function
(
prop
)
{
newValues
[
prop
]
=
$
.
trim
(
$
(
'.vector-prop-'
+
prop
+
' input'
,
element
).
val
());
});
newLength
=
parseFloat
(
newLength
);
newAngle
=
parseFloat
(
newAngle
);
// Process values
var
newName
=
newValues
.
name
,
newLabel
=
newValues
.
label
,
newTail
=
_
.
map
(
newValues
.
tail
.
split
(
/ *, */
),
function
(
coord
)
{
return
parseFloat
(
coord
);
}),
newLength
=
parseFloat
(
newValues
.
length
),
newAngle
=
parseFloat
(
newValues
.
angle
);
// Validate and update values
var
vector
Settings
=
this
.
getVectorSettingsByName
(
vectorName
),
editOption
=
$
(
'.menu .element-list-edit option[data-vector-name="'
+
vectorName
+
'"]'
,
element
),
var
vector
Names
=
this
.
getVectorNames
(
),
vectorSettings
=
this
.
getVectorSettingsByName
(
vectorName
),
boardObject
=
this
.
board
.
elementsByName
[
vectorName
];
if
(
newName
&&
newName
!==
vectorName
)
{
// 1. Update name
if
(
newName
&&
newName
!==
vectorName
&&
!
_
.
contains
(
vectorNames
,
newName
))
{
// Update vector settings
vectorSettings
.
name
=
newName
;
// Update dropdown for selecting vector to edit
var
editOption
=
$
(
'.menu .element-list-edit option[data-vector-name="'
+
vectorName
+
'"]'
,
element
);
editOption
.
data
(
'vector-name'
,
newName
);
editOption
.
text
(
newName
);
// Update board
...
...
@@ -589,14 +608,21 @@ function VectorDrawXBlockEdit(runtime, element, init_args) {
expectedResults
[
newName
]
=
expectedResult
;
delete
expectedResults
[
vectorName
];
}
}
else
{
$
(
'.vector-prop-name input'
,
element
).
val
(
vectorName
);
}
if
(
newLabel
&&
newLabel
!==
'-'
)
{
// 2. Update label
if
(
newLabel
)
{
vectorSettings
.
style
.
label
=
newLabel
;
boardObject
.
point2
.
name
=
newLabel
;
// Always prefer label for labeling vector on board
}
else
{
vectorSettings
.
style
.
label
=
null
;
boardObject
.
point2
.
name
=
newName
||
vectorName
;
// ... but fall back on name if label was removed
}
// 3. Update tail, length, angle
var
values
=
[
newTail
[
0
],
newTail
[
1
],
newLength
,
newAngle
];
if
(
!
_
.
some
(
values
,
Number
.
isNaN
))
{
$
(
'.vector-prop-update .update-error'
,
element
).
css
(
'visibility'
,
'hidden'
);
$
(
'.vector-prop-update .update-error'
,
element
).
hide
(
);
// Use coordinates of new tail, new length, new angle to calculate new position of tip
var
radians
=
newAngle
*
Math
.
PI
/
180
;
var
newTip
=
[
...
...
@@ -616,7 +642,7 @@ function VectorDrawXBlockEdit(runtime, element, init_args) {
this
.
saveChecks
(
vectorName
);
}
}
else
{
$
(
'.vector-prop-update .update-error'
,
element
).
css
(
'visibility'
,
'visible'
);
$
(
'.vector-prop-update .update-error'
,
element
).
show
(
);
}
};
...
...
@@ -665,29 +691,30 @@ function VectorDrawXBlockEdit(runtime, element, init_args) {
// Set up click handlers
$
(
'.save-button'
,
element
).
on
(
'click'
,
function
(
e
)
{
e
.
preventDefault
();
var
data
;
if
(
vectordraw
.
resultMode
)
{
// Author edited both initial state and result
data
=
{
vectors
:
vectordraw
.
settings
.
vectors
,
// Corresponds to state vectors were in
// when author switched to result mode
expected_result_positions
:
vectordraw
.
settings
.
expected_result_positions
,
expected_result
:
vectordraw
.
settings
.
expected_result
};
}
else
if
(
vectordraw
.
wasUsed
)
{
// Author edited initial state
var
state
=
vectordraw
.
getState
();
data
=
{
vectors
:
state
,
expected_result_positions
:
vectordraw
.
settings
.
expected_result_positions
,
expected_result
:
vectordraw
.
settings
.
expected_result
};
}
else
{
// Author did not use WYSIWYG editor
data
=
{};
var
data
=
{};
if
(
vectordraw
.
wasUsed
)
{
// If author edited both initial state and result,
// vectordraw.settings.vectors corresponds to state vectors were in
// when author switched to result mode
data
.
vectors
=
vectordraw
.
resultMode
?
vectordraw
.
settings
.
vectors
:
vectordraw
.
getState
();
data
.
expected_result_positions
=
vectordraw
.
settings
.
expected_result_positions
;
data
.
expected_result
=
vectordraw
.
settings
.
expected_result
;
}
fieldEditor
.
save
(
data
);
});
$
(
'.cancel-button'
,
element
).
on
(
'click'
,
function
(
e
)
{
e
.
preventDefault
();
fieldEditor
.
cancel
();
});
$
(
'.info-button'
,
element
).
on
(
'click'
,
function
(
e
)
{
e
.
preventDefault
();
$
(
'#wysiwyg-description'
,
element
).
toggle
();
});
$
(
'input'
,
element
).
on
(
'change'
,
function
(
e
)
{
$
(
'.update-error'
).
hide
();
$
(
'.update-pending'
).
show
();
});
}
vectordraw/templates/html/vectordraw.html
View file @
9e6e0011
...
...
@@ -74,13 +74,13 @@
<span
id=
"vector-prop-tail-label"
>
{% trans "tail position" %}:
</span>
<input
type=
"text"
value
=
"-"
aria-labelledby=
"vector-prop-tail-label"
>
<input
type=
"text"
disabled=
"disabled"
placeholder
=
"-"
aria-labelledby=
"vector-prop-tail-label"
>
</div>
<div
class=
"vector-prop vector-prop-length"
>
<span
id=
"vector-prop-length-label"
>
{% trans "length" %}:
</span>
<input
type=
"text"
value
=
"-"
aria-labelledby=
"vector-prop-length-label"
>
<input
type=
"text"
disabled=
"disabled"
placeholder
=
"-"
aria-labelledby=
"vector-prop-length-label"
>
</div>
</div>
<div
class=
"row"
>
...
...
@@ -88,13 +88,13 @@
<span
id=
"vector-prop-angle-label"
>
{% trans "angle" %}:
</span>
<input
type=
"text"
value
=
"-"
aria-labelledby=
"vector-prop-angle-label"
>
<input
type=
"text"
disabled=
"disabled"
placeholder
=
"-"
aria-labelledby=
"vector-prop-angle-label"
>
</div>
<div
class=
"vector-prop vector-prop-slope"
>
<span
id=
"vector-prop-slope-label"
>
{% trans "slope" %}:
</span>
<input
type=
"text"
value=
"-"
aria-labelledby=
"vector-prop-slope-label"
disabled=
"disabled
"
>
<input
type=
"text"
disabled=
"disabled"
placeholder=
"-"
aria-labelledby=
"vector-prop-slope-label
"
>
</div>
</div>
<div
class=
"row"
>
...
...
vectordraw/templates/html/vectordraw_edit.html
View file @
9e6e0011
...
...
@@ -64,48 +64,81 @@
<li>
<!-- WYSIWYG editor -->
<div
class=
"vectordraw_block vectordraw_edit_block"
>
<h2
aria-describedby=
"wysiwyg-description"
>
WYSIWYG Editor
</h2>
<h2
aria-describedby=
"wysiwyg-description"
>
WYSIWYG Editor
<button
class=
"info-button"
title=
"Info"
>
<span
class=
"info-label fa fa-question"
aria-hidden=
"true"
></span>
<span
class=
"sr"
>
{% trans "Toggle information about how to use WYSIWYG editor" %}
</span>
</button>
</h2>
<p
id=
"wysiwyg-description"
>
{% blocktrans %}
Instead of using the "Vectors" and "Expected result" fields above
to define or modify the set of working vectors and expected result for this exercise,
you can also use the board below.
<div
id=
"wysiwyg-description"
>
<p>
{% blocktrans %}
Instead of using the "Vectors" and "Expected result" fields above
to define or modify the set of working vectors and expected result for this exercise,
you can also use the board below.
{% endblocktrans %}
</p>
To add a vector, left-click the board where you want the vector to originate.
Keep holding down the left mouse button and drag your mouse pointer across the board
to achieve the desired length and angle for the vector.
Alternatively, you can click "Create vector", which will add a new vector
that starts at the center of the board and has a predefined length (3) and angle (90).
<p>
{% blocktrans %}
To add a vector, left-click the board where you want the vector to originate.
Keep holding down the left mouse button and drag your mouse pointer across the board
to achieve the desired length and angle for the vector.
Alternatively, you can click "Create vector", which will add a new vector
that starts at the center of the board and has a predefined length (3) and angle (90).
{% endblocktrans %}
</p>
To modify the position of an existing vector, left-click it, hold down the left mouse button,
and move your mouse pointer across the board. To modify length and/or angle,
left-click the tip of the vector and drag your mouse pointer across the board.
Alternatively, you can select an existing vector from the dropdown menu,
modify its tail position, length, and angle by changing the values
in the corresponding input fields, and click "Update" to update its position on the board.
You can also modify the name and label of a vector using this technique.
<p>
{% blocktrans %}
To modify the position of an existing vector, left-click it, hold down the left mouse button,
and move your mouse pointer across the board. To modify length and/or angle,
left-click the tip of the vector and drag your mouse pointer across the board.
Alternatively, you can select an existing vector from the dropdown menu,
modify its tail position, length, and angle by changing the values
in the corresponding input fields, and click "Update" to update its position on the board.
You can also modify the name and label of a vector using this technique.
{% endblocktrans %}
</p>
To remove an existing vector, left-click it or select it from the dropdown menu,
then click "Remove".
<p>
{% blocktrans %}
To remove an existing vector, left-click it or select it from the dropdown menu,
then click "Remove".
{% endblocktrans %}
</p>
When you are done defining the set of working vectors, click "Edit result"
to switch the editor to a mode that will allow you to define the expected result for this exercise.
In this mode you can operate on vectors as described above but you can not add or remove vectors,
and you may not change the name and label of a selected vector.
<p>
{% blocktrans %}
When you are done defining the set of working vectors, click "Edit result"
to switch the editor to a mode that will allow you to define the expected result for this exercise.
In this mode you can operate on vectors as described above but you can not add or remove vectors,
and you may not change the name and label of a selected vector.
{% endblocktrans %}
</p>
To define the expected result for the exercise, place each vector where it would be located
in a correct solution. When a vector is selected, use the menu to the right of the board
to select the checks that you would like the grader to perform for this vector,
and click "Update". Note that if you do not select any checks for a given vector,
no checks at all will be performed for it during grading (i.e., the grader will skip a presence check).
<p>
{% blocktrans %}
To define the expected result for the exercise, place each vector where it would be located
in a correct solution. When a vector is selected and positioned correctly,
use the menu to the right of the board to select the checks that you would like the grader
to perform for this vector, then click "Update" to save expected position and associated checks
for the vector. Note that if you do not select any checks for a given vector,
no checks at all will be performed for it during grading (i.e., the grader will skip a presence check).
{% endblocktrans %}
</p>
Finally, note that if you make changes using the board below, any changes you made
via the "Vectors" and "Expected results" fields above will be overwritten
when you save the settings for this exercise by clicking the "Save" button
at the bottom of this dialog.
{% endblocktrans %}
</p>
<p>
{% blocktrans %}
Finally, note that if you make changes using the board below, any changes you made
via the "Vectors" and "Expected results" fields above will be overwritten
when you save the settings for this exercise by clicking the "Save" button
at the bottom of this dialog.
{% endblocktrans %}
</p>
</div>
<div
id=
"vectordraw"
>
<div
class=
"menu"
style=
"width: {{ self.width }}px;"
>
...
...
@@ -134,7 +167,7 @@
<span
id=
"vector-prop-name-label"
>
{% trans "name" %}:
</span>
<input
type=
"text"
value
=
"-"
aria-labelledby=
"vector-prop-name-label"
>
<input
type=
"text"
disabled=
"disabled"
placeholder
=
"-"
aria-labelledby=
"vector-prop-name-label"
>
</div>
</div>
<div
class=
"row"
>
...
...
@@ -142,13 +175,13 @@
<span
id=
"vector-prop-label-label"
>
{% trans "label" %}:
</span>
<input
type=
"text"
value
=
"-"
aria-labelledby=
"vector-prop-label-label"
>
<input
type=
"text"
disabled=
"disabled"
placeholder
=
"-"
aria-labelledby=
"vector-prop-label-label"
>
</div>
<div
class=
"vector-prop vector-prop-tail"
>
<span
id=
"vector-prop-tail-label"
>
{% trans "tail position" %}:
</span>
<input
type=
"text"
value
=
"-"
aria-labelledby=
"vector-prop-tail-label"
>
<input
type=
"text"
disabled=
"disabled"
placeholder
=
"-"
aria-labelledby=
"vector-prop-tail-label"
>
</div>
</div>
<div
class=
"row"
>
...
...
@@ -156,13 +189,13 @@
<span
id=
"vector-prop-length-label"
>
{% trans "length" %}:
</span>
<input
type=
"text"
value
=
"-"
aria-labelledby=
"vector-prop-length-label"
>
<input
type=
"text"
disabled=
"disabled"
placeholder
=
"-"
aria-labelledby=
"vector-prop-length-label"
>
</div>
<div
class=
"vector-prop vector-prop-angle"
>
<span
id=
"vector-prop-angle-label"
>
{% trans "angle" %}:
</span>
<input
type=
"text"
value
=
"-"
aria-labelledby=
"vector-prop-angle-label"
>
<input
type=
"text"
disabled=
"disabled"
placeholder
=
"-"
aria-labelledby=
"vector-prop-angle-label"
>
</div>
</div>
<div
class=
"row"
>
...
...
@@ -171,6 +204,9 @@
<span
class=
"update-label"
aria-hidden=
"true"
>
{% trans "Update" %}
</span>
<span
class=
"sr"
>
{% trans "Update properties of selected element" %}
</span>
</button>
<span
class=
"update-pending"
>
{% trans "Pending changes." %}
</span>
<span
class=
"update-error"
>
{% trans "Invalid input." %}
</span>
</div>
<div
class=
"vector-prop vector-remove"
>
...
...
@@ -194,13 +230,13 @@
<span
id=
"tail-check-label"
>
{% trans "check tail" %}:
</span>
<input
type=
"checkbox"
aria-labelledby=
"tail-check-label"
>
<input
type=
"checkbox"
disabled=
"disabled"
aria-labelledby=
"tail-check-label"
>
</div>
<div
class=
"row"
>
<span
id=
"tail-tolerance-label"
>
{% trans "tolerance" %}:
</span>
<input
type=
"
text"
value=
"1.0
"
aria-labelledby=
"tail-tolerance-label"
>
<input
type=
"
number"
disabled=
"disabled"
min=
"0"
step=
"0.1"
placeholder=
"-
"
aria-labelledby=
"tail-tolerance-label"
>
</div>
</div>
<div
class=
"check"
id=
"check-tip"
>
...
...
@@ -208,13 +244,13 @@
<span
id=
"tip-check-label"
>
{% trans "check tip" %}:
</span>
<input
type=
"checkbox
"
aria-labelledby=
"tip-check-label"
>
<input
type=
"checkbox"
disabled=
"disabled
"
aria-labelledby=
"tip-check-label"
>
</div>
<div
class=
"row"
>
<span
id=
"tip-tolerance-label"
>
{% trans "tolerance" %}:
</span>
<input
type=
"
text"
value=
"1.0
"
aria-labelledby=
"tip-tolerance-label"
>
<input
type=
"
number"
disabled=
"disabled"
min=
"0"
step=
"0.1"
placeholder=
"-
"
aria-labelledby=
"tip-tolerance-label"
>
</div>
</div>
<div
class=
"check"
id=
"check-tail_x"
>
...
...
@@ -222,13 +258,13 @@
<span
id=
"tail-x-check-label"
>
{% trans "check tail(x)" %}:
</span>
<input
type=
"checkbox"
aria-labelledby=
"tail-x-check-label"
>
<input
type=
"checkbox"
disabled=
"disabled"
aria-labelledby=
"tail-x-check-label"
>
</div>
<div
class=
"row"
>
<span
id=
"tail-x-tolerance-label"
>
{% trans "tolerance" %}:
</span>
<input
type=
"
text"
value=
"1.0
"
aria-labelledby=
"tail-x-tolerance-label"
>
<input
type=
"
number"
disabled=
"disabled"
min=
"0"
step=
"0.1"
placeholder=
"-
"
aria-labelledby=
"tail-x-tolerance-label"
>
</div>
</div>
<div
class=
"check"
id=
"check-tail_y"
>
...
...
@@ -236,13 +272,13 @@
<span
id=
"tail-y-check-label"
>
{% trans "check tail(y)" %}:
</span>
<input
type=
"checkbox"
aria-labelledby=
"tail-y-check-label"
>
<input
type=
"checkbox"
disabled=
"disabled"
aria-labelledby=
"tail-y-check-label"
>
</div>
<div
class=
"row"
>
<span
id=
"tail-y-tolerance-label"
>
{% trans "tolerance" %}:
</span>
<input
type=
"
text"
value=
"1.0
"
aria-labelledby=
"tail-y-tolerance-label"
>
<input
type=
"
number"
disabled=
"disabled"
min=
"0"
step=
"0.1"
placeholder=
"-
"
aria-labelledby=
"tail-y-tolerance-label"
>
</div>
</div>
<div
class=
"check"
id=
"check-tip_x"
>
...
...
@@ -250,13 +286,13 @@
<span
id=
"tip-x-check-label"
>
{% trans "check tip(x)" %}:
</span>
<input
type=
"checkbox"
aria-labelledby=
"tip-x-check-label"
>
<input
type=
"checkbox"
disabled=
"disabled"
aria-labelledby=
"tip-x-check-label"
>
</div>
<div
class=
"row"
>
<span
id=
"tip-x-tolerance-label"
>
{% trans "tolerance" %}:
</span>
<input
type=
"
text"
value=
"1.0
"
aria-labelledby=
"tip-x-tolerance-label"
>
<input
type=
"
number"
disabled=
"disabled"
min=
"0"
step=
"0.1"
placeholder=
"-
"
aria-labelledby=
"tip-x-tolerance-label"
>
</div>
</div>
<div
class=
"check"
id=
"check-tip_y"
>
...
...
@@ -264,13 +300,13 @@
<span
id=
"tip-y-check-label"
>
{% trans "check tip(y)" %}:
</span>
<input
type=
"checkbox"
aria-labelledby=
"tip-y-check-label"
>
<input
type=
"checkbox"
disabled=
"disabled"
aria-labelledby=
"tip-y-check-label"
>
</div>
<div
class=
"row"
>
<span
id=
"tip-y-tolerance-label"
>
{% trans "tolerance" %}:
</span>
<input
type=
"
text"
value=
"1.0
"
aria-labelledby=
"tip-y-tolerance-label"
>
<input
type=
"
number"
disabled=
"disabled"
min=
"0"
step=
"0.1"
placeholder=
"-
"
aria-labelledby=
"tip-y-tolerance-label"
>
</div>
</div>
<div
class=
"check"
id=
"check-coords"
>
...
...
@@ -278,13 +314,13 @@
<span
id=
"coords-check-label"
>
{% trans "check coords" %}:
</span>
<input
type=
"checkbox"
aria-labelledby=
"coords-check-label"
>
<input
type=
"checkbox"
disabled=
"disabled"
aria-labelledby=
"coords-check-label"
>
</div>
<div
class=
"row"
>
<span
id=
"coords-tolerance-label"
>
{% trans "tolerance" %}:
</span>
<input
type=
"
text"
value=
"1.0
"
aria-labelledby=
"coords-tolerance-label"
>
<input
type=
"
number"
disabled=
"disabled"
min=
"0"
step=
"0.1"
placeholder=
"-
"
aria-labelledby=
"coords-tolerance-label"
>
</div>
</div>
<div
class=
"check"
id=
"check-length"
>
...
...
@@ -292,13 +328,13 @@
<span
id=
"length-check-label"
>
{% trans "check length" %}:
</span>
<input
type=
"checkbox"
aria-labelledby=
"length-check-label"
>
<input
type=
"checkbox"
disabled=
"disabled"
aria-labelledby=
"length-check-label"
>
</div>
<div
class=
"row"
>
<span
id=
"length-tolerance-label"
>
{% trans "tolerance" %}:
</span>
<input
type=
"
text"
value=
"1.0
"
aria-labelledby=
"length-tolerance-label"
>
<input
type=
"
number"
disabled=
"disabled"
min=
"0"
step=
"0.1"
placeholder=
"-
"
aria-labelledby=
"length-tolerance-label"
>
</div>
</div>
<div
class=
"check"
id=
"check-angle"
>
...
...
@@ -306,13 +342,13 @@
<span
id=
"angle-check-label"
>
{% trans "check angle" %}:
</span>
<input
type=
"checkbox"
aria-labelledby=
"angle-check-label"
>
<input
type=
"checkbox"
disabled=
"disabled"
aria-labelledby=
"angle-check-label"
>
</div>
<div
class=
"row"
>
<span
id=
"angle-tolerance-label"
>
{% trans "tolerance" %}:
</span>
<input
type=
"
text"
value=
"2.0
"
aria-labelledby=
"angle-tolerance-label"
>
<input
type=
"
number"
disabled=
"disabled"
min=
"0"
step=
"0.1"
placeholder=
"-
"
aria-labelledby=
"angle-tolerance-label"
>
</div>
</div>
</div>
...
...
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