我喜欢用卡片元素填充闪亮的应用程序中的某个区域。如果没有足够的空间,这些项目将流入下一行。这可以通过flowLayout
来实现。
但是我不知道物品的数量,所以我需要循环创建卡片元素。但是当我在flowLayout
中使用lapply时,所有元素都显示在彼此下面。
如何解决此问题,使项目以相邻的行显示?
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)
答案 0 :(得分:1)
上面的评论链接到了一个有效的答案,但是有一种更简单的方法。
我们可以使用lapply
来扩展自变量,而不是使用flowLayout
(使列表混乱,do.call
)。
更新的服务器功能:
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)
})
}