Блестящий 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]()
Ответы
Ответ 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 часов до написания этого ответа, поэтому любые исправления приветствуются =)