SymbolixAU / googleway

R Package for accessing and plotting Google Maps
http://symbolixau.github.io/googleway/
Other
234 stars 46 forks source link

Conditionalpanel inside Info_window html content #276

Open cwilligv opened 1 day ago

cwilligv commented 1 day ago

Hi there, I’ve set up my markers with HTML content inside the info_window parameter. I’ve implemented some interactive features and one of the component is a switch input that changes the visibility of another component in there, however, it seems to ignore the condition and doesn’t do anything. Do you know if this is by design or is there another way to enable that interactivity inside the info_window?

Cheers

dcooley commented 1 day ago

Do you know if this is by design

No idea I'm afraid.

Can you share an example of what you're trying to do please?

cwilligv commented 1 day ago

Sure, here is a reprex:

# Load packages 
library(shiny) 
library(bslib)
library(googleway)
library(shinyWidgets)
library(ShinyRating)

# Define the UI
ui <- fluidPage(
  google_mapOutput("map")
)

# Define the server
server <- function(input, output) {

  # Create some dummy data
  data <- data.frame(
    lat = c(-27.469),
    lon = c(153.0251),
    siq = c(85)
  )

  # Generate the map with markers and info windows
  output$map <- renderGoogle_map({
    google_map(key = "you-api-key") %>%
      googleway::add_markers(data = data, lat = "lat", lon = "lon", info_window = create_info_window(data))
  })

  create_info_window <- function(data){
    as.character(
      card(
        class = "shadow-none mx-0 px-0",
        card_body(
          gap = 0,
          padding = 0,
          min_height = 200,
          switchInput("test1", onLabel = "Street", offLabel = "Mall", value = TRUE),
          p("Score"),
          conditionalPanel(
            condition = "input.test1 == true",
            ratingInput(
              inputId = "star20x",
              i_on_color = "#D5AB55",
              cumul = TRUE,
              number = 5,
              value = 3,
              read_only = T
            )
          )
        )
      )
    )
  }
}

# Run the app
shinyApp(ui, server)

And this is sort of what I look for in the info_window:

library(shiny)
library(bslib)
library(ShinyRating)

# UI
ui <- fluidPage(
  theme = bs_theme(),
  titlePanel("Toggle Button Visibility with SwitchInput"),
  sidebarLayout(
    sidebarPanel(
      switchInput("toggle", "Show Button", value = TRUE)
    ),
    mainPanel(
      conditionalPanel(
        condition = "input.toggle == true",
        ratingInput(
          inputId = "star20x",
          i_on_color = "#D5AB55",
          cumul = TRUE,
          number = 5,
          value = 3,
          read_only = T
        )
      )
    )
  )
)

# Server
server <- function(input, output) { }

# Run the application 
shinyApp(ui = ui, server = server)
dcooley commented 23 hours ago

where is ShinyRating hosted?

cwilligv commented 23 hours ago

oh sorry, use this: devtools::install_github("mhanf/ShinyRating")

dcooley commented 23 hours ago

in theory you can specify an DOM inside the info window and it will work.

Here's a minimal example, with the code taken from this SO answer

Note that the info_window parameter requires a 'string specifying the column name', so I've attached the 'info' as a column on the data object

library(shiny) 
library(googleway)

# Define the UI
ui <- fluidPage(
  google_mapOutput("map")
)

# Define the server
server <- function(input, output) {

  # Create some dummy data
  data <- data.frame(
    lat = c(-27.469),
    lon = c(153.0251),
    siq = c(85),
    info = paste0('<div id="content" style="width:400px; background-color:red;">',
      'My Text comes here' ,
      '</div>'
    )
  )

  output$map <- renderGoogle_map({
    google_map(key = secret::get_secret("GOOGLE")) %>%
      googleway::add_markers(data = data, lat = "lat", lon = "lon", info_window = "info")
  })
}

shinyApp(ui, server)
cwilligv commented 18 hours ago

Thanks Dave. Indeed, it works the way you frame it in your example but as soon as I include the conditonalpanel, it seems like the condition can't find the input I'm referring to and doesn't do anything.

If I use your example and add the info html content as a column in the dataframe without the conditionalpanel it works

data <- data.frame(
    lat = c(-27.469),
    lon = c(153.0251),
    siq = c(85),
    info = as.character(
      tags$div(
        switchInput("test1", onLabel = "Street", offLabel = "Mall", value = TRUE),
        p("Score"),
        ratingInput(
          inputId = "star20x",
          i_on_color = "#D5AB55",
          cumul = TRUE,
          number = 5,
          value = 3,
          read_only = T
        )
      )
    )
  )

However, if I include the conditionalpanel then the rating component doesn't even show:

data <- data.frame(
    lat = c(-27.469),
    lon = c(153.0251),
    siq = c(85),
    info = as.character(
      tags$div(
        switchInput("test1", onLabel = "Street", offLabel = "Mall", value = TRUE),
        p("Score"),
        conditionalPanel(
          condition = "input.test1 == true",
          ratingInput(
            inputId = "star20x",
            i_on_color = "#D5AB55",
            cumul = TRUE,
            number = 5,
            value = 3,
            read_only = T
          )
        )
      )
    )
  )

Should the input id 'test1' be referenced in a different way perhaps, for the condition in conditionalpanel to pick it up?

cwilligv commented 5 hours ago

After studying this more I think the issue is that when the info_window is triggered shiny doesn’t know anything about those inputs inside so they need to be binded for the conditional panel to pick it up. any ideas on how to bind those input elements in Shiny?