Real Time bslib theme is not working when running shiny app - shinyapps

I'm trying to embed a real-time bslib theme into my shiny app. It was working previously, and when I try it on a new plain shiny app it works, but for some reasons, I keep receiving the same error when I run my shiny app:
Error : bslib::bs_themer() requires shiny::bootstrapLib() to be present in the app's UI. Consider providing bslib::bs_theme() to the theme argument of the relevant page layout function (or, more generally, adding bootstrapLib(bs_theme()) to the UI.
I appreciate your support. Here is my code:
ui <- navbarPage(theme = bs_theme(), h4(""),
tabPanel(
title = h6(""),
dashboardPage(
dashboardHeader(),
dashboardSidebar(
sidebarMenu()),
dashboardBody(
fluidRow(
box(plotlyOutput(outputId = "plotly_1"), height = 300),
box(plotlyOutput(outputId = "plotly"), height = 300 )),
fluidRow(column(12),
box(DTOutput(outputId = "dt_output"), height = 300),
)))),
tabPanel(title = h6(""),
dashboardPage(
dashboardHeader(),
dashboardSidebar(
sidebarMenu()),
dashboardBody(
fluidRow(
box(plotlyOutput(outputId = "plotly_2"), height = 300),
box(plotlyOutput(outputId = "plotly_3"), height = 300 )),
))))
server <- function(input, output, session) {
bs_themer()
output$plotly_1 <- renderPlotly ({})
output$plotly <- renderPlotly ({})
output$dt_output <- DT:: renderDataTable ()
}
shinyApp(ui = ui, server = server)'

Related

How to make dropdownButton in shinywidgets always stay on top?

In my shiny app, I have a box with a dropdown menu in the top left corner. However, some of the elements in my box are being cut off by the dropwdown menu (for example, in the pic below the table in my box is being covered by the menu). Is there a way to have the menu to always stay above other elements in my box?
This is my code. I noticed this issue only occurs if I use rhandsontable to render my tables. Unfortunately, I do need to use rhandsontable.
library(shiny)
library(shinyWidgets)
library(shinydashboard)
library(rhandsontable)
factorUI <- function(id) {
ns <- NS(id)
box(
width=6,
title = "Charts",
closable = TRUE,
status = "danger",
solidHeader = TRUE,
collapsible = TRUE,
dropdown(
style = "material-circle",
selectInput(ns("options"),"Select an option:",
choices = list("All" = "all", "Option1" = "option1","Option2" = "option2"),selected = "all"),
conditionalPanel("input.options == 'option1'",ns=ns, sliderInput(ns("shr.month"),"No of months:",min=0,max=1,value=c(0,1),step = 1)),
conditionalPanel("input.options == 'option2'",ns=ns, sliderInput(ns("fh.month"),"No of months:",min=0,max=1,value=c(0,1),step = 1)),
conditionalPanel("input.manual == 'Y'",fileInput(ns("upload"),"Upload new pattern",accept = ".csv")),
materialSwitch(inputId = ns("factorind"),label = "Apply factor",status = "primary",right = TRUE),
conditionalPanel("input.factorind == true",ns=ns,
numericInput(ns("start"),"Apply from:",value = NULL,min=0,step=1),
numericInput(ns("factor"),"Factor:",value=NULL,min=0)),
id = ns("sidebar"),
status = "danger",
size = "sm",
icon = shiny::icon("sliders")),
rHandsontableOutput(ns("table")),
)
}
factor <- function(id) {(
moduleServer(
id,
function(input,output,session) {
output$table <- renderRHandsontable({
rhandsontable(iris)
})
}
)
)}
ui <- fluidPage(
titlePanel("Example"),
sidebarLayout(
sidebarPanel(),
mainPanel(factorUI("test"))
)
)
server <- function(input, output) {
factor("test")
}
shinyApp(ui = ui, server = server)
Increase the z-index of dropdown, you can add the style before the end of box like this:
box(
...,
tags$style('.sw-dropdown-content {z-index: 105;}')
)
The CSS z-index decides the layer order of elements, which one is on top which is below. The table has index of 102, so if you make a number larger than that one for your dropdown (shinyWidgets dropdown default is 5), your drop down will be on top.

Show Tab menuItem after it has been hidden in shiny dashboard

I have a dashboard with several (planned - only two shown here) tabs. After the app has been started, the user should see only the first tab "settings" to load data. After the data have been loaded the other tabs should appear.
I managed to hide the tab "Plot" with hidden() but I have problems to have it appear properly:
whereas the selectInput item appears correctly on the sidebar, the Plot "menuItem" is not shown. I would like to see the Tab "Plot" below settings, so that the user can switch between tabs as soon as the dataset has been chosen. In principle it should look like without the hidden function. I'd be grateful for any help on this.
Here is a reproducible example:
library(shiny)
library(shinydashboard)
library(shinyjs)
ui <- dashboardPage(
dashboardHeader(title = "plot datasets"),
dashboardSidebar(
useShinyjs(),
sidebarMenu(id = "menu", style = "position: Scroll; overflow: visible",
menuItem("Setttings ", tabName = "settings",icon = icon("wrench")),
hidden(
menuItem("Plot",tabName = "Plot",icon = icon("envira"))),
conditionalPanel(condition = "input.menu == 'Plot'",
tags$hr(),
selectInput(inputId = "Variables", label = "Variables", choices = NULL)
)
)
),
dashboardBody(
tabItems(
tabItem(tabName = "settings",
fluidRow(style = "background-color:#D3D3D3;",
column(12,h2("Test mtcars"),h3("Please adjust some settings:")),
),
fluidRow(
column(6,
tags$br(),
selectInput(inputId = "set", label = "Which dataset do you want to plot?",
choices = c("","mtcars","iris"), selected = "")
),
)
),
tabItem(tabName = "Plot",
plotOutput("plot1")
)
)
)
)
server <- function(input, output, session){
data <- reactive({
if(input$set == ""){
NULL
}else{
name <- as.character(input$set)
get(name)
}
})
observe({
choice <- colnames(data())
updateSelectInput(session, "Variables", "Variables", choices = sort(choice))
})
observeEvent(nrow(data())>1,{
req(input$set)
show(selector = '[data-value="Plot"]')
})
output$plot1<- renderPlot({
p <- plot(data()[,2:3])
p
})
}
shinyApp(ui, server)

Wear OS Button Background

Button(
onClick = {
raceOn = !raceOn
if (raceOn) {
text.value = "Stop!"
color.value = Color.Red
} else {
text.value = "Go!"
color.value = Color.Green
}
},
modifier = Modifier.background(color = color.value),
content = {
Text(
text = "${text.value}",
)
}
)
Using the code above, I got the attached image. What I want is the inside of the button to be green and not the background behind it. I couldn't the right property to modify.
Has anyone here tried to modify the Button background? Or perhaps suggest another solution. I tried the OutlinedButton and wasn't successful.
Thanks!
Use the MaterialTheme ButtonColors.
val colors: ButtonColors = ButtonDefaults.primaryButtonColors(backgroundColor = Color.Red)
Button(onClick = { /*TODO*/ }, colors = ButtonDefaults.primaryButtonColors()) {
// TODO
}
You can also update via setting the MaterialTheme defaults.
val wearColorPalette: Colors = Colors(
primary = Purple200,
primaryVariant = Purple700,
secondary = Teal200,
secondaryVariant = Teal200,
error = Red400,
onPrimary = Color.Black,
onSecondary = Color.Black,
onError = Color.Black
)
...
MaterialTheme(
colors = wearColorPalette,
typography = Typography,
// For shapes, we generally recommend using the default Material Wear shapes which are
// optimized for round and non-round devices.
content = content
)

How to display UIDatePicker to choose date

I am following this documentation so that I can pick a date in my Xamarin.iOS app like in this image:
https://learn.microsoft.com/en-us/xamarin/ios/user-interface/controls/picker-images/image9.png
But I can't get it to work. My code:
var datePickerView = new UIDatePicker();
datePickerView.MinimumDate = (NSDate)DateTime.Today.AddDays(-7);
datePickerView.MaximumDate = NSDate.Now;
datePickerView.Mode = UIDatePickerMode.Date;
datePickerView.Locale = NSLocale.FromLocaleIdentifier("en_US");
datePickerView.MoveAndResizeFrame(
UIScreen.MainScreen.Bounds.X - UIScreen.MainScreen.Bounds.Width,
UIScreen.MainScreen.Bounds.Height - 230,
UIScreen.MainScreen.Bounds.Width,
180
);
// Add(datePickerView); do I add it to my view?
I also tried making it my InputView of a UITextField but I get an ugly dialog that's not even usable like this.
var t = new UITextField();
t.InputView = datePickerView;
t.ResizeFrame(300, 50);
t.Placeholder = "enter date";
t.TextColor = UIColor.Black;
Add(t);
I am running this app on iPad with iOS 14.5
The problem is related with the position(frame) you set on the datepicker,the view would locate beyond of the screen in that scenario .
Use the following code , it works fine on my side .
Click on the label , then display the datepicker menu.
var datePickerView = new UIDatePicker();
datePickerView.MinimumDate = (NSDate)DateTime.Today.AddDays(-7);
datePickerView.MaximumDate = NSDate.Now;
datePickerView.Mode = UIDatePickerMode.Date;
datePickerView.Locale = NSLocale.FromLocaleIdentifier("en_US");
datePickerView.Frame = new CGRect(0, 0, UIScreen.MainScreen.Bounds.Width, 180); //this line
Add(datePickerView);

How to modify a js variable within a shiny server (htmlwidgets/R)

This question is more conceptual than explicit to a particular piece of code so I guess there's no toy-code this time.
I have a rather large shiny app that uses some d3.js scripts. The D3 objects access a few global variables when their update functions are called. I'd like to control these variables from the Shiny server - is this possible?
This app assumes the global variable was assigned to the window. Then it uses a custom message handler to create the original variable (#1) and another to manipulate the value of that variable (#2).
Edited to have message sent back to R with the state of the global variable.
R Code:
library(shiny)
ui <- fluidPage(
# Application title
titlePanel("Global Variable Manipulation"),
mainPanel(
sliderInput("data", "Element", min = 0, max = 100, value = 0),
actionButton("go", "GO"),
textOutput("var"),
singleton(
tags$head(tags$script(src = "message-handler.js"))
),
singleton(
tags$head(tags$script(src = "message-handler2.js"))
),
singleton(
tags$head(tags$script(src = "back-to-shiny.js"))
)
)
)
server <- function(input, output, session) {
observe({
session$sendCustomMessage(type = 'testmessage',
message = list(a = 1, b = 'text',
controller = input$data))
})
observeEvent(input$go,{
session$sendCustomMessage(type = 'changeMessage',
message = list(2))
})
output$var <- renderPrint({
input$jsvalue
})
}
# Run the application
shinyApp(ui = ui, server = server)
message-handler.js code:
Shiny.addCustomMessageHandler("testmessage",
function(message) {
window.globalVar = message.controller
alert(JSON.stringify(window.globalVar));
}
);
message-handler2.js code:
Shiny.addCustomMessageHandler("changeMessage",
function(message) {
window.globalVar = window.globalVar-message;
alert(JSON.stringify(window.globalVar));
}
);
back-to-shiny.js code:
setInterval(function(){
var message = window.globalVar;
Shiny.onInputChange("jsvalue", message);
},0);

Resources