Relating HTML/JavaScript and server.R

As it was mentioned earlier, one of the biggest advantages of customizing the application UI by just adding tags to UI.R becomes even more visible when the user interface elements (HTML, JavaScript, and so on) depend on reactive values too. This case of reactivity is definitely different from the ones seen so far as the output should be included as HTML code, especially when it comes to JavaScript. For this kind of situation, session$sendCustomMessage() along with a built-in JavaScript function, Shiny.addCustomMessageHandler(), have to be used.

Basically, the first function sends a message to the user interface that will be based on reactive inputs. The second function listens to this and acts accordingly. Considering the JavaScript example again, the following code produces an application where if the input variable (input$number) is less than or equal to 25, the mouseover/mouseout colors will be blue or gray respectively, while if the input value is greater than 25, the color pair will be red/green.

As you might have already noticed, these kinds of customizations need to be similar to the update functions, the invocation of a session object. This object contains by default sendCustomMessage(). This function has two arguments: type and the values to be passed to UI.R. This last argument is packed in a JSON format and delivered to the handler, which can perform the JavaScript operations based on this. The following is the code for this in server.R:

library(shiny)

#initialization of server.R
shinyServer(function(input, output,session) {

  observe({
    input$number
    colorover <- ifelse(input$number <= 25,"blue","red")
    colorout <- ifelse(input$number <= 25,"gray","green")
    session$sendCustomMessage(type='updatecolors', list(over=colorover,out =colorout))
  })
  
  #Plot generation
  output$plot <- renderPlot({
    plot(1/1:input$number)
  })

})

In the following UI.R code, Shiny.addCustomMessageHandler() is passed as an inline script but it can be included in any of the ways described in this chapter. Shiny.addCustomMessageHandler() receives two parameters:

  • Firstly, a string that defines the type (that is, the type specified in the corresponding session$sendCustomMessage() on the server side)
  • Secondly, a function where the output produced on the server side can be included within a JavaScript code.

As it was already explained, the objects generated by session$sendCustomMessage() are passed to UI as a JSON object. For this reason, the call is done as function_argument.value. The name of this argument in the function passed to Shiny.addCustomMessageHandler() can be anything. This is the name that the object that is returned on the server side will acquire in the UI.

The following is the UI.R script:

library(shiny)

# Starting line
shinyUI(bootstrapPage(
  
  tags$head(tags$script(src="change_color.js")),
  
  tags$head(tags$script(HTML(
    ' var colorover;
    var colorout ;
    Shiny.addCustomMessageHandler("updatecolors",
    function(color) { colorover= String(color.over);
    colorout= String(color.out)});'
  ))),
  
  # Application title
  titlePanel("Example 1"),
  
  # Sidebar with a numeric input
  # Sidebar
  sidebarLayout(
    sidebarPanel(
      onmouseover = 'changeColor(this,colorover)',
      onmouseout = 'changeColor(this,colorout)',
      style = "background-color: green;",
      numericInput("number",
      "Insert a number:",
      value = 30,
      min = 1,
      max = 50)),
    
    
    #The plot created in server.R is displayed
    mainPanel(
      plotOutput("plot")
    )
  )
))

In this example, two variables were created to store the color value that will be passed afterwards to changeColor(), the same function that was created for the previous example. The values of these variables are updated by Shiny.addCustomMessageHandler() based on the output received from the server.

The calls to the arguments of changeColor(), onmouseover and onmouseout, change only in their second argument where, instead of having a fixed string, colorover and colorout is passed to them respectively. The JavaScript variables in this case have to be declared outside Shiny.addCustomMessageHandler() due to scope as, similar to R, the variables declared inside a function cannot be called from outside.

With these two scripts plus change_color.js from the previous example, it should be enough to generate an application where, if input$number is greater than 25, the input panel should be either red or green (depending on whether the cursor is inside the box or not), or gray or blue if input$number is less than or equal to 25.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset