RinteRface / bs4Dash

Bootstrap 4 shinydashboard using AdminLTE3
https://bs4dash.rinterface.com
Other
435 stars 81 forks source link

Not working with Bookmarking? #177

Open jamessmythe opened 3 years ago

jamessmythe commented 3 years ago

Hi Davide,

I've been trying to use bs4dash to replace shinydashboard on an app with bookmarking, and for some reason bookmarking doesn't like it. I think it's something to do with the onRestore function, but I can't work it out.

To reproduce, simply switch library(bs4Dash) with library(shinydashboard) - with the latter, the bookmarked page should restore; with bs4Dash, the original "home" page is restored.

Sorry it's a very basic reprex.

James

library(shiny)
library(tidyverse)
library(shinyjs)
library(bs4Dash)

wspUI <- function(id) {

  ns <- NS(id)

  tagList(

    dashboardPage(

      title = "test",

      skin = "blue",

      header = dashboardHeader(
        title = "Yay"
      ),

      sidebar = dashboardSidebar(

      ),

      body = dashboardBody(
        bookmarkButton(label = "Copy URL", width = '100%', style = "margin-top: 5px; text-align: left; background-color: #007bff; color: white")
      )
    )
  )
}

homeUI <- function(id) {

  ns <- NS(id)

  div(id = "homecontent",

      h2("This page should not appear when restoring from a bookmark"),

      actionButton(
        "button1",
        style = "text-align: center; display: table; margin: 0 auto; padding: 10px; font-size: 24px; ",
        label = 'Click me to go through'
      )

  )

}

wspServer <- function(id) {

  moduleServer(

    id,

    function(input, output, session) {

      observeEvent(input$wsp_bookmark, {

        session$doBookmark()

      })

    }

  )

}

ui <- function() {

  fluidPage(

    shinyjs::useShinyjs(),

    div(id = "homecontent", 
        homeUI("home")
    ) %>% hidden(),

    div(id = "wspcontent", 
        wspUI("wsp")
    ) %>% hidden()
  )

}

server <- function(input, output, session, chosenModule){

  chosenModule <- reactiveValues(mod = 0)

  observeEvent(input$button1, {chosenModule$mod <<- 1}, ignoreInit = TRUE)

  observe({

    if(chosenModule$mod == 1) {

      wspServer("wsp")

      toshow <<- paste("wspcontent")
      tohide <<- paste("homecontent")
      shinyjs::show(id = toshow)
      shinyjs::hide(id = tohide)

    } else {

      toshow <<- paste("homecontent")
      tohide <<- paste("wspcontent")
      shinyjs::show(id = toshow)
      shinyjs::hide(id = tohide)

    }

  })

  onBookmark(function(state){
    state$values$mod <- chosenModule$mod
    })

  onRestore(function(state){
    chosenModule$mod <- state$values$mod
    })

  setBookmarkExclude(c("sidebarItemExpanded", "sidebarId", "wsp-bookmark","wsp-wsp_audiences","button1"))

}

shinyApp(ui, server, enableBookmarking = "url")
lanceupton commented 3 years ago

I'm facing a similar issue and in case a more minimal example is useful, I've included some.

The below works as intended - The onRestore callback shows a notification.

library(shiny)

shinyApp(
  enableBookmarking = "server",
  ui = function(request) {
    fluidPage(
      textInput("text", "Text Input"),
      bookmarkButton()
    )
  },
  server = function(input, output, session) {
    onRestore(function(state) {
      showNotification("restored")
    })
  }
)

The below bs4Dash version does not trigger the onRestore callback:

library(shiny)
library(bs4Dash)
shinyApp(
  enableBookmarking = "server",
  ui = function(request) {
    bs4DashPage(
      header = bs4DashNavbar(disable = TRUE),
      sidebar = bs4DashSidebar(disable = TRUE),
      body = bs4DashBody(
        textInput("text", "Text Input"),
        bookmarkButton()
      )
    )
  },
  server = function(input, output, session) {
    onRestore(function(state) {
      showNotification("restored")
    })
  }
)
Alik-V commented 1 year ago

Hi @DivadNojnarg, I am looking to use your bs4Dash in one of applications for its sleek visuals. However, the application heavily relies on the use of bookmarking functionality. I see this issue has been created a while ago - do you know if it's still relevant today?

DivadNojnarg commented 1 year ago

Looking at the example above, the bookmark is done and you can retrieve the input value when visiting the link provided by bookmark button. However, the onRestore does not show the notification. I don't see any JS error/warning.

library(shiny)
library(bs4Dash)
shinyApp(
  enableBookmarking = "server",
  ui = function(request) {
    bs4DashPage(
      header = bs4DashNavbar(disable = TRUE),
      sidebar = bs4DashSidebar(disable = TRUE),
      body = bs4DashBody(
        textInput("text", "Text Input"),
        bookmarkButton()
      )
    )
  },
  server = function(input, output, session) {
    onRestore(function(state) {
      showNotification("restored")
    })
  }
)
Andryas commented 1 year ago

I tried the follow code and is still not working, any idea when it will be fixed? Thank you

I used the Posit example.

library(shiny)
library(bs4Dash)

ui <- function(request) {
  bs4Dash::bs4DashPage(
    bs4Dash::dashboardHeader(),
    bs4Dash::bs4DashSidebar(
      sliderInput("n", "Value to add", min = 0, max = 100, value = 50),
      actionButton("add", "Add"), br(), br(),
      bookmarkButton()
    ),
    bs4Dash::bs4DashBody(
      h4("Sum of all previous slider values:", textOutput("sum"))
    )
  )
}

server <- function(input, output, session) {
  vals <- reactiveValues(sum = 0)

  # Save extra values in state$values when we bookmark
  onBookmark(function(state) {
    state$values$currentSum <- vals$sum
  })

  # Read values from state$values when we restore
  onRestore(function(state) {
    print(state$values$currentSum)
    vals$sum <- state$values$currentSum
  })

  # Exclude the add button from bookmarking
  setBookmarkExclude("add")

  observeEvent(input$add, {
    vals$sum <- vals$sum + input$n
  })
  output$sum <- renderText({
    vals$sum
  })
}

shinyApp(ui, server, enableBookmarking = "url")