Spec-Zone.ru › Ruby on Rails 7.0

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

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

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

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

  • :include_blank — устанавливается в true или в строку запроса, если первый элемент опции тега 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 ещё нет значения, он добавляет опцию с общим запросом — «Пожалуйста, выберите» — или заданной строкой запроса.

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

    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 также может быть процедурой, определяющей опции, которые должны быть отключены.

    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 779
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 695
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 не отправляется. Поэтому любой idiom сильных параметров, такой как:

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 198
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 257
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>.

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

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

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

# attributes: id, name, country_id
class City < ActiveRecord::Base
  belongs_to :country
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 531
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 461
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 357
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 (например, массив из двух элементов), «последние» служат значениями вариантов, а «первые» — текстом вариантов. Хеши автоматически преобразуются в этот формат, поэтому ключи становятся «первыми», а значения — «последними». Если selected указан, соответствующий «последний» или элемент получит выбранный тег 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>

Если вы хотите указать отключаемые теги 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 400
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_tag, как в этом примере:

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

Не выберет человека с id 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 158
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).

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

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">David</option>
  <option value="2" selected="selected">Eileen</option>
  <option value="3">Rafael</option>
</select>

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

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

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

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

Gotcha

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

@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 576
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, вам необходимо обернуть этот вызов в обычный HTML-тег select.

time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 291
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)
weekday_options_for_select(selected = nil, index_as_value: false, day_format: :day_names, beginning_of_week: Date.beginning_of_week) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 608
def weekday_options_for_select(selected = nil, index_as_value: false, day_format: :day_names, beginning_of_week: Date.beginning_of_week)
  day_names = I18n.translate("date.#{day_format}")
  day_names = day_names.map.with_index.to_a if index_as_value
  day_names = day_names.rotate(Date::DAYS_INTO_WEEK.fetch(beginning_of_week))

  options_for_select(day_names, selected)
end

Возвращает строку тегов option для дней недели.

Параметры:

  • :index_as_value - По умолчанию false, установите в true, чтобы использовать индексы от

`I18n.translate(“date.day_names”)` в качестве значений. По умолчанию, воскресенье всегда 0.

  • :day_format - Ключ I18n массива для использования в качестве опций дней недели.

По умолчанию :day_names, установите в :abbr_day_names для сокращений.

  • :beginning_of_week - По умолчанию Date.beginning_of_week.

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

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

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

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

Spec-Zone.ru

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