我有一个闪亮的服务器版本0.4.0,我希望有4个小的textInput框看起来像这样:
x-min x-max y-min y-max
[...] [...] [...] [...]
他们现在看起来像这样:
x-min
[...................]
x-max
[...................]
y-min
[...................]
y-max
[...................]
使用此代码:
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),
任何想法如何实现这一目标?
编辑:我在代码的其他地方成功地改变了这样的事情:
<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">
这就是那些不起作用的东西:
<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"/>
编辑:
以下是一个不起作用的自包含示例ui.R
:
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; }"))
)
))
结果页面:
答案 0 :(得分:105)
解释(并简化为2个输入的情况),你的问题是:
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) {}
))
显示
但是你想要并排的小输入,如下:
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) {}
))
给出:
让我们先并肩做:
目前textInput会生成两个单独的标记 - label
和input
,每个标记都由CSS配置为display:block
,这意味着它是一个向左突破的矩形容器的一面。我们需要将每个textInput
的字段包装在新容器(div)中,并告诉该容器允许其后面的容器(下一个textInput
)位于页面上的同一水平行上,使用CSS的display:inline-block
。
因此,我们在每个textInput
周围添加一个样式的div:
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) {}
))
现在让我们处理小事。有几种方法可以做小事,
由于bootstrap.js
在我们使用闪亮时确实可以控制布局,因此只有3个可靠地工作,所以让我们使用它。
输入大小记录在Bootstrap 2.3.2's CSS Forms documentation, under 'Control Sizing'中。它包括各种尺寸,从迷你,小,中,大,xlarge和xxlarge,默认可能是中等。让我们尝试小一点。
要设置尺寸,我们需要更改input
生成的textInput
标记的类。
现在textInput
只是围绕功能更强大的tags
功能的便利功能,例如tags$label
和tags$input
。我们可以构建一个更强大的textInput
版本,允许我们配置元素,特别是input
节点的类:
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) {}
))
我们已经完成了 - 但是我们可以通过让textInput3
生成div标签来推动其中的一些功能。它也可以自己设置类,但我会留给你写。
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) {}
))
为了感兴趣,这是使用类input-mini
的版本:
答案 1 :(得分:52)
使用最新版本的Shiny,您可以通过将输入调用放在splitLayout()中来实现此目的。这会将流体行,框等分成必要的列,以便并排显示输入字段。
以下示例将在一个框中为您提供三个文本输入,这些输入将在fluidRow中并排显示。
fluidRow(
box(width = 12, title = "A Box in a Fluid Row I want to Split",
splitLayout(
textInput("inputA", "The first input"),
textInput("inputB", "The second input"),
textInput("inputC", "The third input")
)
)
)
答案 2 :(得分:35)
也许这个解决方案在2013年还没有,但是如果你想在不编写HTML或CSS的情况下这样做,你可以在column
中使用fluidRow
函数,如下所示:
< / p>
fluidRow(
column(3,
selectInput('pcat', 'Primary Category', c("ALL", "Some"))),
column(3,
selectInput('smodel', 'Statistical Model', c("NONE", "LINEAR REGRESSION", "LOWESS")))
)
它将把事情并排放置。
编辑:现在有另一种使用splitLayout()
功能的非常简单的方法。有关详细信息,请参阅Nadir Sidi的答案。
答案 3 :(得分:8)
我删除了旧的答案 - 这是有效的:
ui.r:
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(
div(id="XXmin",textInput(inputId="xlimitsmin", label="x-min", value = 0.0)),
tags$head(tags$style(type="text/css", "#XXmin {display: inline-block}")),
tags$head(tags$style(type="text/css", "#xlimitsmin {max-width: 50px}")),
div(id="XXmax",textInput(inputId="xlimitsmax", label="x-max", value = 0.5)),
tags$head(tags$style(type="text/css", "#XXmax {display: inline-block}"),
tags$head(tags$style(type="text/css", "#xlimitsmax {max-width: 50px}"))
))
))
以下是我所做的更改:
1)我在select
陈述中删除了select#xlimitsmax
和select#xlimitsmin
中的.css
2)我将两个控件分别放在他们自己的div()
中,并为他们命名XXmin
和XXmax
。然后我添加了.css
语句以使它们成为内联块。
如果你有很多这样的话,你可能想要使用class
语句 - 例如:
div(class="MyClass",textInput(inputId="xlimitsmin", label="x-min", value = 0.0)),
tags$head(tags$style(type="text/css", ".MyClass {display: inline-block}")),
tags$head(tags$style(type="text/css", "#xlimitsmin {max-width: 50px}")),
然后您可以将每个控件div()
标记为class="MyClass"
并仅使用一个.css
语句。
编辑添加:感谢您发布示例代码 - 这使得它变得更加容易。
第二编辑:只是为了澄清。将textInput
命令放在div()
中的目的是将输入框及其标签合并为一个对象,以便可以应用样式(在本例中为display
样式)。如果你不这样做,标签和盒子就像两个独立的实体一样,在这种情况下很难操纵它们。
答案 4 :(得分:6)
作为在类中放置详细样式声明的替代方法,您似乎可以根据自己的喜好轻松扩展闪亮标记函数。默认情况下,这个特别的方便。 (这是闪亮的shiny_0.14.1)。我以为我需要编写一个闭包,但这似乎有效。
inline = function (x) {
tags$div(style="display:inline-block;", x)
}
inline(textInput(inputId="xlimitsmin", label="x-min", value = 0.0)),
inline(textInput(inputId="xlimitsmax", label="x-max", value = 0.5)),
inline(textInput(inputId="ylimitsmin", label="y-min", value = 0.5)),
inline(textInput(inputId="ylimitsmax", label="y-max", value = 1.0)),
答案 5 :(得分:2)
如果您想要mainPanel中的输入,可以使用以下内容:
div(class="row-fluid",
div(class="span1",textInput("xlimitsmin", label = "x-min", value = 0.0)),
div(class="span1",textInput("xlimitsmax", label = "x-max", value = 0.5)),
div(class="span1",textInput("ylimitsmin", label = "y-min", value = 0.5)),
div(class="span1",textInput("ylimitsmax", label = "y-max", value = 1.0))
)
添加:
#xlimitsmin, #xlimitsmax, #ylimitsmin, #ylimitsmax {
max-width: 25px;
}
在您的应用中的css文件(例如,www /目录中的style.css)中,并使用以下命令从ui.R中获取:
includeCSS( 'WWW / style.R')
我不确定为什么你需要textInput而不是numericInput,因为你似乎要寻找的输入是数字。如果选择numericInput,则可以简单地将textInput替换为上面的numericInput。如果您想要sidebarPanel中的输入,您可以使用下面的代码。需要上面提到的css文件。
div(class="row-fluid",
div(class="span3",numericInput("xlimitsmin", label = "x-min", value = 0.0)),
div(class="span3",numericInput("xlimitsmax", label = "x-max", value = 0.5)),
div(class="span3",numericInput("ylimitsmin", label = "y-min", value = 0.5)),
div(class="span3",numericInput("ylimitsmax", label = "y-max", value = 1.0))
)
答案 6 :(得分:0)
我对splitLayout()
不满意,因为当空间有限时,它会引入滚动条。
我发现,至少对于按钮或文本框之类的输入小部件而言,一种具有较好响应行为的相当简单的解决方案是使用flex-box :(请参见本实用指南:https://css-tricks.com/snippets/css/a-guide-to-flexbox/)
div(
style = "display: flex; flex-wrap: wrap;",
div(
style = "flex: 1;",
textInput("inputA", "The first input")
),
div(
style = "flex: 1;",
textInput("inputB", "The second input")
),
div(
style = "flex: 1;",
textInput("inputC", "The third input")
)
)
可以调整相对宽度。对应于splitLayout(cellWidths = c("25%", "75%"), ...)
:
div(
style = "display: flex; flex-wrap: wrap;",
div(
style = "flex: 1;",
textInput("inputA", "The first input")
),
div(
style = "flex: 3;", # second item 3 times as wide as first one
textInput("inputB", "The second input")
)
)
答案 7 :(得分:0)
Sgrubsmyon的方法对我来说几乎是完美的,但是我在flex-box方法中遇到了一个新问题,因为输入之间没有填充。显然,这与“ display:flex”有关,后者是“ flex-grow 1”的包装,它占用了所有可用空间。我钻进了兔子洞,无法解决这个问题,但是了解了一种类似的方法,该方法使用“ CSS-Grid”,并且更加简单(relevant SO question where I learnt this from):
div(
style = "display: grid;
grid-template-columns: 20% repeat(3, 20%); ## same as repeat(4, 20%)
grid-gap: 10px;",
textInput("inputA", "The first input"),
textInput("inputB", "The second input"),
textInput("inputC", "The third input"),
textInput("inputD", "The fourth input")
)
位于here的CSS-Grid方法也有类似的出色指南,您可以在其中了解可以使用的所有不同参数和可定制性。请注意,直到编写此答案之前2个小时我才接触过CSS,因此欢迎进行任何更正=)