Подтвердить что ты не робот

Блестящий 4 маленьких текстовых поля бок о бок

У меня есть блестящая версия сервера 0.4.0, и я хочу иметь 4 маленьких окна ввода текста, чтобы выглядеть так:

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

Любые идеи, как достичь этого?

EDITED: я успешно изменил такие вещи, как это происходит в другом месте кода:

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

Результирующая страница:

enter image description here

4b9b3361

Ответ 1

чтобы перефразировать (и для упрощения в случае двух входов), ваша проблема в том, что:

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

показывает

enter image description here

Но вам нужны небольшие боковые стороны, например:

small row

Короткий ответ

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

дает:

enter image description here

Длинный ответ

Боковые входы

Сначала сделайте бок о бок:

В настоящее время 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) {}
))

row

Малые входы

Теперь давайте поговорим о маленьком. Есть несколько способов сделать небольшой,

  • уменьшить шрифт,
  • сделать поле ввода меньше символов в нем.
  • скажите css или (здесь) bootstrap, чтобы нарисовать меньший ящик.

Так как bootstrap.js действительно контролирует макет, когда мы используем блестящий, только 3 будет надежно работать, поэтому давайте использовать его.

Размеры ввода задокументированы в Bootstrap 2.3.2. Документация по CSS-форматам в разделе "Размер управления" . Он включает в себя различные размеры от мини, малый, средний, большой, xlarge и xxlarge, а по умолчанию - средний. Попробуйте вместо этого попробовать.

Чтобы установить размер, нам нужно изменить класс тега input, сгенерированный textInput.

Теперь textInput - это просто удобная функция вокруг более мощных функций tags, таких как tags$label и tags$input. Мы можем создать более мощную версию textInput, которая позволяет нам настраивать элементы, в частности класс 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) {}
))

small row

И мы закончили - но мы можем свернуть некоторые из этих функций, создав 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:

enter image description here

Ответ 2

Используя последнюю версию 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")
      )
  )
)

Ответ 3

Возможно, этого решения не было в 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(). Смотрите ответ Надир Сиди для более подробной информации.

Ответ 4

Я удалил старый ответ - вот что работает:

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.

Отредактировано для добавления: Спасибо за публикацию кода примера - это сделало его намного проще.

2nd Edit: Просто уточнить. Точка ввода команд textInput внутри div() заключается в объединении поля ввода и его метки в один объект, чтобы можно было применить стили (в данном случае стиль display). Если вы этого не сделаете, ярлык и ящик действуют как два отдельных объекта, и их труднее манипулировать в таких случаях.

Ответ 5

В качестве альтернативы размещению многословных деклараций стиля в классе кажется, что вы можете легко расширить функции блестящих тегов по своему вкусу. Этого было бы удобно по умолчанию. (это с блестящим 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)),

Ответ 6

Если вам нужны входы в 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 (например, style.css в каталоге www/) в вашем приложении и введите его из 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))
)

Ответ 7

Я не был счастлив с splitLayout() потому что он вводит полосы прокрутки, когда пространство ограничено.

Я обнаружил, что, по крайней мере, для виджетов ввода, таких как кнопки или текстовые поля, довольно простое решение с лучшим поведением реагирования использует flex-box: (см. Это великолепное руководство: https://css-tricks.com/snippets/css/a -гид-во-флексбокс/)

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

Ответ 8

Подход Sgrubsmyon был почти идеален для меня, однако я столкнулся с новой проблемой с подходом flex-box в том, что между входами не было заполнения. По-видимому, это как-то связано с "display: flex", являющимся оболочкой для "flex-grow 1", который занимает все доступное пространство. Я нырнул в кроличью нору и не смог заставить это работать, но узнал о похожем подходе, который использует "CSS - Grid" и еще проще (соответствующий вопрос о том, откуда я это узнал):

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, расположенного здесь, где вы можете узнать обо всех различных аргументах и настраиваемости, которые вы можете использовать. Обратите внимание, что я никогда не трогал CSS до 2 часов до написания этого ответа, поэтому любые исправления приветствуются =)