首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >显示表中的下拉功能

显示表中的下拉功能
EN

Stack Overflow用户
提问于 2021-04-12 07:23:07
回答 1查看 370关注 0票数 4

我正在搜索一个方法(包),它使我能够从一个表()中的一个表()中的另一个表中的一行中“删除”一行。我设想的服务器端功能是,我可以创建一些逻辑来更新目标表。不幸的是,我还没有成功地用我能找到的可用的闪亮软件包来实现这个原型。

下面代码中MVP概念的思想是将顶部表中的一个调用者分配给第二个表中的一行。

我的结论是:

代码语言:javascript
复制
library(shiny)
library(shinyjqui)
library(tidyverse)

ui <- fluidPage(
  h1("UI functionality: Drop-on table"),
  h3("Callers - (source)"),
  tableOutput("callers"),
  h3("Calls to be made - (destination)"),
  tableOutput("calls_to_be_made"),
  hr()
)

server <- function(input, output, session) {
  
  callers <- tibble(
    Caller = c("Jerry", "Donald")
  )
  
  calls_to_be_made <- tibble(
    Name = c("John", "Fred", "Bill", "Freddy"),
    PhoneNumber = c("0123 456 785", "0123 456 6453", "9876 532 432","235 63 430"),
    Caller = c("Jerry",NA,NA,NA )
  )
  
  jqui_sortable(
    ui      = "#callers table",
    options = list(items = "tbody tr", connectWith = "#calls_to_be_made table")
  )

  jqui_sortable(
    ui      = "#calls_to_be_made table",
    options = list(items = "tbody tr")
  )

  output$callers <-  renderTable(callers, rownames = T)
  output$calls_to_be_made <-  renderTable(calls_to_be_made, rownames = T)
}

shinyApp(ui, server)

我尝试过用shinyjqui函数、jqui_draggable()jqui_droppable()解决方案,但这些尝试没有成功,我觉得它们实际上离上面的代码更远。

我正在寻找创造性的想法和建议来实现这一功能。希望你们中的一些读过这个问题的人会给出一些建议,让他们在闪亮的环境中完成这个功能。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-06 12:44:15

您可以使用{shinyjqui}创建一个界面,该接口允许您从某个表中拖动单元格,将它们拖放到另一个表中,并对拖放表的底层数据帧进行闪亮的更新。

首先,我们需要在服务器功能中定义可拖放的。

代码语言:javascript
复制
  jqui_draggable(
    ui = "#callers td",
    options = list(
      revert = "invalid",
      helper = "clone"))
  
  droppable <- function() {
    jqui_droppable(
      ui = "#calls_to_be_made td",
      options = list(
        drop = JS("function(event, ui) {
                     Shiny.setInputValue(\"update_cells\", {
                       source_col: ui.draggable.index(),
                       source_row: ui.draggable.parent().index() + 1,
                       dest_col: $(this).index(),
                       dest_row: $(this).parent().index() + 1
                     });
                   }")))
  }

  droppable() #Initialisation

这里发生了几件事。

首先,jqui_droppable调用封装在一个函数(droppable)中,因为我们需要稍后再调用它。

其次,我们使用Shiny.setInputValue() (一个javascript函数)将被删除的单元格(source_*)和被丢弃的单元格(dest_*)的行和列索引发送到闪亮的后端。Javascript索引从0开始,R索引从1开始,因此我们抵消JS索引来匹配内部R索引。但是,由于行名占用HTML表中的列,而不是R数据帧中的列,因此不需要偏移列索引。

接下来,我们对calls_to_be_made进行反应,并编写更新数据帧服务器端的逻辑。

代码语言:javascript
复制
  calls_to_be_made_react <- reactiveVal(calls_to_be_made)

  observeEvent(input$update_cells, {
    ## Update dataset
    if (min(unlist(input$update_cells)) > 0) {
      updated_ctbm <- calls_to_be_made_react()
      ## Specify what row and column to drop in
      updated_ctbm[
        input$update_cells[["dest_row"]],
        "Caller"] <- callers[
          input$update_cells[["source_row"]],
          input$update_cells[["source_col"]]]
      
      calls_to_be_made_react(updated_ctbm)

      ## Make sure the newly drawn table becomes droppable again
      droppable()
    }
  })

if语句中的条件检查行名是否被拖放,并且在这种情况下不更新数据帧。这个条件可以扩展到某种类型的验证函数,它限制了哪些单元格可以被拖放到哪个可拖动的单元上,但这超出了这个问题的范围。

observableEvent内部也是我们再次调用droppable函数的地方。因为闪亮重新绘制了整个表,所以使该表可下垂的代码也需要再次运行。

最后,我们需要更新输出调用,所以它使用了反应性calls_to_be_made

代码语言:javascript
复制
  output$calls_to_be_made <-  renderTable(calls_to_be_made_react(), rownames = T)

这提供了以下服务器功能,可以执行您所要求的操作。

代码语言:javascript
复制
server <- function(input, output, session) {

  callers <- tibble(
    Caller = c("Jerry", "Donald")
  )

  calls_to_be_made <- tibble(
    Name = c("John", "Fred", "Bill", "Freddy"),
    PhoneNumber = c("0123 456 785", "0123 456 6453", "9876 532 432","235 63 430"),
    Caller = c("Jerry",NA,NA,NA )
  )

  jqui_draggable(
    ui = "#callers td",
    options = list(
      revert = "invalid",
      helper = "clone"))
  
  droppable <- function() {
    jqui_droppable(
      ui = "#calls_to_be_made td",
      options = list(
        drop = JS("function(event, ui) {
                     Shiny.setInputValue(\"update_cells\", {
                       source_col: ui.draggable.index(),
                       source_row: ui.draggable.parent().index() + 1,
                       dest_col: $(this).index()
                       dest_row: $(this).parent().index() + 1
                     });
                   }")))
  }

  droppable() #Initialisation

  calls_to_be_made_react <- reactiveVal(calls_to_be_made)

  observeEvent(input$update_cells, {
    ## Update dataset
    if (min(unlist(input$update_cells)) > 0) {
      updated_ctbm <- calls_to_be_made_react()
      ## Specify what row and column to drop in
      updated_ctbm[
        input$update_cells[["dest_row"]],
        "Caller"] <- callers[
          input$update_cells[["source_row"]],
          input$update_cells[["source_col"]]]
      
      calls_to_be_made_react(updated_ctbm)

      ## Make sure the newly drawn table becomes droppable again
      droppable()
    }
  })
  
  output$callers <-  renderTable(callers, rownames = T)
  output$calls_to_be_made <-  renderTable(calls_to_be_made_react(), rownames = T)
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67054134

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档