Search code examples
rshinyaction-buttonshinywidgets

How to align to the right an actionButton inside a ConditionalPanel?


I am creating a shiny app where depending on your selectInput, you will see an extra actionButton or not. In order to get that, this extra button has to be inside a conditionalPanel.

I want to have both actionButtons aligned, the regular one on the left and the extra, on the right. Thanks to this post I managed to move it to the right, but they are not aligned as you can see in the attached image.

image 1

Code:

library(shiny)
library(shinyWidgets)
library(shinyFeedback)
library(DT)

ui <- fluidPage(
  sidebarPanel(
    useShinyFeedback(),
    selectInput(inputId = "type", label = "Select your data", 
                choices =  c("Data 1" = "data1",
                             "Data 2" = "data2")),
    
    actionButton(
      inputId = "button",
      label = "Submit type of data",
      icon = icon("check")
    ),
    
    conditionalPanel(
      condition = "input.type == 'data2'",
      div(style = "position:absolute;right:1em;",
        actionButton(
          inputId = "button_more_info_data2",
          label = "More info",
          icon = icon("info-circle"))
      )
    )
    
  ),
  mainPanel(
    dataTableOutput("table")
  )
)

server <- function(input, output, session) {
  
  observeEvent(input$button, {
    if(input$type == "data2"){
      show_alert(
        title = "Are you sure?",
        text = HTML("This data is....<br>Please, be careful with..."),
        type = "warning",
        html = TRUE
      )
      
    }else{
      show_alert(
        title = "OK",
        text = "You don't have to do anything",
        type = "success"
      )
    }
  })
  
  observeEvent(input$type,{
    feedbackWarning(inputId = "type",
                    show = ("data2" %in% input$type),
                    text ="This data is... Please, be careful..."
    )
  })
  
  mydata <- reactive({
    if(input$type == "data1"){
      mtcars
    }else{
      iris
    }
      
    }) %>% bindEvent(input$button)
  
  output$table <- renderDataTable(mydata())
}

if (interactive())
  shinyApp(ui, server)

I also tried what they answered in:

1- This post, but it doesn't work for me because I am not working with columns.

conditionalPanel(
   condition = "input.type == 'data2'",
     actionButton(
                  inputId = "button_more_info_data2",
                  label = "More info",
                  icon = icon("info-circle"),
                  style = 'margin-top:25px'
        )
    )

2- These two from this post:

conditionalPanel(
      condition = "input.type == 'data2'",
      div(style="display:inline-block",
        actionButton(
          inputId = "button_more_info_data2",
          label = "More info",
          icon = icon("info-circle"),
          style="float:right")
      )
    )

 conditionalPanel(
      condition = "input.type == 'data2'",
      div(style = "display:inline-block; float:right",
        actionButton(
          inputId = "button_more_info_data2",
          label = "More info",
          icon = icon("info-circle"))
      )
    )

3- And this option (but I think it depends on another actionButton and it doesn't work for me).

conditionalPanel(
          condition = "input.type == 'data2'",
          div(style = "display:inline-block",
            actionButton(
              inputId = "button_more_info_data2",
              label = "More info",
              icon = icon("info-circle"))
          )
        )

Does anybody know how to have both actionButtons aligned?

Thanks in advance


Solution

  • I found the solution by chance.

    The order of the conditionalPanel has to be moved before the regular actionButton and instead of writing 1em, it would be 2.5em to have the button and the selectInput justified.

    image

    library(shiny)
    library(shinyWidgets)
    library(shinyFeedback)
    library(DT)
    
    ui <- fluidPage(
      sidebarPanel(
        useShinyFeedback(),
        selectInput(inputId = "type", label = "Select your data", 
                    choices =  c("Data 1" = "data1",
                                 "Data 2" = "data2")),
        conditionalPanel(
          condition = "input.type == 'data2'",
          div(style = "position:absolute;right:2.5em;",
              actionButton(
                inputId = "button_more_info_data2",
                label = "More info",
                icon = icon("info-circle"))
          )
        ),
        
        actionButton(
          inputId = "button",
          label = "Submit type of data",
          icon = icon("check")
        ),
        
       
        
      ),
      mainPanel(
        dataTableOutput("table")
      )
    )
    
    server <- function(input, output, session) {
      
      observeEvent(input$button, {
        if(input$type == "data2"){
          show_alert(
            title = "Are you sure?",
            text = HTML("This data is....<br>Please, be careful with..."),
            type = "warning",
            html = TRUE
          )
          
        }else{
          show_alert(
            title = "OK",
            text = "You don't have to do anything",
            type = "success"
          )
        }
      })
      
      observeEvent(input$type,{
        feedbackWarning(inputId = "type",
                        show = ("data2" %in% input$type),
                        text ="This data is... Please, be careful..."
        )
      })
      
      mydata <- reactive({
        if(input$type == "data1"){
          mtcars
        }else{
          iris
        }
        
      }) %>% bindEvent(input$button)
      
      output$table <- renderDataTable(mydata())
    }
    
    if (interactive())
      shinyApp(ui, server)
    
    shinyApp(ui, server)