Mar*_*uss 4 r input dynamic shiny
我混合了动态创建的输入和通常定义的输入。动态创建的输入的行为就像一个大型垂直堆叠块,其他输入围绕其流动。我怎样才能让它们全部流动在一起?
这重现了这个问题:
library(shinydashboard)
shinyApp(
ui = dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody(
flowLayout(
uiOutput('input_fields'),
textInput('fielda','Field A',''),
textInput('fieldb','Field B',''),
textInput('fieldc','Field C',''),
textInput('fieldd','Field D','')
)
)
),
server = function(input, output) {
output$input_fields <- renderUI({
lapply(1:4, function(i) {
textInput(paste0('field',i), paste('Field',i),'')
})
})
}
)
Run Code Online (Sandbox Code Playgroud)
当前布局:
所需布局:
编辑:忽略字段 A、B、C、D 小部件。它们仅用于显示其他项目如何换行,但 uiOutput 项目充当一个块。假设所有输入都是动态的。
我想我应该使用这段代码。它将 renderUI 移动到 lapply 内以创建多个通用输出(在运行时变化,最多 10 个),我可以使用同样通用的 uiOutput 语句来引用这些输出。它甚至不会警告 5 个不存在的输出。不完美,但可以了。可能需要添加一个observeEvent,因为我认为它本身不会做出反应。
library(shinydashboard)
shinyApp(
ui = dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody(
wellPanel(
flowLayout(
uiOutput('field1'),
uiOutput('field2'),
uiOutput('field3'),
uiOutput('field4'),
uiOutput('field5'),
uiOutput('field6'),
uiOutput('field7'),
uiOutput('field8'),
uiOutput('field9'),
uiOutput('field10')
)
)
)
),
server = function(input, output) {
lapply(1:5, function(i) {
output[[paste0('field',i)]] <- renderUI({
textInput(paste0('field',i), paste('Field',i),'')
})
})
}
)
Run Code Online (Sandbox Code Playgroud)
所有四个动态生成的小部件都被视为一个对象,因为它们包含在一个列表中。因此,定位它们是相当困难的。我能想到的最简单的解决方案是使用insertUI最新闪亮版本的功能,可以使用devtools包安装:
devtools::install_github("rstudio/shiny")
Run Code Online (Sandbox Code Playgroud)
(在这里您可以阅读/了解有关insertUI和 的更多信息removeUI)
我们必须告诉insertUI它应该在用户界面的何处添加新的小部件,我们通过指定参数selector(它必须是 jQuery 选择器接受的字符串)和参数where(有四个选项指定小部件如何应该相对于选择器)
因此,如果我们想在下面添加一个新的小部件,Field 1我们必须进行设置selector = "#fielda"(我们使用#选择器,因为我们引用的是 ID)。同样,我们Field 2通过设置selector = "#fieldb"等添加另一个小部件。根据您的命名约定,我们可以将其概括为:
selector = paste0('#field', letters[i])
Run Code Online (Sandbox Code Playgroud)
在所有情况下我们也设置where = "afterEnd. 它将把新的小部件放置在参考小部件下方。(没有空间将它们放置在参考小部件上方)
现在我们可以包装insertUI成for-loop
for (i in 1:4) {
insertUI(
selector = paste0('#field', letters[i]),
where = "afterEnd",
ui = textInput(paste0('field',i), paste('Field',i),'')
)
}
Run Code Online (Sandbox Code Playgroud)
请注意,我们不需要uiOutput在客户端添加任何内容。
另一个解决方案是dashboardBody在服务器端渲染整个内容,创建动态不同的uiOutputs...这并不令人愉快。
当我们看一下图片时,我们可以看到我是用相反的方式来做的——第一行的名字中的字母大写,第二行的名字中的数字。我希望这不是什么大问题:)
完整示例:
library(shiny)
library(shinydashboard)
shinyApp(
ui = dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody(
flowLayout(
textInput('fielda','Field A',''),
textInput('fieldb','Field B',''),
textInput('fieldc','Field C',''),
textInput('fieldd','Field D','')
)
)
),
server = function(input, output) {
for (i in 1:4) {
insertUI(
selector = paste0('#field', letters[i]),
where = "afterEnd",
ui = textInput(paste0('field',i), paste('Field',i),'')
)
}
}
)
Run Code Online (Sandbox Code Playgroud)
编辑:
如果没有参考小部件,那么您还可以flowLayout使用非标准评估在服务器端动态定义。
假设您想生成三个textInput小部件。您通常可以通过输入来完成此操作
flowLayout(
textInput('fielda', 'Field A'),
textInput('fieldb', 'Field B'),
textInput('fieldc', 'Field C')
)
Run Code Online (Sandbox Code Playgroud)
在客户端。paste0您可以通过在服务器端粘贴带有函数的字符串来执行相同的操作,
i = 1:3
UI <- paste0("flowLayout(",
paste0("textInput(",
"'field", letters[i], "', ",
paste0("'Field ", LETTERS[i], "'"),
")",
collapse = ", "),
")")
Run Code Online (Sandbox Code Playgroud)
将其保存在变量中,例如,,UI然后解析字符串,最后评估它。
eval(parse(text = UI))
Run Code Online (Sandbox Code Playgroud)
在下面的示例中,您有 15 个动态生成的小部件
完整示例:
library(shiny)
library(shinydashboard)
shinyApp(
ui = dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody(
wellPanel(
uiOutput("ui1")
)
)
),
server = function(input, output) {
output[["ui1"]] <- renderUI({
i = 1:15
UI <- paste0("flowLayout(",
paste0("textInput(",
"'field", letters[i], "', ",
paste0("'Field ", LETTERS[i], "'"),
")",
collapse = ", "),
")")
# print(UI)
eval(parse(text = UI))
})
}
)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1857 次 |
| 最近记录: |