Use Custom `end`-Function to Provide Immediate Feedback using Knitr
feedback.Rmd
This example shows how to use the package
ShinyItemBuilder
to display a feedback after an
assessment.
library(ShinyItemBuilder)
For illustration purposes, three items from the demo01
included in the package ShinyItemBuilder
are used. After
calling getDemoPool("demo01")
the object
item_pool
contains information about all items, but we only
select item 2, 3 and 4:
item_pool <- getDemoPool("demo01")
item_pool <- item_pool[c(2,3,4),]
Project | Task | |
---|---|---|
2 | SinglePageItems_01SC.zip | task0 |
3 | SinglePageItems_02MC.zip | task0 |
4 | SinglePageItems_03TXT.zip | task0 |
To implement the booklet design, we overwrite the end function.
assessment_config <- getConfig(Verbose = T)
After calling getConfig()
, the object
assessment_config
already contains the (default)
implementation of the end
-function:
assessment_config$end
#> function (session)
#> {
#> showModal(modalDialog(title = "You Answered all Items", "Please close the browser / tab.",
#> footer = tagList(actionButton("endActionButtonOK", "Restart"))))
#> }
#> <bytecode: 0x55b51462fc88>
#> <environment: 0x55b51463ce48>
This function can be overwritten by assigning a new function
end = function(session)
with the same signature. In this
new function, we first load the data gathered for this session, stored
in the variable session$userData$cbasession
:
In the following lines we create a simple data.frame representation of the scoring results:
a <- NULL
for (d in 1:dim(data$ResultData)[1]){
s <- parse_ib_scoring(data$ResultData[d,"Resultdata"])
a <- rbind(a,cbind(Project=data$ResultData[d,"Project"],
Task=data$ResultData[d,"Task"],
Scope=data$ResultData[d,"Scope"],
s[s$Active,c("Name","ResultText")]))
}
This is followed by the markdown template that will be used to
generate the feedback. In this example the markdown is created within
the function, but it could also be stored in a separate
*.Rmd
file.
After writing the markdown template to file (see
write(template, ...)
), render it to html (see
rmarkdown::render(...)
), the generated content is loaded
from file as base64 encoded string (see
base64enc::dataURI(file = ...)
). Finally, the generated
html (as base64 encoded string) is displayed in a modal dialog:
showModal(modalDialog(
title = "Feedback",
footer = tagList(actionButton("endActionButtonOK", "Restart")),
renderUI({
tags$iframe(src=b64, height=400, width=550, frameBorder=0)
}),
), session)
Taking everything together, this is an custom
end
-function that provides immediate feedback about the
scores obtained in CBA ItemBuilder items:
assessment_config$end <- function(session) {
data <- runtime.data[[session$userData$cbasession]]
a <- NULL
for (d in 1:dim(data$ResultData)[1]){
s <- parse_ib_scoring(data$ResultData[d,"Resultdata"])
a <- rbind(a,cbind(Project=data$ResultData[d,"Project"],
Task=data$ResultData[d,"Task"],
Scope=data$ResultData[d,"Scope"],
s[s$Active,c("Name","ResultText")]))
}
template <- '---
output: html_document
---
### Your Results: A Score of `r sum(a$Name == "ScoreCorrect")`
```{r, echo=F}
knitr::kable(a)
```
'
write(template, file=paste0(session$userData$cbasession,".rmd"), append = FALSE)
tmpfile <- rmarkdown::render(paste0(session$userData$cbasession,".rmd"))
b64 <- base64enc::dataURI(file = tmpfile, mime = "text/html")
if (file.exists(tmpfile))
file.remove(tmpfile)
if (file.exists(paste0(session$userData$cbasession,".rmd")))
file.remove(paste0(session$userData$cbasession,".rmd"))
showModal(modalDialog(
title = "Feedback",
footer = tagList(actionButton("endActionButtonOK", "Restart")),
renderUI({
tags$iframe(src=b64, height=400, width=550, frameBorder=0)
}),
), session)
}
Note that the dialog includes the actionButton with the name
endActionButtonOK
(see
footer = tagList(actionButton("endActionButtonOK", "Restart"))
),
that restarts the assessment.