Action button with html

How do I implement an action button into my html? I am using the server.R and www\index.html way of creating a ui fully with html. Here is what I have right now:

<button class="btn action-button" type='button' id="submit_loc">Start</button>

in index.html, which is meant to be caught in server.R with

server <- function(input, output) {
  observeEvent(input$submit_loc,
               {
                 cat('input detected')
               })
}

However, this doesn't seem to work, with nothing showing in the console when I click the button. Am I missing something?

Hi,

Welcome to the RStudio community!

I think it's not as easy as that. If you want to create custom input bindings, you'll need to do some extra fancy coding in most cases. Have a look at this blog with links:
http://jonkatz2.github.io/2018/09/27/Debugging-Custom-Shiny-Inputs

Hope this helps,
PJ

Here you can find some related infos:
https://shiny.rstudio.com/articles/html-ui.html

Thanks for the reply. I did some more research on my own as well and found this: https://stackoverflow.com/questions/47215230/listen-to-button-events-with-shiny-oninputchange-r-shiny

and have modified my code like so:

index.html:

<button class="btn action-button" type='button' onclick="buttonClicked()" id="submit">Start</button>
<script>
    function submitButton() {
        Shiny.onInputChange("submit_loc", Math.random());
    }
</script>

server.R

server <- function(input, output) {
  observeEvent(input$submit_loc,
               {
                 cat('input detected')
               })
}

From what I understand, this would mean that observeEvent would see that submit_loc value changes, which would then trigger it. However this does not seem to work either, and I am not sure why. This is my first time using Shiny, and R in general, so I am not sure if I am missing something obvious. I found that most examples/questions are based around people using ui.R and not index.html, which is what I think is throwing me off, as in ui.R it seems all you need to do is

actionButton(inputId = "submit_loc",label = h4("START")

You are almost there in the original post. Creating a custom input binding is possible, but could be a bit more work if you need to respond to a button click. To "hook" into the Shiny from vanilla HTML buttons, add the following css class shiny-bound-input action-button. Here's a small example.

www/index.html

<!DOCTYPE html>
<html>
<head>
    <script src="shared/jquery.js" type="text/javascript"></script>
    <script src="shared/shiny.js" type="text/javascript"></script>
    <link rel="stylesheet" type="text/css" href="shared/shiny.css"/>
    <title>HTML Button Test</title>
</head>
<body>
    <main>
        <h1>HTML Button test</h1>
        <p>Click the button.</p>
        <button id="btn" class="shiny-bound-input action-button">
            My Button
        </button>
    </main>
</body>
</html>

app.R

library(shiny)

# server: print a message when the button is clicked
server <- function(input, output) {
    observeEvent(input$btn, {
        print("button clicked")
    })
}

# load template
shinyApp(ui = htmlTemplate("www/index.html"), server)

Thanks for your reply! I managed to get my original working with the messy JS (changing the value of a variable and detecting that) but your way is far cleaner. I saw somewhere that I needed action-button in class but I didn't know about shiny-bound-input, I will try that.

Do you happen to have a link to some documentation about things like shiny-bound-input? It seems like this method of using index.html over ui.R isn't very popular and I've been having some struggles trying to get it to work.

Thanks, I hope it works out for you!

Unfortunately, I'm not aware of any documentation on Shiny CSS classes. The Shiny docs used to print the HTML markup (which is where I found out about css classes like shiny-bound-input), but it may be easier to create a Shiny app with the elements that you would like to replicate in HTML, and then inspect the HTML markup.

Right, that makes sense. This is my first time using Shiny so I wanted to create my front end with something I was more familiar with, though from now on I will probably learn the ui.R syntax as support and docs seem much more extensive that way.

That's great! You may be interested in the htmltools package. The tags object allows you to build UIs in a similar method as HTML documents (the tags object is also available via the shiny package). For example, if you wanted to rewrite the index.html file in R using tags, it would look like this.

library(shiny)

ui <- tagList(
    tags$head(
        tags$title("HTML Button Test")
    ),
    tags$main(
        tags$h1("HTML Button Test"),
        tags$p("Click the button."),
        tags$button(
            id = "btn",
            class = "shiny-bound-input action-button",
            "My Button"
        ) 
    )
)

You wouldn't need to add the shared assets as this is handled by Shiny. Unlike HTML markup, you generating the <body> element (i.e, tags$body) isn't required and handled automatically by Shiny. Doing so will render a nested <body> element :grimacing:

Hope that helps!

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.