5

我目前正在对网站进行可访问性大修,遇到了一个我不知道如何在 Rails 中解决的问题。代码如下:

<%= f.label :birthdate %>
<%= f.date_select :birthdate, {:start_year => Time.now.year - 14, :end_year => 1900, :prompt => true, :order => [:day, :month, :year]} %>

产生:

<label for="birthdate">Birthdate</label>
<select id="birthdate_3i" name="birthdate(3i)">
    <option value="">Day</option>
    <option value="1">1</option>
        ...
    <option value="31">31</option>
</select>
<select id="birthdate_2i" name="birthdate(2i)">
    <option value="">Month</option>
    <option value="1">January</option>
        ...
    <option value="12">December</option>
</select>
<select id="birthdate_1i" name="birthdate(1i)">
    <option value="">Year</option>
    <option value="1998">1998</option>
        ...
    <option value="1900">1900</option>
</select>

有谁知道我是否必须为已生成的 3 个选择字段手动编写标签/字段集?或者我应该以不同的方式使用 rails 代码。我对 Rails 有点陌生……更像是一个前端。

4

5 回答 5

2

我最近在一个项目中遇到了这个问题,我们发现select在 Rails 日期选择中每个之前添加标签的唯一方法是对 Rails 进行猴子补丁。我们在 Rails 5.1.4 上。这是构建月/日/年选择并在最后 2 个选择之前放置分隔符的原始方法,当date_separator作为参数传递时:

https://github.com/rails/rails/blob/2c97fbf6503c9199f3fe5ed06222e7226dc6fcd9/actionview/lib/action_view/helpers/date_helper.rb#L1091

这是我们的猴子补丁,它使用正确的标签在每个日期选择之前放置一个图例分隔符:for

module ActionView
  module Helpers
    class DateTimeSelector

      # Given an ordering of datetime components, create the selection HTML
      # and join them with their appropriate separators.
      def build_selects_from_types(order)
        select = ""
        order.reverse_each do |type|
          separator = separator(type)
          select.insert(0, separator.to_s + send("select_#{type}").to_s)
        end
        select.html_safe
      end

      # Returns the separator for a given datetime component.
      def separator(type)
        return "" if @options[:use_hidden]
        field_name = "#{@options[:prefix]}_#{@options[:field_name]}"
        case type
          when :year
            "<label for='#{field_name}_1i'>Year</label>"
          when :month
            "<label for='#{field_name}_2i'>Month</label>"
          when :day
            "<label for='#{field_name}_3i'>Day</label>"
          when :hour
            (@options[:discard_year] && @options[:discard_day]) ? "" : @options[:datetime_separator]
          when :minute, :second
            @options[:"discard_#{type}"] ? "" : @options[:time_separator]
        end
      end
    end
  end
end
于 2017-12-15T16:53:18.487 回答
0
date_select("DOB", :birthdate, :prompt => {
:day => 'Select day', :month => 'Select month', :year => 'Select year',
:start_year => Time.now.year - 14, :end_year => 1900
})

更多选项:
http ://api.rubyonrails.org/classes/ActionView/Helpers/DateHelper.html#method-i-date_select

于 2012-08-22T02:23:39.413 回答
0

我认为不可能生成单独的标签。即使您愿意接受一个标签,还有一个额外的障碍是它不是严格有效的 HTML,因为没有“生日”表单控件。你应该在标签助手中使用 :birthdate_3i 吗?

于 2013-04-24T15:37:10.610 回答
0

只需将其包裹date_selectdivor中即可fieldset。标签可以指向任何带有 ID 的东西,如果您有多个输入到一个数据类型中(如 rails date_select),那么您可以标记容器,并让选择框成为它的组件。

<%= f.label :birthdate %>
<div id="birthdate">
  <%= f.date_select :birthdate, {:start_year => Time.now.year - 14, :end_year => 1900, :prompt => true, :order => [:day, :month, :year]} %>
</div>
于 2013-05-07T18:32:58.707 回答
0

有一种方法不包括修补 Rails。不过,它仍然很hacky。这个想法是增加由date_select. 我们将使用 Nokogiri 来执行此操作(gem 'nokogiri'在 Gemfile 中需要)。

下面的代码添加date_select_with_labels到执行此操作的股票表单构建器中:

class ActionView::Helpers::FormBuilder
  def date_select_with_labels(attribute, options = {})
    generated_selects = @template.date_select(object.model_name.singular, attribute, options)

    selects_with_labels = Nokogiri::HTML::Document.parse(generated_selects).css('select').map do |select|
      label(
        attribute,
        date_select_part_type_from_options(select, options[:include_blank]),
        options.reverse_merge(for: select.attr('id'))
      ) +
        select.to_s.html_safe
    end

    @template.content_tag(:div) do
      selects_with_labels.join('').html_safe
    end
  end

  private

  def date_select_part_type_from_options(select, include_blank)
    maybe_one = include_blank ? 1 : 0

    case select.css('option').size
    when 12 + maybe_one
      'Month'
    when (28 + maybe_one)..(31 + maybe_one)
      'Day'
    else
      'Year'
    end
  end
end
于 2020-03-13T07:56:30.910 回答