闪亮的4个小文本输入框并排


77

我有一个闪亮的服务器版本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; }"))
    )
))

结果页面:

在此处输入图片说明


您的<style>语句在代码中的何处?如果您只是做类似更改选择框颜色的操作,那行得通吗?
约翰·保罗

样式声明分散在闪亮的ui.R文件中,并放在html head(tags$head(tags$style(type="text/css", "select#something { height: 200px; width: 300px; }")))中。如果我执行以下操作,仍然无法正常工作:tags$head(tags$style(type="text/css", "select#xlimitsmin { max-width: 50px }"))
719016 2014年

平安!6小时内提供赏金-您能分配给某人吗?
亚历克斯·布朗

1
还剩16个小时吗?明天我会在12小时后回办公室尝试。
719016 2014年

Answers:


121

释义(并简化为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

因此,我们在每个div周围添加一个样式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) {}
))

行

小投入

现在让我们来处理小问题。有几种做小事情的方法,

  1. 缩小字体,
  2. 使输入框中的字符更少。
  3. 告诉CSS或(这里)引导程序绘制一个较小的框

因为bootstrap.js当我们使用光亮效果时实际上可以控制布局,所以只有3个可以可靠地起作用,所以让我们使用它。

输入大小记录在Bootstrap 2.3.2的CSS Forms文档中的“控件大小”下。它包括mini,small,medium,large,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) {}
))

出于兴趣的考虑,这是使用class的版本input-mini

在此处输入图片说明


90

使用Shiny(> = 0.11),可以通过将输入调用放在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")
      )
  )
)

17
+1,splitLayout还允许您自定义每个单个单元格的宽度;splitLayout(cellWidths = c(“ 25%”,“ 75%”),plotOutput(“ plot1”),plotOutput(“ plot2”))
ZN13

6
现在这应该是公认的答案,这正是OP的追求。
乔里斯·梅斯

5
而且功能box来自shinydashboard软件包
needRhelp

这比接受的答案容易得多,谢谢纳迪尔。
鲍勃

40

也许该解决方案在2013年就不存在了,但是如果您想在不编写HTML或CSS的情况下执行此操作,则可以column在一个fluidRow类似的内部使用该函数:

  fluidRow(
    column(3,
    selectInput('pcat', 'Primary Category', c("ALL", "Some"))),
    column(3,
    selectInput('smodel', 'Statistical Model', c("NONE", "LINEAR REGRESSION", "LOWESS")))
  )

它将并排放置。

编辑:现在有使用该splitLayout()函数执行此操作的另一种非常简单的方法。有关更多详细信息,请参见Nadir Sidi的答案。


6
谢谢!这使我免于头痛,幸运的是,我向下滚动答案,这很可能是做到这一点的最佳方法。
nico

我也喜欢这个解决方案。如果您有下拉菜单,splitLayout会引入滚动条,这对于此类输入来说非常不足。但是使用专栏,效果很好!
JReddig

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)我在消除selectselect#xlimitsmaxselect#xlimitsmin你的.css声明中

2)我将您的两个控件分别放在各自的位置,div()并给它们命名为XXminXXmax。然后我加了.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命令放在a内的目的div()是将输入框及其标签组合到一个对象中,以便可以应用样式(在这种情况下为display样式)。如果您不这样做,则标签和框将充当两个单独的实体,在这种情况下很难操作它们。


8

作为在类中添加冗长的样式声明的替代方法,似乎您可以轻松地根据自己的喜好扩展闪亮的标签函数。默认情况下,这种特殊的设置很方便。(这是带有光泽的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)),

我喜欢这个答案,这可能有助于解决其他问题。谢谢
约翰·罗莎

实际上,这是我摆脱不必要的水平滚动条的唯一方法。谢谢!
Brunox13

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))
)

2

我不满意,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")
  )
)

0

Sgrubsmyon的方法对我来说几乎是完美的,但是我在flex-box方法中遇到了一个新问题,因为输入之间没有填充。显然,这与“ display:flex”有关,后者是“ flex-grow 1”的包装,它占用了所有可用空间。我钻进了兔子洞,无法使它正常工作,但了解了一种类似的方法,该方法使用“ CSS-Grid”并且更加简单(相关的SO问题是我从中学到的)

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")

)

CSS-Grid方法也有类似的出色指南,您可以在此处了解可使用的所有不同参数和可定制性。请注意,直到编写此答案之前2个小时我才接触过CSS,因此欢迎进行任何更正=)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.