I've got a shiny server version 0.4.0 and I want to have 4 small textInput boxes to look like this:
x-min x-max y-min y-max
[...] [...] [...] [...]
They now look like this:
x-min
[...................]
x-max
[...................]
y-min
[...................]
y-max
[...................]
With this code:
textInput(inputId="xlimitsmin", label="x-min", value = 0.0),
textInput(inputId="xlimitsmax", label="x-max", value = 0.5),
textInput(inputId="ylimitsmin", label="y-min", value = 0.5),
textInput(inputId="ylimitsmax", label="y-max", value = 1.0),
Any ideas how to achieve this?
EDITED: I've successfully changed things like this elsewhere in the code:
<style type="text/css">select#yaxis4 { height: 280px; width: 500px; }</style>
[... which links to this later on in the page...]
<label class="control-label" for="yaxis4">Y-Axis</label>
<select id="yaxis4" multiple="multiple">
And this is what it looks like for the ones that don't work:
<style type="text/css">select#xlimitsmax { display: inline-block; max-width: 50px; }</style>
[... which links to...]
<label>x-max</label>
<input id="xlimitsmax" type="text" value="0.5"/>
EDITED:
Here is a self contained example ui.R
that doesn't work:
library(shiny)
shinyUI(
pageWithSidebar(
# application title
headerPanel("test01"),
sidebarPanel(
tags$head(
tags$style(type="text/css", "select { max-width: 360px; }"),
tags$style(type="text/css", ".span4 { max-width: 360px; }"),
tags$style(type="text/css", ".well { max-width: 360px; }")
),
wellPanel(
p(strong("Side Panel:"))
)
),
mainPanel(
textInput(inputId="xlimitsmin", label="x-min", value = 0.0),
tags$head(tags$style(type="text/css", "select#xlimitsmin { max-width: 50px }")),
textInput(inputId="xlimitsmax", label="x-max", value = 0.5),
tags$head(tags$style(type="text/css", "select#xlimitsmax { display: inline-block; max-width: 50px; }"))
)
))
Resulting page:
to paraphrase (and to simplify to the case of 2 inputs), your problem is that:
runApp(list(
ui = bootstrapPage(
textInput(inputId="xlimitsmin", label="x-min", value = 0.0),
textInput(inputId="xlimitsmax", label="x-max", value = 0.5)
),
server = function(input, output) {}
))
shows
But you want side-by-side small inputs, like so:
textInputRow<-function (inputId, label, value = "")
{
div(style="display:inline-block",
tags$label(label, `for` = inputId),
tags$input(id = inputId, type = "text", value = value,class="input-small"))
}
runApp(list(
ui = bootstrapPage(
textInputRow(inputId="xlimitsmin", label="x-min", value = 0.0),
textInputRow(inputId="xlimitsmax", label="x-max", value = 0.5)
),
server = function(input, output) {}
))
gives:
Let's do side-by-side first:
Currently textInput generates two separate tags - the label
, and the input
, each of which is configured by CSS as display:block
, which means it's a rectangle that will break to the left side of the container. We need to wrap each textInput
's field in new container (div) and tell that container that the container that follows it (the next textInput
) is allowed to be on the same horizontal row on the page, using CSS's display:inline-block
.
So we add a div with a style around each textInput
:
runApp(list(
ui = bootstrapPage(
div(style="display:inline-block",textInput(inputId="xlimitsmin", label="x-min", value = 0.0)),
div(style="display:inline-block",textInput(inputId="xlimitsmax", label="x-max", value = 0.5))
),
server = function(input, output) {}
))
Now let's deal with small. There are a few ways to do small,
Since bootstrap.js
is really in control of layout when we use shiny, only 3 will reliably work, so let's use that.
Input sizes are documented in Bootstrap 2.3.2's CSS Forms documentation, under 'Control Sizing'. It includes a variety of sizes from mini, small, medium, large, xlarge, and xxlarge, and the default is probably medium. Let's try small, instead.
To set the size, we need to change the class of the input
tag generated by textInput
.
Now textInput
is just a convenience function around the more powerful tags
functions such as tags$label
and tags$input
. We can build a more powerful version of textInput
that allows us to configure the elements, specifically the class of the input
node:
textInput2<-function (inputId, label, value = "",...)
{
tagList(tags$label(label, `for` = inputId), tags$input(id = inputId,
type = "text", value = value,...))
}
runApp(list(
ui = bootstrapPage(
div(style="display:inline-block",textInput2(inputId="xlimitsmin", label="x-min", value = 0.0, class="input-small")),
div(style="display:inline-block",textInput2(inputId="xlimitsmax", label="x-max", value = 0.5, class="input-small"))
),
server = function(input, output) {}
))
And we are done - but we can roll some of this functionality up by having textInput3
generate the div tag. It could also set the class by itself, but I'll leave that for you to write.
textInput3<-function (inputId, label, value = "",...)
{
div(style="display:inline-block",
tags$label(label, `for` = inputId),
tags$input(id = inputId, type = "text", value = value,...))
}
runApp(list(
ui = bootstrapPage(
textInput3(inputId="xlimitsmin", label="x-min", value = 0.0, class="input-small"),
textInput3(inputId="xlimitsmax", label="x-max", value = 0.5, class="input-small")
),
server = function(input, output) {}
))
For interest's sake, here's the version using class input-mini
: