Spec-Zone.ru › Ruby on Rails 6.1

модуль ActionView::Helpers::FormOptionsHelper

Включенные модули:
ActionView::Helpers::TextHelper

Предоставляет множество методов для преобразования различных типов контейнеров в набор тегов option.

Методы collection_select, select и time_zone_select принимают параметр options, являющийся хэш:

  • :include_blank — устанавливается в значение true или строку подсказки, если первый элемент option в элементе select является пустым. Полезно, если для элемента select не требуется значение по умолчанию.

    select("post", "category", Post::CATEGORIES, { include_blank: true })
    

    может стать:

    <select name="post[category]" id="post_category">
      <option value="" label=" "></option>
      <option value="joke">joke</option>
      <option value="poem">poem</option>
    </select>

    Еще один распространенный случай — тег select для объекта, связанного с belongs_to.

    Пример с @post.person_id => 2:

    select("post", "person_id", Person.all.collect { |p| [ p.name, p.id ] }, { include_blank: 'None' })
    

    может стать:

    <select name="post[person_id]" id="post_person_id">
      <option value="">None</option>
      <option value="1">David</option>
      <option value="2" selected="selected">Eileen</option>
      <option value="3">Rafael</option>
    </select>
  • :prompt — устанавливается в значение true или строку подсказки. Когда элемент select еще не имеет значения, он добавляет option с общей подсказкой — «Пожалуйста, выберите» — или заданной строкой подсказки.

    select("post", "person_id", Person.all.collect { |p| [ p.name, p.id ] }, { prompt: 'Select Person' })
    

    может стать:

    <select name="post[person_id]" id="post_person_id">
      <option value="">Select Person</option>
      <option value="1">David</option>
      <option value="2">Eileen</option>
      <option value="3">Rafael</option>
    </select>
  • :index — как и другие вспомогательные методы для форм, select может принимать параметр :index для ручного задания ID, используемого в результирующем выводе. В отличие от других вспомогательных методов, select ожидает, что этот параметр будет в параметре html_options.

    select("album[]", "genre", %w[rap rock country], {}, { index: nil })
    

    становится:

    <select name="album[][genre]" id="album__genre">
      <option value="rap">rap</option>
      <option value="rock">rock</option>
      <option value="country">country</option>
    </select>
  • :disabled — может быть одним значением или массивом значений, которые будут отключенными option в конечном выводе.

    select("post", "category", Post::CATEGORIES, { disabled: 'restricted' })
    

    может стать:

    <select name="post[category]" id="post_category">
      <option value="joke">joke</option>
      <option value="poem">poem</option>
      <option disabled="disabled" value="restricted">restricted</option>
    </select>

    Когда используется вспомогательный метод collection_select, :disabled также может быть методом Proc, который определяет те option, которые должны быть отключены.

    collection_select(:post, :category_id, Category.all, :id, :name, { disabled: -> (category) { category.archived? } })
    

    Если категории «2008 stuff» и «Christmas» возвращают true при вызове метода archived?, это вернет:

    <select name="post[category_id]" id="post_category_id">
      <option value="1" disabled="disabled">2008 stuff</option>
      <option value="2" disabled="disabled">Christmas</option>
      <option value="3">Jokes</option>
      <option value="4">Poems</option>
    </select>

Публичные методы экземпляров

collection_check_boxes(object, method, collection, value_method, text_method, options = {}, html_options = {}, &block) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 756
def collection_check_boxes(object, method, collection, value_method, text_method, options = {}, html_options = {}, &block)
  Tags::CollectionCheckBoxes.new(object, method, self, collection, value_method, text_method, options, html_options).render(&block)
end

Возвращает теги чекбоксов для коллекции существующих возвращаемых значений method для класса object. Значение, возвращаемое при вызове method на экземпляре object, будет выбрано. Если вызов method возвращает nil, выбор не производится.

Параметры :value_method и :text_method — это методы, которые нужно вызывать для каждого элемента коллекции collection. Возвращаемые значения используются в качестве атрибута value и содержимого каждого тега чекбокса соответственно. Они также могут быть любым объектом, который отвечает на вызов call, например, proc, который вызывается для каждого элемента коллекции collection для получения значения/текста.

Пример структуры объекта для использования с этим методом:

class Post < ActiveRecord::Base
  has_and_belongs_to_many :authors
end
class Author < ActiveRecord::Base
  has_and_belongs_to_many :posts
  def name_with_initial
    "#{first_name.first}. #{last_name}"
  end
end

Пример использования (выбор связанного автора для экземпляра Post, @post):

collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial)

Если @post.author_ids уже [1], это вернёт:

<input id="post_author_ids_1" name="post[author_ids][]" type="checkbox" value="1" checked="checked" />
<label for="post_author_ids_1">D. Heinemeier Hansson</label>
<input id="post_author_ids_2" name="post[author_ids][]" type="checkbox" value="2" />
<label for="post_author_ids_2">D. Thomas</label>
<input id="post_author_ids_3" name="post[author_ids][]" type="checkbox" value="3" />
<label for="post_author_ids_3">M. Clark</label>
<input name="post[author_ids][]" type="hidden" value="" />

Также можно настроить отображение элементов, передав блок методу:

collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
  b.label { b.check_box }
end

Аргументом, передаваемым в блок, является специальный вид билдера для этой коллекции, который способен сгенерировать метку и чекбокс для текущего элемента в коллекции с соответствующим текстом и значением. С его помощью можно изменить порядок отображения метки и чекбокса, или даже использовать метку в качестве обертки, как в приведённом выше примере.

Методы билдера label и check_box также принимают дополнительные HTML-параметры:

collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
  b.label(class: "check_box") { b.check_box(class: "check_box") }
end

Также доступны три специальных метода: object, text и value, которые представляют текущий элемент, его метод получения текста и метода получения значения соответственно. Их можно использовать так:

collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
   b.label(:"data-value" => b.value) { b.check_box + b.text }
end

Деталь

Когда для коллекции чекбоксов не выбран ни один элемент, большинство веб-браузеров не отправят никакого значения.

Например, если у нас есть модель User с полем category_ids и в нашем действии обновления есть следующий код:

@user.update(params[:user])

Если не выбраны никакие category_ids, то можно предположить, что это поле не будет обновлено.

Это возможно благодаря скрытому полю, сгенерированному вспомогательным методом для каждой коллекции чекбоксов. Это скрытое поле имеет такое же имя, как и чекбоксы, со значением по умолчанию.

В редком случае, если вам не нужно это скрытое поле, вы можете передать параметр include_hidden: false вспомогательному методу.

collection_radio_buttons(object, method, collection, value_method, text_method, options = {}, html_options = {}, &block) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 672
def collection_radio_buttons(object, method, collection, value_method, text_method, options = {}, html_options = {}, &block)
  Tags::CollectionRadioButtons.new(object, method, self, collection, value_method, text_method, options, html_options).render(&block)
end

Возвращает теги радиокнопок для коллекции существующих возвращаемых значений method для класса object. Значение, возвращаемое при вызове method на экземпляре object, будет выбрано. Если вызов method возвращает nil, выбор не производится.

Параметры :value_method и :text_method — это методы, которые нужно вызывать для каждого элемента коллекции collection. Возвращаемые значения используются в качестве атрибута value и содержимого каждого тега радиокнопки соответственно. Они также могут быть любым объектом, который отвечает на вызов call, например, proc, который вызывается для каждого элемента коллекции collection для получения значения/текста.

Пример структуры объекта для использования с этим методом:

class Post < ActiveRecord::Base
  belongs_to :author
end
class Author < ActiveRecord::Base
  has_many :posts
  def name_with_initial
    "#{first_name.first}. #{last_name}"
  end
end

Пример использования (выбор связанного автора для экземпляра Post, @post):

collection_radio_buttons(:post, :author_id, Author.all, :id, :name_with_initial)

Если @post.author_id уже 1, это вернёт:

<input id="post_author_id_1" name="post[author_id]" type="radio" value="1" checked="checked" />
<label for="post_author_id_1">D. Heinemeier Hansson</label>
<input id="post_author_id_2" name="post[author_id]" type="radio" value="2" />
<label for="post_author_id_2">D. Thomas</label>
<input id="post_author_id_3" name="post[author_id]" type="radio" value="3" />
<label for="post_author_id_3">M. Clark</label>

Также можно настроить отображение элементов, передав блок методу:

collection_radio_buttons(:post, :author_id, Author.all, :id, :name_with_initial) do |b|
  b.label { b.radio_button }
end

Аргументом, передаваемым в блок, является специальный вид билдера для этой коллекции, который способен сгенерировать метку и радиокнопку для текущего элемента в коллекции с соответствующим текстом и значением. С его помощью можно изменить порядок отображения метки и радиокнопки, или даже использовать метку в качестве обертки, как в приведённом выше примере.

Методы билдера label и radio_button также принимают дополнительные HTML-параметры:

collection_radio_buttons(:post, :author_id, Author.all, :id, :name_with_initial) do |b|
  b.label(class: "radio_button") { b.radio_button(class: "radio_button") }
end

Также доступны три специальных метода: object, text и value, которые представляют текущий элемент, его метод получения текста и метода получения значения соответственно. Их можно использовать так:

collection_radio_buttons(:post, :author_id, Author.all, :id, :name_with_initial) do |b|
   b.label(:"data-value" => b.value) { b.radio_button + b.text }
end

Деталь

Спецификация HTML гласит, что когда ничего не выбрано в коллекции радиокнопок, веб-браузеры не отправляют никакого значения серверу. К сожалению, это создаёт проблему: если модель User имеет поле category_id, и в форме не выбрана никакая категория, параметр category_id не отправляется. Поэтому любой идиом сильных параметров, например:

params.require(:user).permit(...)

вызовет ошибку, так как параметр {user: ...} не будет присутствовать.

Для предотвращения этого вспомогательный метод генерирует дополнительное скрытое поле перед каждой коллекцией радиокнопок. Скрытое поле имеет то же имя, что и радиокнопки, и значение по умолчанию.

В случае, если вы не хотите, чтобы вспомогательный метод генерировал это скрытое поле, вы можете указать параметр include_hidden: false.

collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 202
def collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
  Tags::CollectionSelect.new(object, method, self, collection, value_method, text_method, options, html_options).render
end

Возвращает теги <select> и <option> для коллекции существующих возвращаемых значений method для класса object. Значение, возвращаемое при вызове method на экземпляре object, будет выбрано. Если вызов method возвращает nil, выбор не производится, если не включён :prompt или :include_blank в хеш options.

Параметры :value_method и :text_method — это методы, которые нужно вызывать для каждого элемента коллекции collection. Возвращаемые значения используются в качестве атрибута value и содержимого каждого тега <option> соответственно. Они также могут быть любым объектом, который отвечает на вызов call, например, proc, который вызывается для каждого элемента коллекции collection для получения значения/текста.

Пример структуры объекта для использования с этим методом:

class Post < ActiveRecord::Base
  belongs_to :author
end

class Author < ActiveRecord::Base
  has_many :posts
  def name_with_initial
    "#{first_name.first}. #{last_name}"
  end
end

Пример использования (выбор связанного автора для экземпляра Post, @post):

collection_select(:post, :author_id, Author.all, :id, :name_with_initial, prompt: true)

Если @post.author_id уже 1, это вернёт:

<select name="post[author_id]" id="post_author_id">
  <option value="">Please select</option>
  <option value="1" selected="selected">D. Heinemeier Hansson</option>
  <option value="2">D. Thomas</option>
  <option value="3">M. Clark</option>
</select>
grouped_collection_select(object, method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 262
def grouped_collection_select(object, method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {})
  Tags::GroupedCollectionSelect.new(object, method, self, collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options).render
end

Возвращает теги <select>, <optgroup> и <option> для коллекции существующих возвращаемых значений method для класса object. Значение, возвращаемое при вызове method на экземпляре object, будет выбрано. Если вызов method возвращает nil, выбор не производится, если не включён :prompt или :include_blank в хеш options.

Параметры:

  • object - Экземпляр класса, используемый для тега select

  • method - Атрибут object соответствующий тегу select

  • collection - Массив объектов, представляющих теги <optgroup>.

  • group_method - Имя метода, который, когда вызывается для элемента collection, возвращает массив дочерних объектов, представляющих теги <option>. Он также может быть любым объектом, который отвечает на вызов call, например, proc, который вызывается для каждого элемента collection для получения значения.

  • group_label_method - Имя метода, который, когда вызывается для элемента collection, возвращает строку, используемую в качестве атрибута label для его тега <optgroup>. Он также может быть любым объектом, который отвечает на вызов call, например, proc, который вызывается для каждого элемента collection для получения метки.

  • option_key_method - Имя метода, который, когда вызывается для дочернего объекта элемента collection, возвращает значение, используемое в качестве атрибута value для его тега <option>.

  • option_value_method - Имя метода, который, когда вызывается для дочернего объекта элемента collection, возвращает значение, используемое в качестве содержимого его тега <option>.

Пример структуры объекта для использования с этим методом:

class Continent < ActiveRecord::Base
  has_many :countries
  # attribs: id, name
end

class Country < ActiveRecord::Base
  belongs_to :continent
  # attribs: id, name, continent_id
end

class City < ActiveRecord::Base
  belongs_to :country
  # attribs: id, name, country_id
end

Пример использования:

grouped_collection_select(:city, :country_id, @continents, :countries, :name, :id, :name)

Возможный вывод:

<select name="city[country_id]" id="city_country_id">
  <optgroup label="Africa">
    <option value="1">South Africa</option>
    <option value="3">Somalia</option>
  </optgroup>
  <optgroup label="Europe">
    <option value="7" selected="selected">Denmark</option>
    <option value="2">Ireland</option>
  </optgroup>
</select>
grouped_options_for_select(grouped_options, selected_key = nil, options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 530
def grouped_options_for_select(grouped_options, selected_key = nil, options = {})
  prompt  = options[:prompt]
  divider = options[:divider]

  body = "".html_safe

  if prompt
    body.safe_concat content_tag("option", prompt_text(prompt), value: "")
  end

  grouped_options.each do |container|
    html_attributes = option_html_attributes(container)

    if divider
      label = divider
    else
      label, container = container
    end

    html_attributes = { label: label }.merge!(html_attributes)
    body.safe_concat content_tag("optgroup", options_for_select(container, selected_key), html_attributes)
  end

  body
end

Возвращает строку тегов <option>, похожих на options_for_select, но обернутых тегами <optgroup>:

grouped_options = [
 ['North America',
   [['United States','US'],'Canada']],
 ['Europe',
   ['Denmark','Germany','France']]
]
grouped_options_for_select(grouped_options)

grouped_options = {
  'North America' => [['United States','US'], 'Canada'],
  'Europe' => ['Denmark','Germany','France']
}
grouped_options_for_select(grouped_options)

Возможный результат:

<optgroup label="North America">
  <option value="US">United States</option>
  <option value="Canada">Canada</option>
</optgroup>
<optgroup label="Europe">
  <option value="Denmark">Denmark</option>
  <option value="Germany">Germany</option>
  <option value="France">France</option>
</optgroup>

Параметры:

  • grouped_options - Принимает вложенный массив или хэш строк. Первое значение служит меткой <optgroup>, а второе значение должно быть массивом опций. Второе значение может быть вложенным массивом пар «текст-значение». Подробнее см. options_for_select.

    Ex. ["North America",[["United States","US"],["Canada","CA"]]]
  • selected_key - Значение, равное атрибуту value для одного из тегов <option>, у которого будет установлен атрибут selected. Примечание: это значение может соответствовать нескольким опциям, так как у вас может быть одинаковая опция в нескольких группах. Тогда каждой будет присвоено значение selected="selected".

Опции:

  • :prompt - устанавливается в true или строку-подсказку. Когда у элемента select еще нет значения, это добавляет опцию с общей подсказкой — «Пожалуйста, выберите» — или заданной строкой-подсказкой.

  • :divider - разделитель для групп опций.

    grouped_options = [
      [['United States','US'], 'Canada'],
      ['Denmark','Germany','France']
    ]
    grouped_options_for_select(grouped_options, nil, divider: '---------')
    

    Возможный результат:

    <optgroup label="---------">
      <option value="US">United States</option>
      <option value="Canada">Canada</option>
    </optgroup>
    <optgroup label="---------">
      <option value="Denmark">Denmark</option>
      <option value="Germany">Germany</option>
      <option value="France">France</option>
    </optgroup>

Примечание: Возвращаются только теги <optgroup> и <option>, поэтому вам все равно необходимо обернуть вывод в соответствующий тег <select>.

option_groups_from_collection_for_select(collection, group_method, group_label_method, option_key_method, option_value_method, selected_key = nil) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 460
def option_groups_from_collection_for_select(collection, group_method, group_label_method, option_key_method, option_value_method, selected_key = nil)
  collection.map do |group|
    option_tags = options_from_collection_for_select(
      value_for_collection(group, group_method), option_key_method, option_value_method, selected_key)

    content_tag("optgroup", option_tags, label: value_for_collection(group, group_label_method))
  end.join.html_safe
end

Возвращает строку тегов <option>, таких как options_from_collection_for_select, но группирует их по тегам <optgroup> на основе отношений объектов в аргументах.

Параметры:

  • collection - Массив объектов, представляющих теги <optgroup>.

  • group_method - Имя метода, который, когда вызывается на элементе collection, возвращает массив дочерних объектов, представляющих теги <option>.

  • group_label_method - Имя метода, который, когда вызывается на элементе collection, возвращает строку, используемую в качестве атрибута label для его тега <optgroup>.

  • option_key_method - Имя метода, который, когда вызывается на дочернем объекте элемента collection, возвращает значение для атрибута value его тега <option>.

  • option_value_method - Имя метода, который, когда вызывается на дочернем объекте элемента collection, возвращает значение для содержимого тега <option>.

  • selected_key - Значение, равное атрибуту value для одного из тегов <option> , у которого будет установлен атрибут selected . Соответствует возвращаемому значению одного из вызовов option_key_method. Если nil, выбор не делается. Также может быть хэш, если необходимо указать значения для отключения.

Пример структуры объекта для использования с этим методом:

class Continent < ActiveRecord::Base
  has_many :countries
  # attribs: id, name
end

class Country < ActiveRecord::Base
  belongs_to :continent
  # attribs: id, name, continent_id
end

Пример использования:

option_groups_from_collection_for_select(@continents, :countries, :name, :id, :name, 3)

Возможный результат:

<optgroup label="Africa">
  <option value="1">Egypt</option>
  <option value="4">Rwanda</option>
  ...
</optgroup>
<optgroup label="Asia">
  <option value="3" selected="selected">China</option>
  <option value="12">India</option>
  <option value="5">Japan</option>
  ...
</optgroup>

Примечание: Возвращаются только теги <optgroup> и <option>, поэтому вам все равно необходимо обернуть вывод в соответствующий тег <select>.

options_for_select(container, selected = nil) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 356
def options_for_select(container, selected = nil)
  return container if String === container

  selected, disabled = extract_selected_and_disabled(selected).map do |r|
    Array(r).map(&:to_s)
  end

  container.map do |element|
    html_attributes = option_html_attributes(element)
    text, value = option_text_and_value(element).map(&:to_s)

    html_attributes[:selected] ||= option_value_selected?(value, selected)
    html_attributes[:disabled] ||= disabled && option_value_selected?(value, disabled)
    html_attributes[:value] = value

    tag_builder.content_tag_string(:option, text, html_attributes)
  end.join("\n").html_safe
end

Принимает контейнер (хэш, массив, перечисляемый объект, ваш тип) и возвращает строку тегов option. Если элементы контейнера имеют методы first и last (например, двумерный массив), то «last» служит значениями опций, а «first» — текстом опций. Хэши автоматически преобразуются в этот формат, ключи становятся «first», а значения — «last». Если задан selected, соответствующий «last» или элемент получит выбранный тег option. selected также может быть массивом значений, которые будут выбраны при использовании множественного выбора.

options_for_select([["Dollar", "$"], ["Kroner", "DKK"]])
# => <option value="$">Dollar</option>
# => <option value="DKK">Kroner</option>

options_for_select([ "VISA", "MasterCard" ], "MasterCard")
# => <option value="VISA">VISA</option>
# => <option selected="selected" value="MasterCard">MasterCard</option>

options_for_select({ "Basic" => "$20", "Plus" => "$40" }, "$40")
# => <option value="$20">Basic</option>
# => <option value="$40" selected="selected">Plus</option>

options_for_select([ "VISA", "MasterCard", "Discover" ], ["VISA", "Discover"])
# => <option selected="selected" value="VISA">VISA</option>
# => <option value="MasterCard">MasterCard</option>
# => <option selected="selected" value="Discover">Discover</option>

Вы можете дополнительно указать HTML-атрибуты в качестве последнего элемента массива.

options_for_select([ "Denmark", ["USA", { class: 'bold' }], "Sweden" ], ["USA", "Sweden"])
# => <option value="Denmark">Denmark</option>
# => <option value="USA" class="bold" selected="selected">USA</option>
# => <option value="Sweden" selected="selected">Sweden</option>

options_for_select([["Dollar", "$", { class: "bold" }], ["Kroner", "DKK", { onclick: "alert('HI');" }]])
# => <option value="$" class="bold">Dollar</option>
# => <option value="DKK" onclick="alert('HI');">Kroner</option>

Если вы хотите указать теги отключенных опций, установите selected в хэш, где :disabled будет либо значением, либо массивом значений, которые необходимо отключить. В этом случае вы можете использовать :selected для указания выбранных тегов option.

options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], disabled: "Super Platinum")
# => <option value="Free">Free</option>
# => <option value="Basic">Basic</option>
# => <option value="Advanced">Advanced</option>
# => <option value="Super Platinum" disabled="disabled">Super Platinum</option>

options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], disabled: ["Advanced", "Super Platinum"])
# => <option value="Free">Free</option>
# => <option value="Basic">Basic</option>
# => <option value="Advanced" disabled="disabled">Advanced</option>
# => <option value="Super Platinum" disabled="disabled">Super Platinum</option>

options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], selected: "Free", disabled: "Super Platinum")
# => <option value="Free" selected="selected">Free</option>
# => <option value="Basic">Basic</option>
# => <option value="Advanced">Advanced</option>
# => <option value="Super Platinum" disabled="disabled">Super Platinum</option>

ПРИМЕЧАНИЕ: Возвращаются только теги option, вам нужно обернуть этот вызов в обычный HTML-тег select.

options_from_collection_for_select(collection, value_method, text_method, selected = nil) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 399
def options_from_collection_for_select(collection, value_method, text_method, selected = nil)
  options = collection.map do |element|
    [value_for_collection(element, text_method), value_for_collection(element, value_method), option_html_attributes(element)]
  end
  selected, disabled = extract_selected_and_disabled(selected)
  select_deselect = {
    selected: extract_values_from_collection(collection, value_method, selected),
    disabled: extract_values_from_collection(collection, value_method, disabled)
  }

  options_for_select(options, select_deselect)
end

Возвращает строку тегов option, скомпилированных путем итерации по collection, и присвоением результата вызова value_method как значения опции, а text_method как текста опции.

options_from_collection_for_select(@people, 'id', 'name')
# => <option value="#{person.id}">#{person.name}</option>

Это чаще всего используется внутри тега select, как в этом примере:

select_tag 'person', options_from_collection_for_select(@people, 'id', 'name')

Если selected задано как значение или массив значений, элементы, возвращающие совпадение в value_method, будут выбранными тегами option.

Если selected задано как Proc, то членами коллекции, которые возвращают true для анонимной функции, являются выбранные значения.

selected также может быть хэш, указывающий как значения :selected, так и :disabled как требуется.

Убедитесь, что вы указали тот же класс, что и value_method, при указании выбранных или отключенных опций. Отсутствие этого приведет к нежелательным результатам. Пример:

options_from_collection_for_select(@people, 'id', 'name', '1')

Не выберет человека с идентификатором 1, потому что 1 (целое число Integer) не равно '1' (строка)

options_from_collection_for_select(@people, 'id', 'name', 1)

должно дать нужный результат.

select(object, method, choices = nil, options = {}, html_options = {}, &block) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 163
def select(object, method, choices = nil, options = {}, html_options = {}, &block)
  Tags::Select.new(object, method, self, choices, options, html_options, &block).render
end

Создает тег select и серию содержащихся тегов option для заданного объекта и метода. Выбранной опцией будет опция, текущая для объекта, если объект доступен.

Есть два возможных формата для параметра choices, соответствующие выводу других помощников:

  • Плоская коллекция (см. options_for_select).

  • Вложенная коллекция (см. grouped_options_for_select).

Например:

select("post", "person_id", Person.all.collect { |p| [ p.name, p.id ] }, { include_blank: true })

преобразуется в:

<select name="post[person_id]" id="post_person_id">
  <option value="" label=" "></option>
  <option value="1" selected="selected">David</option>
  <option value="2">Eileen</option>
  <option value="3">Rafael</option>
</select>

предполагая, что у связанного человека ID 1.

Это можно использовать для предоставления набора опций по умолчанию стандартным способом: перед рендерингом формы создания экземпляру новой модели присваиваются опции по умолчанию и привязывается к @model_name. Обычно эта модель не сохраняется в базе данных. Вместо этого второй объект модели создается при получении запроса создания. Это позволяет пользователю несколько раз отправлять страницу формы с ожидаемыми результатами создания нескольких записей. Кроме того, это позволяет использовать один фрагмент для генерации элементов формы для форм редактирования и создания.

По умолчанию, post.person_id является выбранной опцией. Укажите selected: value, чтобы использовать другой выбор, или selected: nil, чтобы оставить все опции невыбранными. Аналогично, вы можете указать значения, которые следует отключить в тегах опций, указав опцию :disabled. Это может быть одно значение или массив значений, которые необходимо отключить.

Блок может быть передан в select, чтобы настроить отображение тегов option. Это полезно, когда тег опции имеет сложные атрибуты.

select(report, "campaign_ids") do
  available_campaigns.each do |c|
    content_tag(:option, c.name, value: c.id, data: { tags: c.tags.to_json })
  end
end

Примечание

Спецификация HTML гласит, что когда параметр multiple передается в select, и все опции не выбраны, веб-браузеры не отправляют никаких значений на сервер. К сожалению, это приводит к проблеме: если у модели User много roles, и есть аксессор role_ids, и в форме, которая редактирует роли пользователя, пользователь отменяет выбор всех ролей из поля множественного выбора role_ids, параметр role_ids не отправляется. Таким образом, любой идиом массового назначения, такой как

@user.update(params[:user])

не обновит роли.

Чтобы предотвратить это, помощник генерирует вспомогательное скрытое поле перед каждым полем множественного выбора. Скрытое поле имеет то же имя, что и поле множественного выбора, и пустое значение.

Примечание: Клиент либо отправляет только скрытое поле (представляющее невыбранное поле множественного выбора), либо оба поля. Это означает, что результирующий массив всегда содержит пустую строку.

В случае если вы не хотите, чтобы помощник генерировал это скрытое поле, вы можете указать опцию include_hidden: false.

time_zone_options_for_select(selected = nil, priority_zones = nil, model = ::ActiveSupport::TimeZone) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 575
def time_zone_options_for_select(selected = nil, priority_zones = nil, model = ::ActiveSupport::TimeZone)
  zone_options = "".html_safe

  zones = model.all
  convert_zones = lambda { |list| list.map { |z| [ z.to_s, z.name ] } }

  if priority_zones
    if priority_zones.is_a?(Regexp)
      priority_zones = zones.select { |z| z.match?(priority_zones) }
    end

    zone_options.safe_concat options_for_select(convert_zones[priority_zones], selected)
    zone_options.safe_concat content_tag("option", "-------------", value: "", disabled: true)
    zone_options.safe_concat "\n"

    zones = zones - priority_zones
  end

  zone_options.safe_concat options_for_select(convert_zones[zones], selected)
end

Возвращает строку тегов option для практически любого часового пояса в мире. Укажите имя ActiveSupport::TimeZone как selected, чтобы пометить его как выбранный тег option. Вы также можете указать массив объектов ActiveSupport::TimeZone как priority_zones, чтобы они были перечислены выше остальных (длинных) элементов списка. (Вы можете использовать ActiveSupport::TimeZone.us_zones для получения списка часовых поясов США или Regexp для выбора нужных поясов)

Параметр selected должен быть либо nil, либо строкой, которая задаёт имя ActiveSupport::TimeZone.

По умолчанию, model — это константа ActiveSupport::TimeZone (которую можно получить в Active Record как объект значения). Параметр model должен отвечать на запрос all и возвращать массив объектов, представляющих часовые пояса; каждый объект должен отвечать на запрос name. Если задан Regexp, он попытается сопоставить пояса с помощью метода match?.

ПРИМЕЧАНИЕ: Возвращаются только теги option, вы должны обернуть этот вызов в обычный тег select HTML.

time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 296
def time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {})
  Tags::TimeZoneSelect.new(object, method, self, priority_zones, options, html_options).render
end

Возвращает теги select и option для заданного объекта и метода, используя time_zone_options_for_select для генерации списка тегов option.

В дополнение к параметру :include_blank описанному выше, этот метод также поддерживает параметр :model, который по умолчанию равен ActiveSupport::TimeZone. Пользователи могут использовать его для указания объекта модели часового пояса с иными настройками. (См. time_zone_options_for_select для получения дополнительной информации.)

Вы также можете указать массив объектов ActiveSupport::TimeZone как priority_zones, чтобы они были перечислены выше остальных (длинных) элементов списка. Вы можете использовать ActiveSupport::TimeZone.us_zones для списка часовых поясов США, ActiveSupport::TimeZone.country_zones(country_code) для часовых поясов другой страны или Regexp для выбора необходимых поясов.

Наконец, этот метод поддерживает параметр :default, который выбирает значение по умолчанию ActiveSupport::TimeZone, если часовой пояс объекта nil.

time_zone_select("user", "time_zone", nil, include_blank: true)

time_zone_select("user", "time_zone", nil, default: "Pacific Time (US & Canada)")

time_zone_select("user", 'time_zone', ActiveSupport::TimeZone.us_zones, default: "Pacific Time (US & Canada)")

time_zone_select("user", 'time_zone', [ ActiveSupport::TimeZone['Alaska'], ActiveSupport::TimeZone['Hawaii'] ])

time_zone_select("user", 'time_zone', /Australia/)

time_zone_select("user", "time_zone", ActiveSupport::TimeZone.all.sort, model: ActiveSupport::TimeZone)

© 2004–2020 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API