我使用Shiny GUI R包。我正在寻找一种在按下actionButton后显示“loading ...”等消息的方法。该函数需要几分钟才能执行,因此我需要以某种方式通知用户按钮实际触发了某个事件。现在server.R代码如下所示:
DATA <- reactive({
if(input$DownloadButton>0) {
RunDownload()
} else {
NULL
}
})
output$Download <- renderText({
if(NROW(DATA())>0) {
paste0(Sys.time(),": ",NROW(DATA()), " items downloaded")
} else {
''
}
})
actionButton()
是一个从互联网下载数据的功能。 input$DownloadButton
是actionButton。因此,在按下按钮后,用户等待几分钟,然后才会看到一条消息,表明下载成功。我想在按下actionButton之后显示消息“正在加载...”,然后在执行结束时显示另一条消息,如paste0(Sys.time(),": ",NROW(DATA()), " items downloaded")
。
答案 0 :(得分:32)
我已经使用了比之前发布的更简单,更可靠的方式。
的组合
tags$style(type="text/css", "
#loadmessage {
position: fixed;
top: 0px;
left: 0px;
width: 100%;
padding: 5px 0px 5px 0px;
text-align: center;
font-weight: bold;
font-size: 100%;
color: #000000;
background-color: #CCFF66;
z-index: 105;
}
")
与
conditionalPanel(condition="$('html').hasClass('shiny-busy')",
tags$div("Loading...",id="loadmessage")
)
示例:
runApp(list(
ui = pageWithSidebar(
headerPanel("Test"),
sidebarPanel(
tags$head(tags$style(type="text/css", "
#loadmessage {
position: fixed;
top: 0px;
left: 0px;
width: 100%;
padding: 5px 0px 5px 0px;
text-align: center;
font-weight: bold;
font-size: 100%;
color: #000000;
background-color: #CCFF66;
z-index: 105;
}
")),
numericInput('n', 'Number of obs', 100),
conditionalPanel(condition="$('html').hasClass('shiny-busy')",
tags$div("Loading...",id="loadmessage"))
),
mainPanel(plotOutput('plot'))
),
server = function(input, output) {
output$plot <- renderPlot({ Sys.sleep(2); hist(runif(input$n)) })
}
))
标签$ head()不是必需的,但将所有样式保留在head标签内是一种很好的做法。
答案 1 :(得分:4)
我通过将以下代码添加到sidebarPanel()来解决了这个问题:
HTML('<script type="text/javascript">
$(document).ready(function() {
$("#DownloadButton").click(function() {
$("#Download").text("Loading...");
});
});
</script>
')
答案 2 :(得分:4)
非常简单,您可以在函数的开头showModal()
和结尾的removeModal()
使用内置的闪亮函数。如果您删除页脚,则无法从中点击该模式。
示例:
observeEvent(input$button, {
showModal(modalDialog("Doing a function", footer=NULL))
#Do the stuff here....
#...
#...
#Finish the function
removeModal()
})
答案 3 :(得分:3)
您可以使用ShinyJS:https://github.com/daattali/shinyjs
按下actionButton后,您可以轻松切换显示&#34; loading ...&#34;的文本组件,当计算完成后,您可以将此组件切换为隐藏。
答案 4 :(得分:2)
我找到了一个解决方案,对我来说很好。我正在使用Bootstrap模式。它会在函数执行开始时显示,并在结束时再次隐藏。
modalBusy&lt; - function(id,title,...){
msgHandler = singleton(tags$head(tags$script('Shiny.addCustomMessageHandler("jsCode", function(message) { console.log(message) eval(message.code); });' ) ) ) label_id = paste(id, "label", sep='-') modal_tag <- div(id=id, class="modal hide fade", "aria-hidden"=FALSE, "aria-labelledby"=label_id, "role"="dialog", "tabindex"="-1", "data-keyboard"=FALSE, "data-backdrop"="static") header_tag <- div(class="modal-header", h3(id=label_id, title)) body_tag <- div(class="modal-body", Row(...)) footer_tag <- div(class="modal-footer") modal_tag <- tagAppendChildren(modal_tag, header_tag, body_tag, footer_tag) tagList(msgHandler, modal_tag) }
要显示和隐藏它,请使用功能
showModal <- function(id,session) {
session$sendCustomMessage(type="jsCode",
list(code= paste("$('#",id,"').modal('show')"
,sep="")))
}
hideModal <- function(id,session) {
session$sendCustomMessage(type="jsCode",
list(code= paste("$('#",id,"').modal('hide')"
,sep="")))
}
在函数调用之前调用showModal函数,之后调用hideModal函数!
希望这有帮助。
的Seb
答案 5 :(得分:1)
虽然这个问题很老了,但我认为它仍然相关。我提供了另一种解决方案,它在按钮上显示活动指示器,在按钮标签旁边开始一个漫长的过程。
我们需要一个在 span
中带有标签的操作按钮以及识别该标签的某种方式。
actionButton("btnUpdate", span("Update", id="UpdateAnimate", class=""))
我们还需要一些可以添加到按钮标签的 CSS 动画,例如像这样:
tags$head(tags$style(type="text/css", '
.loading {
display: inline-block;
overflow: hidden;
height: 1.3em;
margin-top: -0.3em;
line-height: 1.5em;
vertical-align: text-bottom;
box-sizing: border-box;
}
.loading.dots::after {
text-rendering: geometricPrecision;
content: "⠋\\A⠙\\A⠹\\A⠸\\A⠼\\A⠴\\A⠦\\A⠧\\A⠇\\A⠏";
animation: spin10 1s steps(10) infinite;
animation-duration: 1s;
animation-timing-function: steps(10);
animation-delay: 0s;
animation-iteration-count: infinite;
animation-direction: normal;
animation-fill-mode: none;
animation-play-state: running;
animation-name: spin10;
}
.loading::after {
display: inline-table;
white-space: pre;
text-align: left;
}
@keyframes spin10 { to { transform: translateY(-15.0em); } }
'))
现在我们可以使用 shinyjs
来操作 span
类,它动态地在按钮标签后面添加动画。我们在用户按下按钮时添加动画:
observeEvent(input$btnUpdate, { # User requests update
# ...
shinyjs::addClass(id = "UpdateAnimate", class = "loading dots")
shinyjs::disable("btnUpdate")
# ...
})
当操作完成后,我们可以从span中移除类并结束动画:
output$distPlot <- renderPlot({
# ...
Sys.sleep(1) # just for show, you probably want to remove it in a real app
# Button settings
shinyjs::enable("btnUpdate")
shinyjs::removeClass(id = "UpdateAnimate", class = "loading dots")
# ...
})