1

I am looking for a way to choose from a given set of items (say the months of the year) a subset of items (say those months which I like) as well as (simultaneously) a single item (could be my birthday month). Depending on the choices, some more information needs to be printed (this might be the percentage of days which this month contributes to the overall favourite months). A datatable containing columns with

  • all possible items (month names)
  • checkboxes
  • radiobuttons
  • additional output

would be a technical realisation of this idea.

I have found working examples for each of checkboxes (entry of 2015-06-11) and radiobuttons (answer of 2016-08-12) separately, but I am unable to combine these. It seems to me that the underlying mechanism is different; but maybe I am simply lacking JS knowledge. The following code tries to include the radioButtons into the checkbox example; the checkboxes are still working, the radioButtons seem to be working but I can't access the actual choice :-(

library(shiny)
library(DT)
shinyApp(
  ui = fluidPage(DT::dataTableOutput('x1'), verbatimTextOutput('x2'), verbatimTextOutput('sel')),

server = function(input, output) {
  # create a character vector of shiny inputs
  shinyInput = function(FUN, len, id, ...) {
    inputs = character(len)
    for (i in seq_len(len)) {
      inputs[i] = as.character(FUN(paste0(id, i), label = NULL, ...))
    }
    inputs
  }

  # obtain the values of inputs
  shinyValue = function(id, len) {
    unlist(lapply(seq_len(len), function(i) {
      value = input[[paste0(id, i)]]
      if (is.null(value)) NA else value
    }))
  }

  # a sample data frame
  res = data.frame(
    Month = month.abb,
    Like = shinyInput(checkboxInput, 12, 'v2_', value = TRUE),
    # v3 is constructed as in the radioButton matrix example
    Birthday = sprintf('<input type="radio" name="%s" value="%s"/>', "rButton", 1:12),
    Info = sample(LETTERS, 12, TRUE),
    stringsAsFactors = FALSE
  )

  # render the table containing shiny inputs
  output$x1 = DT::renderDataTable(
    res, server = FALSE, escape = FALSE, selection = 'none', options = list(
      dom = 't', paging = FALSE, ordering = FALSE,
      # is the preDrawCallback argument needed? Seems to have no effect at all.
      preDrawCallback = JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
      drawCallback = JS('function() { Shiny.bindAll(this.api().table().node()); } ')#,
      # the following is from the radioButton matrix example, but doesn't work here
      #       callback = JS("table.rows().every(function(i, tab, row) {
      #                   var $this = $(this.node());
      #                   $this.attr('id', this.data()[0]);
      #                   $this.addClass('shiny-input-radiogroup');
      #                   });
      #                   Shiny.unbindAll(table.table().node());
      #                   Shiny.bindAll(table.table().node());")
    )
  )
  # print the values of inputs
  output$x2 = renderPrint({
    data.frame(Like = shinyValue('v2_', 12))
  })
  output$sel = renderPrint({
    # this is from the radioButton matrix example but doesn't work here
    str(sapply("rButton", function(i) input[[i]]))
  })
})

On the other hand I am not sure whether this will - when realised - make an intuitive, useful interface. I am also interested in advice regarding the structure of the user interface.

Hans
  • 115
  • 1
  • 6
  • I have not added a code snippet but only the links as I would just copy/paste from elewhere. But I am not sure whether it would be better (and more polite) to duplicate the code for convenience. What is the right thing to do? – Hans Feb 14 '18 at 00:55
  • 1
    Hi Hans, in general you should provide a [reproducible example](https://stackoverflow.com/questions/48343080/how-to-convert-a-shiny-app-consisting-of-multiple-files-into-an-easily-shareable/48343110#48343110), so I would advise you to create the code that gets you as close to what you want as possible. – Florian Feb 14 '18 at 06:38

0 Answers0