[英]Create dynamic number of card elements in shiny flowLayout
I like to fill an area in a shiny app with card elements. 我喜欢用卡片元素填充闪亮的应用程序中的区域。 The items flow into the next row when there is not enough space.
如果没有足够的空间,这些项目将流入下一行。 This can be achieved with
flowLayout
. 这可以通过
flowLayout
实现。
But I do not know the number of items in advance, so I need to create the card elements in a loop. 但是我不知道物品的数量,所以我需要循环创建卡片元素。 But when I use lapply inside
flowLayout
all elements are shown below each other. 但是,当我在
flowLayout
使用lapply时,所有元素都显示在彼此下面。
How to fix this, so that items are shown in rows next to each other? 如何解决此问题,使项目以相邻的行显示?
library(shiny)
card <- function(.img, .species, .sepal.length) {
HTML(
paste0(
'<div class="card">
<img src="', .img, '" style="width:100%">
<div class="container">
<h4><i>', .species, '</i></h4>
<hr>
<p>Sepal Length: ', .sepal.length, '</p>
</div>
</div>')
)
}
img.src <- "https://www.plant-world-seeds.com/images/item_images/000/007/023/large_square/iris_baby_blue.jpg?1500653527"
ui <- fluidPage(
tags$head(tags$style('.card {
width: 250px;
clear: both;
/* Add shadows to create the "card" effect */
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
transition: 0.3s;
}
/* On mouse-over, add a deeper shadow */
.card:hover {
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
}
/* Add some padding inside the card container */
.container {
width: 250px;
padding: 2px 16px;
}')),
uiOutput("cards")
)
server <- function(input, output, session) {
# This looks as expected
# output$cards <- renderUI({
# shiny::flowLayout(
# cellArgs = list(
# style = "
# width: auto;
# height: auto;
# margin: 5px;
# "),
# card(img.src,
# .species = iris[1, "Species"],
# .sepal.length = iris[1, "Sepal.Length"]),
# card(img.src,
# .species = iris[2, "Species"],
# .sepal.length = iris[2, "Sepal.Length"]),
# card(img.src,
# .species = iris[3, "Species"],
# .sepal.length = iris[3, "Sepal.Length"]),
# card(img.src,
# .species = iris[4, "Species"],
# .sepal.length = iris[4, "Sepal.Length"])
# )
# })
# Now elements are below each other when using lapply
output$cards <- renderUI({
shiny::flowLayout(
cellArgs = list(
style = "
width: auto;
height: auto;
margin: 5px;
"),
lapply(1:4, function(.x) card(img.src,
.species = iris[.x, "Species"],
.sepal.length = iris[.x, "Sepal.Length"]))
)
})
}
shinyApp(ui, server)
The comment above links to an answer that works, but there is a much easier way. 上面的评论链接到了一个可行的答案,但是有一种更简单的方法。
Instead of using lapply
(which makes a list, confusing flowLayout
), we can use do.call
to expand the argument. 可以使用
do.call
来扩展参数,而不是使用lapply
(它使列表混乱,使flowLayout
混乱)。
Updated server function: 更新的服务器功能:
server <- function(input, output, session) {
output$cards <- renderUI({
# First make the cards
args <- lapply(1:4, function(.x) card(img.src,
.species = iris[.x, "Species"],
.sepal.length = iris[.x, "Sepal.Length"]))
# Make sure to add other arguments to the list:
args$cellArgs <- list(
style = "
width: auto;
height: auto;
margin: 5px;
")
# basically the same as flowLayout(cards[[1]], cards[[2]],...)
do.call(shiny::flowLayout, args)
})
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.