Appsilon / semantic.dashboard

Quick, beautiful and customizable dashboard template for Shiny based on shiny.semantic and Fomantic UI.
https://appsilon.github.io/semantic.dashboard/
Other
255 stars 44 forks source link

shinyWidgets::pickerInput not working as expected when used w/ semantic.dashboard #186

Closed AlexPars closed 2 years ago

AlexPars commented 2 years ago

Let me start by saying that semantic.dashboard is a great R package.

I also wanted to inquire about possible solution(s) for the following issues encountered when using shinyWidgets::pickerInput in combination with semantic.dashboard:

See snapshot of UI as Shiny app starts , First_shinyWidget and then a second snapshot when clicking on the box containing the value to select
Second_shinyWidget

Here is the code used to create this dashboard

`if(interactive()){

ui <- semantic.dashboard::dashboardPage(

header = semantic.dashboard::dashboardHeader(
  color = "blue", 
  title = "Dashboard Test", 
  inverted = TRUE
),

sidebar = semantic.dashboard::dashboardSidebar(
  size = "thin", 
  color = "teal",
  semantic.dashboard::sidebarMenu(
    semantic.dashboard::menuItem(
      tabName = "tabID_main", 
      "Main Tab"),
    semantic.dashboard:: menuItem(
      tabName = "tabID_extra", 
      "Extra Tab")
  )
),

body = semantic.dashboard::dashboardBody(
  semantic.dashboard::tabItems(

    selected = 1,

    semantic.dashboard::tabItem(
      tabName = "tabID_main",
      semantic.dashboard::box(
        shiny::h1("Main body"), 
        title = "A b c", 
        width = 16, 
        color = "orange",

        shinyWidgets::pickerInput(
          inputId = "ID_One",
          choices = c("Value One","Value Two","Value Three"),
          label = shiny::h5("Value to select"),
          selected = "Value Two",
          width = "fit",
          inline = TRUE),

        shiny::verbatimTextOutput(outputId = "res_One")
      )
    ),

    semantic.dashboard::tabItem(
      tabName = "tabID_extra",
      shiny::h1("extra")
    )

  )
)

)

server <- function(input, output, session) { output$res_One <- shiny::renderPrint(input$ID_One) }

shiny::shinyApp(ui, server)

}

`

I am using

osenan commented 2 years ago

Hi @AlexPars,

semantic.dashboard uses shiny.semantic components, which in turn suppress boostrap css and js libraries. pickerInput needs boostrap to work. So solution is to load manually js and css boostrap libraries and it will work. Here it is the example of your app:

ui <- semantic.dashboard::dashboardPage(
  header = semantic.dashboard::dashboardHeader(
    color = "blue", 
    title = "Dashboard Test", 
    inverted = TRUE
  ),

  sidebar = semantic.dashboard::dashboardSidebar(
    size = "thin", 
    color = "teal",
    semantic.dashboard::sidebarMenu(
      semantic.dashboard::menuItem(
        tabName = "tabID_main", 
        "Main Tab"),
      semantic.dashboard:: menuItem(
        tabName = "tabID_extra", 
        "Extra Tab")
    )
  ),

  body = semantic.dashboard::dashboardBody(
    tags$head(
      tags$link(rel = "stylesheet", type = "text/css", id = "bootstrapCSS",
                href = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"),
      tags$script(src = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js")
    ),
    semantic.dashboard::tabItems(
      semantic.dashboard::tabItem(
        tabName = "tabID_main",
        semantic.dashboard::box(
          shiny::h1("Main body"), 
          title = "A b c", 
          width = 16, 
          color = "orange",

          shinyWidgets::pickerInput(
            inputId = "ID_One",
            choices = c("Value One","Value Two","Value Three"),
            label = shiny::h5("Value to select"),
            selected = "Value Two",
            width = "fit",
            inline = TRUE),

          shiny::verbatimTextOutput(outputId = "res_One")
        )
      ),

      semantic.dashboard::tabItem(
        tabName = "tabID_extra",
        shiny::h1("extra")
      )

    )
  )
)

server <- function(input, output, session) {
  output$res_One <- shiny::renderPrint(input$ID_One)
}

shiny::shinyApp(ui, server)

semantic_dashboard

In addition, we have now semantic.dashboard 0.2.1. I see you have old version of R but I encourage you to try to update to the latest version, if you can also update R version and then easily enjoy newer versions of shiny and all the shiny ecosystem.

Kind regards and good coding! Oriol

AlexPars commented 2 years ago

Thank you. Your approach solved the problem indeed.

Regarding going to a newer version, one of my constraints is that I can not use yet R version 4.x. And latest available packages (at least Windows binaries) for R 3.6.3 are from May 15 2021.

One more question, please: is there any way to restrict this Bootstrap usage for only a few tabs/subtabs, and also to be able to use shinyWidget functions (using this Bootstrap dependency) and shiny.semantic functions?

I have tried to make it work this way, but without success.

osenan commented 2 years ago

Hi, with today's state of the art of Shiny it is not possible to do what you would like to do.

What I suggest:

If your case is that you want to use most of your components from semantic.dashboard and shiny.semantic , you can load css and js from shiny.semantic after you load bootrap css and js libraries:

      tags$head(
        tags$link(rel = "stylesheet", type = "text/css", id = "bootstrapCSS",
                  href = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"),
        tags$script(src = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"),
        tags$link(rel = "stylesheet", type = "text/css", href = "https://github.com/Appsilon/shiny.semantic/blob/develop/inst/www/shared/semantic/semantic.min.css"),
        tags$script(src = "https://github.com/Appsilon/shiny.semantic/blob/develop/inst/www/shared/semantic/semantic.min.js")

But if two classes have the same name in bootstrap or in fomantic ui - so the last loaded will prevail, in this case fomantic ui - so some ShinyWidgets may break and you may need to add custom css/js.

If your situation is that you need to use lots of different boostrap components inside a semantic.dashboard app maybe is better to use a framework that uses boostrap, like shinydashboard or similar, if not you will need to add custom css/js to each of the non working components.

Also if you need very customised solution it might be better for your case to not use any specific framework, instead you can use custom css and some for example you could use https://cran.rstudio.com/web/packages/imola/index.html for the layout.

Hope it helps, Oriol