Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
M
moodle-qtype_stack
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
elc
moodle-qtype_stack
Commits
b3e68254
Commit
b3e68254
authored
1 year ago
by
Tim Hunt
Browse files
Options
Downloads
Patches
Plain Diff
Latest Moodle: deferred feedback behaviour: ensure check button hidden
Fixes issue #1046.
parent
006344ae
No related branches found
No related tags found
No related merge requests found
Changes
4
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
amd/build/input.min.js
+1
-1
1 addition, 1 deletion
amd/build/input.min.js
amd/build/input.min.js.map
+1
-1
1 addition, 1 deletion
amd/build/input.min.js.map
amd/src/input.js
+1
-1
1 addition, 1 deletion
amd/src/input.js
tests/behat/preview.feature
+30
-0
30 additions, 0 deletions
tests/behat/preview.feature
with
33 additions
and
3 deletions
amd/build/input.min.js
+
1
−
1
View file @
b3e68254
...
@@ -19,6 +19,6 @@
...
@@ -19,6 +19,6 @@
* @copyright 2018 The Open University
* @copyright 2018 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
*/
define
(
"
qtype_stack/input
"
,[
"
core/ajax
"
,
"
core/event
"
],(
function
(
Ajax
,
CustomEvents
){
function
StackInput
(
validationDiv
,
prefix
,
qaid
,
name
,
input
){
var
TYPING_DELAY
=
1
e3
,
delayTimeoutHandle
=
null
,
validationResults
=
{},
lastValidatedValue
=
getInputValue
();
function
cancelTypingDelay
(){
delayTimeoutHandle
&&
clearTimeout
(
delayTimeoutHandle
),
delayTimeoutHandle
=
null
}
function
valueChanging
(){
cancelTypingDelay
(),
showWaiting
(),
delayTimeoutHandle
=
setTimeout
(
valueChanged
,
TYPING_DELAY
),
setTimeout
((
function
(){
checkNoChange
()}),
0
)}
function
checkNoChange
(){
getInputValue
()
===
lastValidatedValue
&&
(
cancelTypingDelay
(),
validationDiv
.
classList
.
remove
(
"
waiting
"
))}
function
valueChanged
(){
cancelTypingDelay
(),
showValidationResults
()
||
validateInput
()}
function
validateInput
(){
Ajax
.
call
([{
methodname
:
"
qtype_stack_validate_input
"
,
args
:{
qaid
:
qaid
,
name
:
name
,
input
:
getInputValue
()},
done
:
function
(
response
){
validationReceived
(
response
)},
fail
:
function
(
response
){
showValidationFailure
(
response
)}}]),
showLoading
()}
function
getInputValue
(){
return
input
.
getValue
()}
function
validationReceived
(
response
){
"
invalid
"
!==
response
.
status
?(
validationResults
[
response
.
input
]
=
response
,
showValidationResults
()):
showValidationFailure
(
response
)}
function
extractScripts
(
html
,
scriptCommands
){
for
(
var
result
,
scriptregexp
=
/<script
[^
>
]
*>
([\s\S]
*
?)
<
\/
script>/g
;
null
!==
(
result
=
scriptregexp
.
exec
(
html
));)
scriptCommands
.
push
(
result
[
1
]);
return
html
.
replace
(
scriptregexp
,
""
)}
function
showValidationResults
(){
var
val
=
getInputValue
();
if
(
!
validationResults
[
val
])
return
showWaiting
(),
!
1
;
var
results
=
validationResults
[
val
];
lastValidatedValue
=
val
;
var
scriptCommands
=
[];
validationDiv
.
innerHTML
=
extractScripts
(
results
.
message
,
scriptCommands
);
for
(
var
i
=
0
;
i
<
scriptCommands
.
length
;
i
++
)
eval
(
scriptCommands
[
i
]);
return
removeAllClasses
(),
results
.
message
||
validationDiv
.
classList
.
add
(
"
empty
"
),
CustomEvents
.
notifyFilterContentUpdated
(
validationDiv
),
!
0
}
function
showValidationFailure
(
response
){
lastValidatedValue
=
""
,
validationDiv
.
innerHTML
=
response
.
message
,
removeAllClasses
(),
validationDiv
.
classList
.
add
(
"
error
"
),
CustomEvents
.
notifyFilterContentUpdated
(
validationDiv
)}
function
showLoading
(){
removeAllClasses
(),
validationDiv
.
classList
.
add
(
"
loading
"
)}
function
showWaiting
(){
removeAllClasses
(),
validationDiv
.
classList
.
add
(
"
waiting
"
)}
function
removeAllClasses
(){
validationDiv
.
classList
.
remove
(
"
empty
"
),
validationDiv
.
classList
.
remove
(
"
error
"
),
validationDiv
.
classList
.
remove
(
"
loading
"
),
validationDiv
.
classList
.
remove
(
"
waiting
"
)}
input
.
addEventHandlers
(
valueChanging
)}
function
StackSimpleInput
(
input
){
this
.
addEventHandlers
=
function
(
valueChanging
){
input
.
addEventListener
(
"
input
"
,
valueChanging
)},
this
.
getValue
=
function
(){
return
input
.
value
.
replace
(
/^
\s
+|
\s
+$/g
,
""
)}}
function
StackTextareaInput
(
textarea
){
this
.
addEventHandlers
=
function
(
valueChanging
){
textarea
.
addEventListener
(
"
input
"
,
valueChanging
)},
this
.
getValue
=
function
(){
return
textarea
.
value
.
replace
(
/^
\s
+|
\s
+$/g
,
""
).
split
(
/
\s
*
[\r\n]\s
*/
).
join
(
"
<br>
"
)}}
function
StackRadioInput
(
container
){
this
.
addEventHandlers
=
function
(
valueChanging
){
container
.
addEventListener
(
"
input
"
,
valueChanging
)},
this
.
getValue
=
function
(){
var
selected
=
container
.
querySelector
(
"
:checked
"
);
return
selected
?
selected
.
value
:
""
}}
function
StackCheckboxInput
(
container
){
this
.
addEventHandlers
=
function
(
valueChanging
){
container
.
addEventListener
(
"
input
"
,
valueChanging
)},
this
.
getValue
=
function
(){
for
(
var
selected
=
container
.
querySelectorAll
(
"
:checked
"
),
result
=
[],
i
=
0
;
i
<
selected
.
length
;
i
++
)
result
[
i
]
=
selected
[
i
].
value
;
return
result
.
length
>
0
?
result
.
join
(
"
,
"
):
""
}}
function
StackMatrixInput
(
idPrefix
,
container
){
var
numcol
=
0
,
numrow
=
0
;
container
.
querySelectorAll
(
"
input[type=text]
"
).
forEach
((
function
(
element
){
if
(
element
.
name
.
slice
(
0
,
idPrefix
.
length
+
5
)
===
idPrefix
+
"
_sub_
"
){
var
bits
=
element
.
name
.
substring
(
idPrefix
.
length
+
5
).
split
(
"
_
"
);
numrow
=
Math
.
max
(
numrow
,
parseInt
(
bits
[
0
],
10
)
+
1
),
numcol
=
Math
.
max
(
numcol
,
parseInt
(
bits
[
1
],
10
)
+
1
)}})),
this
.
addEventHandlers
=
function
(
valueChanging
){
container
.
addEventListener
(
"
input
"
,
valueChanging
)},
this
.
getValue
=
function
(){
for
(
var
values
=
new
Array
(
numrow
),
i
=
0
;
i
<
numrow
;
i
++
)
values
[
i
]
=
new
Array
(
numcol
);
return
container
.
querySelectorAll
(
"
input[type=text]
"
).
forEach
((
function
(
element
){
if
(
element
.
name
.
slice
(
0
,
idPrefix
.
length
+
5
)
===
idPrefix
+
"
_sub_
"
){
var
bits
=
element
.
name
.
substring
(
idPrefix
.
length
+
5
).
split
(
"
_
"
);
values
[
bits
[
0
]][
bits
[
1
]]
=
element
.
value
.
replace
(
/^
\s
+|
\s
+$/g
,
""
)}})),
"
matrix([
"
+
values
.
join
(
"
],[
"
)
+
"
])
"
}}
function
initInputs
(
questionDivId
,
prefix
,
qaid
,
inputs
){
for
(
var
questionDiv
=
document
.
getElementById
(
questionDivId
),
allok
=!
0
,
i
=
0
;
i
<
inputs
.
length
;
i
++
)
allok
=
initInput
(
questionDiv
,
prefix
,
qaid
,
inputs
[
i
])
&&
allok
;
allok
&&
(
questionDiv
.
classList
.
contains
(
"
dfexplicitvaildate
"
)
||
questionDiv
.
classList
.
contains
(
"
dfcbmexplicitvaildate
"
))
&&
(
questionDiv
.
querySelector
(
"
.im-controls input.submit
"
).
hidden
=!
0
)}
function
initInput
(
questionDiv
,
prefix
,
qaid
,
name
){
var
validationDiv
=
document
.
getElementById
(
prefix
+
name
+
"
_val
"
);
if
(
!
validationDiv
)
return
!
1
;
var
inputTypeHandler
=
getInputTypeHandler
(
questionDiv
,
prefix
,
name
);
return
!!
inputTypeHandler
&&
(
new
StackInput
(
validationDiv
,
prefix
,
qaid
,
name
,
inputTypeHandler
),
!
0
)}
function
getInputTypeHandler
(
questionDiv
,
prefix
,
name
){
var
input
=
questionDiv
.
querySelector
(
'
[name="
'
+
prefix
+
name
+
'
"]
'
);
if
(
input
)
return
"
TEXTAREA
"
===
input
.
nodeName
?
new
StackTextareaInput
(
input
):
"
radio
"
===
input
.
type
?
new
StackRadioInput
(
input
.
closest
(
"
.answer
"
)):
new
StackSimpleInput
(
input
);
if
((
input
=
questionDiv
.
querySelector
(
'
[name="
'
+
prefix
+
name
+
'
_1"]
'
))
&&
"
checkbox
"
===
input
.
type
)
return
new
StackCheckboxInput
(
input
.
closest
(
"
.answer
"
));
var
matrix
=
document
.
getElementById
(
prefix
+
name
+
"
_container
"
);
return
matrix
?
new
StackMatrixInput
(
prefix
+
name
,
matrix
):
null
}
return
{
initInputs
:
initInputs
}}));
define
(
"
qtype_stack/input
"
,[
"
core/ajax
"
,
"
core/event
"
],(
function
(
Ajax
,
CustomEvents
){
function
StackInput
(
validationDiv
,
prefix
,
qaid
,
name
,
input
){
var
TYPING_DELAY
=
1
e3
,
delayTimeoutHandle
=
null
,
validationResults
=
{},
lastValidatedValue
=
getInputValue
();
function
cancelTypingDelay
(){
delayTimeoutHandle
&&
clearTimeout
(
delayTimeoutHandle
),
delayTimeoutHandle
=
null
}
function
valueChanging
(){
cancelTypingDelay
(),
showWaiting
(),
delayTimeoutHandle
=
setTimeout
(
valueChanged
,
TYPING_DELAY
),
setTimeout
((
function
(){
checkNoChange
()}),
0
)}
function
checkNoChange
(){
getInputValue
()
===
lastValidatedValue
&&
(
cancelTypingDelay
(),
validationDiv
.
classList
.
remove
(
"
waiting
"
))}
function
valueChanged
(){
cancelTypingDelay
(),
showValidationResults
()
||
validateInput
()}
function
validateInput
(){
Ajax
.
call
([{
methodname
:
"
qtype_stack_validate_input
"
,
args
:{
qaid
:
qaid
,
name
:
name
,
input
:
getInputValue
()},
done
:
function
(
response
){
validationReceived
(
response
)},
fail
:
function
(
response
){
showValidationFailure
(
response
)}}]),
showLoading
()}
function
getInputValue
(){
return
input
.
getValue
()}
function
validationReceived
(
response
){
"
invalid
"
!==
response
.
status
?(
validationResults
[
response
.
input
]
=
response
,
showValidationResults
()):
showValidationFailure
(
response
)}
function
extractScripts
(
html
,
scriptCommands
){
for
(
var
result
,
scriptregexp
=
/<script
[^
>
]
*>
([\s\S]
*
?)
<
\/
script>/g
;
null
!==
(
result
=
scriptregexp
.
exec
(
html
));)
scriptCommands
.
push
(
result
[
1
]);
return
html
.
replace
(
scriptregexp
,
""
)}
function
showValidationResults
(){
var
val
=
getInputValue
();
if
(
!
validationResults
[
val
])
return
showWaiting
(),
!
1
;
var
results
=
validationResults
[
val
];
lastValidatedValue
=
val
;
var
scriptCommands
=
[];
validationDiv
.
innerHTML
=
extractScripts
(
results
.
message
,
scriptCommands
);
for
(
var
i
=
0
;
i
<
scriptCommands
.
length
;
i
++
)
eval
(
scriptCommands
[
i
]);
return
removeAllClasses
(),
results
.
message
||
validationDiv
.
classList
.
add
(
"
empty
"
),
CustomEvents
.
notifyFilterContentUpdated
(
validationDiv
),
!
0
}
function
showValidationFailure
(
response
){
lastValidatedValue
=
""
,
validationDiv
.
innerHTML
=
response
.
message
,
removeAllClasses
(),
validationDiv
.
classList
.
add
(
"
error
"
),
CustomEvents
.
notifyFilterContentUpdated
(
validationDiv
)}
function
showLoading
(){
removeAllClasses
(),
validationDiv
.
classList
.
add
(
"
loading
"
)}
function
showWaiting
(){
removeAllClasses
(),
validationDiv
.
classList
.
add
(
"
waiting
"
)}
function
removeAllClasses
(){
validationDiv
.
classList
.
remove
(
"
empty
"
),
validationDiv
.
classList
.
remove
(
"
error
"
),
validationDiv
.
classList
.
remove
(
"
loading
"
),
validationDiv
.
classList
.
remove
(
"
waiting
"
)}
input
.
addEventHandlers
(
valueChanging
)}
function
StackSimpleInput
(
input
){
this
.
addEventHandlers
=
function
(
valueChanging
){
input
.
addEventListener
(
"
input
"
,
valueChanging
)},
this
.
getValue
=
function
(){
return
input
.
value
.
replace
(
/^
\s
+|
\s
+$/g
,
""
)}}
function
StackTextareaInput
(
textarea
){
this
.
addEventHandlers
=
function
(
valueChanging
){
textarea
.
addEventListener
(
"
input
"
,
valueChanging
)},
this
.
getValue
=
function
(){
return
textarea
.
value
.
replace
(
/^
\s
+|
\s
+$/g
,
""
).
split
(
/
\s
*
[\r\n]\s
*/
).
join
(
"
<br>
"
)}}
function
StackRadioInput
(
container
){
this
.
addEventHandlers
=
function
(
valueChanging
){
container
.
addEventListener
(
"
input
"
,
valueChanging
)},
this
.
getValue
=
function
(){
var
selected
=
container
.
querySelector
(
"
:checked
"
);
return
selected
?
selected
.
value
:
""
}}
function
StackCheckboxInput
(
container
){
this
.
addEventHandlers
=
function
(
valueChanging
){
container
.
addEventListener
(
"
input
"
,
valueChanging
)},
this
.
getValue
=
function
(){
for
(
var
selected
=
container
.
querySelectorAll
(
"
:checked
"
),
result
=
[],
i
=
0
;
i
<
selected
.
length
;
i
++
)
result
[
i
]
=
selected
[
i
].
value
;
return
result
.
length
>
0
?
result
.
join
(
"
,
"
):
""
}}
function
StackMatrixInput
(
idPrefix
,
container
){
var
numcol
=
0
,
numrow
=
0
;
container
.
querySelectorAll
(
"
input[type=text]
"
).
forEach
((
function
(
element
){
if
(
element
.
name
.
slice
(
0
,
idPrefix
.
length
+
5
)
===
idPrefix
+
"
_sub_
"
){
var
bits
=
element
.
name
.
substring
(
idPrefix
.
length
+
5
).
split
(
"
_
"
);
numrow
=
Math
.
max
(
numrow
,
parseInt
(
bits
[
0
],
10
)
+
1
),
numcol
=
Math
.
max
(
numcol
,
parseInt
(
bits
[
1
],
10
)
+
1
)}})),
this
.
addEventHandlers
=
function
(
valueChanging
){
container
.
addEventListener
(
"
input
"
,
valueChanging
)},
this
.
getValue
=
function
(){
for
(
var
values
=
new
Array
(
numrow
),
i
=
0
;
i
<
numrow
;
i
++
)
values
[
i
]
=
new
Array
(
numcol
);
return
container
.
querySelectorAll
(
"
input[type=text]
"
).
forEach
((
function
(
element
){
if
(
element
.
name
.
slice
(
0
,
idPrefix
.
length
+
5
)
===
idPrefix
+
"
_sub_
"
){
var
bits
=
element
.
name
.
substring
(
idPrefix
.
length
+
5
).
split
(
"
_
"
);
values
[
bits
[
0
]][
bits
[
1
]]
=
element
.
value
.
replace
(
/^
\s
+|
\s
+$/g
,
""
)}})),
"
matrix([
"
+
values
.
join
(
"
],[
"
)
+
"
])
"
}}
function
initInputs
(
questionDivId
,
prefix
,
qaid
,
inputs
){
for
(
var
questionDiv
=
document
.
getElementById
(
questionDivId
),
allok
=!
0
,
i
=
0
;
i
<
inputs
.
length
;
i
++
)
allok
=
initInput
(
questionDiv
,
prefix
,
qaid
,
inputs
[
i
])
&&
allok
;
allok
&&
(
questionDiv
.
classList
.
contains
(
"
dfexplicitvaildate
"
)
||
questionDiv
.
classList
.
contains
(
"
dfcbmexplicitvaildate
"
))
&&
(
questionDiv
.
querySelector
(
"
.im-controls input.submit
, .im-controls button.submit
"
).
hidden
=!
0
)}
function
initInput
(
questionDiv
,
prefix
,
qaid
,
name
){
var
validationDiv
=
document
.
getElementById
(
prefix
+
name
+
"
_val
"
);
if
(
!
validationDiv
)
return
!
1
;
var
inputTypeHandler
=
getInputTypeHandler
(
questionDiv
,
prefix
,
name
);
return
!!
inputTypeHandler
&&
(
new
StackInput
(
validationDiv
,
prefix
,
qaid
,
name
,
inputTypeHandler
),
!
0
)}
function
getInputTypeHandler
(
questionDiv
,
prefix
,
name
){
var
input
=
questionDiv
.
querySelector
(
'
[name="
'
+
prefix
+
name
+
'
"]
'
);
if
(
input
)
return
"
TEXTAREA
"
===
input
.
nodeName
?
new
StackTextareaInput
(
input
):
"
radio
"
===
input
.
type
?
new
StackRadioInput
(
input
.
closest
(
"
.answer
"
)):
new
StackSimpleInput
(
input
);
if
((
input
=
questionDiv
.
querySelector
(
'
[name="
'
+
prefix
+
name
+
'
_1"]
'
))
&&
"
checkbox
"
===
input
.
type
)
return
new
StackCheckboxInput
(
input
.
closest
(
"
.answer
"
));
var
matrix
=
document
.
getElementById
(
prefix
+
name
+
"
_container
"
);
return
matrix
?
new
StackMatrixInput
(
prefix
+
name
,
matrix
):
null
}
return
{
initInputs
:
initInputs
}}));
//# sourceMappingURL=input.min.js.map
//# sourceMappingURL=input.min.js.map
\ No newline at end of file
This diff is collapsed.
Click to expand it.
amd/build/input.min.js.map
+
1
−
1
View file @
b3e68254
This diff is collapsed.
Click to expand it.
amd/src/input.js
+
1
−
1
View file @
b3e68254
...
@@ -440,7 +440,7 @@ define([
...
@@ -440,7 +440,7 @@ define([
// With JS With instant validation, we don't need the Check button, so hide it.
// With JS With instant validation, we don't need the Check button, so hide it.
if
(
allok
&&
(
questionDiv
.
classList
.
contains
(
'
dfexplicitvaildate
'
)
||
if
(
allok
&&
(
questionDiv
.
classList
.
contains
(
'
dfexplicitvaildate
'
)
||
questionDiv
.
classList
.
contains
(
'
dfcbmexplicitvaildate
'
)))
{
questionDiv
.
classList
.
contains
(
'
dfcbmexplicitvaildate
'
)))
{
questionDiv
.
querySelector
(
'
.im-controls input.submit
'
).
hidden
=
true
;
questionDiv
.
querySelector
(
'
.im-controls input.submit
, .im-controls button.submit
'
).
hidden
=
true
;
}
}
}
}
...
...
This diff is collapsed.
Click to expand it.
tests/behat/preview.feature
0 → 100644
+
30
−
0
View file @
b3e68254
@qtype
@qtype_oumatrix
Feature
:
Test how STACK questions work using Preview in the qeustoin bank
As a teacher
In order to check my STACK questions will work for students
I need to preview them
Background
:
Given
I set up STACK using the PHPUnit configuration
And the following "users" exist
:
|
username
|
|
teacher
|
And the following "courses" exist
:
|
fullname
|
shortname
|
category
|
|
Course
1
|
C1
|
0
|
And the following "course enrolments" exist
:
|
user
|
course
|
role
|
|
teacher
|
C1
|
editingteacher
|
And the following "question categories" exist
:
|
contextlevel
|
reference
|
name
|
|
Course
|
C1
|
Test
questions
|
And the following "questions" exist
:
|
questioncategory
|
qtype
|
name
|
template
|
|
Test
questions
|
stack
|
Simple
STACK
question
|
test1
|
@javascript
Scenario
:
Check button should be hidden with deferred feedback.
When
I am on the
"Simple STACK question"
"core_question > preview"
page logged in as teacher
Then
I should see
"Find"
And
I should see
"Not yet answered"
And
"check"
"button"
should not be visible
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment