Boris Nikolov
Boris Nikolov

Reputation: 65

Shiny timepicker

I would like to implement a timepicker and dateInput in my Shiny app. However, I did not manage to create a proper timepicker. I tried different options - using the one from http://jdewit.github.io/bootstrap-timepicker/ but if I include the raw html with includeHTML("file.html") the style is not displayed correctly, I can only see one small box. I downloaded the Bower package, changed the paths in the HTML, still nothing.

Here is my Shiny code:

shinyUI(bootstrapPage(
  titlePanel("Dates and date ranges"),

  column(4, wellPanel(


    dateRangeInput('dates',
                   label = 'Date range input: yyyy-mm-dd',
                   start = "2015-03-02", end = "2015-03-15",
                   weekstart = 1, language = "en"
    )

  )),

  column(6,
         verbatimTextOutput("dateRangeText"),
         plotOutput("distPlot", width = "100%")
  ),
  includeHTML("static.html")
))

And my HTML:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link type="text/css" href="bower_components/bootstrap-timepicker/css/bootstrap.min.css" />
        <link type="text/css" href="bower_components/bootstrap-timepicker/css/bootstrap-timepicker.min.css" />
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
        <script type="text/javascript" src="bower_components/bootstrap-timepicker/js/bootstrap-2.2.2.min.js"></script>
        <script type="text/javascript" src="bower_components/bootstrap-timepicker/js/bootstrap-timepicker.min.js"></script>
    </head>
    <body>
        <div class="input-append bootstrap-timepicker">
            <input id="timepicker2" type="text" class="input-small">
            <span class="add-on">
                <i class="icon-time"></i>
            </span>
        </div>

        <script type="text/javascript">
            $('#timepicker2').timepicker({
                minuteStep: 1,
                template: 'modal',
                appendWidgetTo: 'body',
                showSeconds: true,
                showMeridian: false,
                defaultTime: false
            });
        </script>
    </body>
</html>

I'm not really sure what I'm doing wrong as I am new to JS and Web in general, any suggestions? Or perhaps you can advise me to create the timepicker in an easier way. Thanks in advance!

Regards, Boris

Upvotes: 3

Views: 1473

Answers (1)

amwill04
amwill04

Reputation: 1360

After much scratching of the head I got this working. I scrapped the includeHTML method for tags I find these much easier and I have also scructured this to my own liking, i.e separating the js into a separate file.

File Structure:

--|myApp
     --ui.R
     --server.R
     --|www
           --timepicker.js
           --|bootstrap-timepicker

The reason I have separated this all out is personal choice. If you place a folder called www within your shinyApp you can then source from there any dependancies with www as the root folder. I didn't use bower I simply downloaded the source zip folder from bootstrap-timepicker git page.

THE FILES

timepicker.js

$('#timepicker2').timepicker({
            minuteStep: 1,
            template: 'modal',
            appendWidgetTo: 'body',
            showSeconds: true,
            showMeridian: false,
            defaultTime: false
        });

ui.R

shinyUI(bootstrapPage(
  tags$head(
  tags$link(href="bootstrap-timepicker/css/bootstrap-timepicker.min.css", rel = "stylesheet"),
  tags$script(type="text/javascript", src="bootstrap-timepicker/js/bootstrap-timepicker.min.js")
  ),
  titlePanel("Dates and date ranges"),
  column(4, wellPanel(


    dateRangeInput('dates',
                   label = 'Date range input: yyyy-mm-dd',
                   start = "2015-03-02", end = NULL,
                   weekstart = 1, language = "en"
    )

  )),

  column(6,
         verbatimTextOutput("dateRangeText"),
         plotOutput("distPlot", width = "100%")
  ),
  tags$div(class = "input-group bootstrap-timepicker timepicker",
           tags$input(id = "timepicker2",
                      type = "text",
                      class = "form-control input-small"),
           tags$span(class = "input-group-addon",
                     tags$i(class= "glyphicon glyphicon-time"))),
  tags$script(src = "timepicker.js")
))

Explanation

If you have not explored tags in shiny I recommend them. Extremely powerful withough having to source HTML files. If you wish to just see what they do then copy tags$script(src = "timepicker.js") into your R console and you will get the following:

<script src="timepicker.js"></script> 

They build the HTML for you.

First the two bootstrap-timepicker files are source and placed within tags$head this will make shiny place these into the head of the HTML document.

Next the div for the time picker is built using tags$div before finally sourcing the timepicker.js file. See Should Jquery code go in header or footer? as to why we source the js file last. I am no expert in js so that is how I got it to work.

I suspect the reason why includeHTML does not work is because it is not loading the dependancies correctly.

Upvotes: 5

Related Questions