You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Shiny/R中实现拖放状态保存,供客户端调整后查看?

解决方案实现步骤

1. 替换Div为图片

把原代码中的文本Div替换为包含图片的容器,支持本地或网络图片:

  • 本地图片:需在应用目录下创建www文件夹,将图片放入其中,代码中直接引用文件名
  • 网络图片:填写完整图片URL

示例替换代码:

htmltools::tags$div(
  class = "rank-list-item",
  tags$img(src = "image1.jpg", width = "100px"),
  tags$br(),
  "图片1" # 可选添加图片说明
)

2. 添加保存功能与状态持久化

必须做状态持久化:Shiny前端交互状态仅存在于当前用户会话,刷新/关闭页面后会丢失,需将排序结果永久存储。以下是基于文件存储的实现(适配shinyapps.io环境):

修改UI部分

添加用户标识输入框和保存按钮,同时显示保存状态:

fluidRow(
  column(
    width = 6,
    textInput("user_id", "请输入您的姓名/标识:"),
    actionButton("save_btn", "保存排序结果")
  ),
  column(
    width = 6,
    verbatimTextOutput("save_status") # 反馈保存结果
  )
)

修改Server部分

监听保存按钮,将排序结果追加写入CSV文件:

server <- function(input, output, session) {
  observeEvent(input$save_btn, {
    # 确保用户输入和排序结果不为空
    req(input$user_id, input$rank_list_2)
    
    # 整理保存数据:用户标识、时间戳、排序结果
    result_data <- data.frame(
      user_id = input$user_id,
      timestamp = as.character(Sys.time()),
      sorted_items = paste(input$rank_list_2, collapse = "; ")
    )
    
    # 写入CSV文件,首次写入自动添加表头
    write.table(
      result_data,
      file = "sort_results.csv",
      sep = ",",
      row.names = FALSE,
      append = TRUE,
      col.names = !file.exists("sort_results.csv")
    )
    
    # 显示保存成功提示
    output$save_status <- renderPrint({
      cat("排序结果已成功保存!")
    })
  })
}

3. 开发者查看结果

部署到shinyapps.io后,你可以通过以下方式获取结果:

  • 登录shinyapps.io后台,找到对应应用,进入Files标签页,下载sort_results.csv文件,即可查看所有客户的排序提交记录。

完整修改后的代码

library(shiny)
library(sortable)

ui <- fluidPage(
  tags$head(
    tags$style(HTML(".bucket-list-container {min-height: 350px;}")),
    tags$style(
      "#rank_list_1,
      #rank_list_2{
      display: flex;
      gap: 10px;
      }
      .rank-list-item {
        padding: 5px;
        border: 1px solid #ddd;
        border-radius: 4px;
        text-align: center;
      }"
    )
  ),
  fluidRow(
    column(
      width = 12,
      tags$b("图片排序调整"),
      bucket_list(
        header = "请将图片拖拽到右侧区域调整顺序",
        group_name = "bucket_list_group",
        orientation = "horizontal",
        add_rank_list(
          text = "待排序图片",
          input_id = "rank_list_1",
          labels = list(
            htmltools::tags$div(
              class = "rank-list-item",
              tags$img(src = "image1.jpg", width = "100px"),
              tags$br(),
              "图片1"
            ),
            htmltools::tags$div(
              class = "rank-list-item",
              tags$img(src = "image2.jpg", width = "100px"),
              tags$br(),
              "图片2"
            ),
            htmltools::tags$div(
              class = "rank-list-item",
              tags$img(src = "image3.jpg", width = "100px"),
              tags$br(),
              "图片3"
            ),
            htmltools::tags$div(
              class = "rank-list-item",
              tags$img(src = "image4.jpg", width = "100px"),
              tags$br(),
              "图片4"
            )
          )
        ),
        add_rank_list(
          text = "已排序图片",
          labels = NULL,
          input_id = "rank_list_2"
        )
      )
    )
  ),
  fluidRow(
    column(
      width = 6,
      textInput("user_id", "请输入您的姓名/标识:"),
      actionButton("save_btn", "保存排序结果")
    ),
    column(
      width = 6,
      verbatimTextOutput("save_status")
    )
  )
)

server <- function(input, output, session) {
  observeEvent(input$save_btn, {
    req(input$user_id, input$rank_list_2)
    
    result_data <- data.frame(
      user_id = input$user_id,
      timestamp = as.character(Sys.time()),
      sorted_items = paste(input$rank_list_2, collapse = "; ")
    )
    
    write.table(
      result_data,
      file = "sort_results.csv",
      sep = ",",
      row.names = FALSE,
      append = TRUE,
      col.names = !file.exists("sort_results.csv")
    )
    
    output$save_status <- renderPrint({
      cat("排序结果已成功保存!")
    })
  })
}

shinyApp(ui, server)

关键注意事项

  • 本地图片需放在应用目录的www文件夹下,否则shinyapps.io无法加载
  • shinyapps.io的文件存储属于应用实例级,所有用户的提交会统一写入同一个CSV文件
  • 如果需要区分不同客户的多次提交,可在数据中增加随机会话ID等标识

内容的提问来源于stack exchange,提问作者Laura

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 04:34:56