[ruby-on-rails] 레일 위의 루비 f. 사용자 정의 속성이있는 옵션 선택
다음과 같은 양식 선택 문이 있습니다.
= f.select :country_id, @countries.map{ |c| [c.name, c.id] }
이 코드는 다음과 같습니다.
...
<option value="1">Andorra</option>
<option value="2">Argentina</option>
...
하지만 다음과 같이 내 옵션에 사용자 정의 HTML 속성을 추가하고 싶습니다.
...
<option value="1" currency_code="XXX">Andorra</option>
<option value="2" currency_code="YYY">Argentina</option>
...
답변
Rails는 기존 options_for_select 도우미를 사용하여 사용자 지정 속성을 추가하여 옵션을 선택할 수 있습니다. 귀하의 질문에 거의 코드가 있습니다. html5 데이터 속성 사용 :
<%= f.select :country_id, options_for_select(
@countries.map{ |c| [c.name, c.id, {'data-currency_code'=>c.currency_code}] }) %>
초기 선택 추가 :
<%= f.select :country_id, options_for_select(
@countries.map{ |c| [c.name, c.id, {'data-currency_code'=>c.currency_code}] },
selected_key = f.object.country_id) %>
그룹화 된 옵션이 필요한 경우 다음과 같이 grouped_options_for_select 도우미를 사용할 수 있습니다 (@continents가 각 대륙 메서드가있는 대륙 개체의 배열 인 경우).
<%= f.select :country_id, grouped_options_for_select(
@continents.map{ |group| [group.name, group.countries.
map{ |c| [c.name, c.id, {'data-currency_code'=>c.currency_code}] } ] },
selected_key = f.object.country_id) %>
신용은 문서가 아니라 레일 소스를 읽음으로써 이것을 발견하는 것에 대해 게시 한 paul @ pogodan에게 가야합니다. https://web.archive.org/web/20130128223827/http://www.pogodan.com/blog/2011/02/24/custom-html-attributes-in-options-for-select
답변
다음과 같이 할 수 있습니다.
= f.select :country_id, @countries.map{ |c| [c.name, c.id, { 'data-currency-code' => c.currency_code} ] }
답변
이것은 Rails에서 직접 가능하지 않으며, 사용자 지정 속성을 생성하기 위해 자신 만의 헬퍼를 생성해야합니다. 즉, 원하는 작업을 수행하는 방법에는 두 가지가 있습니다.
(1) HTML5에서 사용자 정의 속성 이름 사용. HTML5에서는 사용자 정의 속성 이름 을 가질 수 있지만 앞에 ‘data-‘를 추가해야합니다. 이러한 사용자 정의 속성은 양식과 함께 제출되지 않지만 Javascript에서 요소에 액세스하는 데 사용할 수 있습니다. 이 작업을 수행하려면 다음과 같은 옵션을 생성하는 도우미를 만드는 것이 좋습니다.
<option value="1" data-currecy-code="XXX">Andorra</option>
(2) 사용자 지정 분할과 함께 값을 사용하여 추가 데이터를 제출합니다. 실제로 통화 코드를 제출하려면 다음과 같이 선택 상자를 만드는 것이 좋습니다.
= f.select :country_id, @countries.map{ |c| [c.name, "#{c.id}:#{c.currency_code}"] }
이렇게하면 다음과 같은 HTML이 생성됩니다.
<option value="1:XXX">Andorra</option>
<option value="2:YYY">Argentina</option>
그런 다음 컨트롤러에서 구문 분석 할 수 있습니다.
@id, @currency_code = params[:country_id].split(':')
답변
추가 속성 해시는 Rails 3에서만 지원됩니다.
Rails 2.x 를 사용 중이고 재정의하려는 경우options_for_select
기본적으로 Rails 3 코드를 복사했습니다. 다음 세 가지 방법을 재정의해야합니다.
def options_for_select(container, selected = nil)
return container if String === container
container = container.to_a if Hash === container
selected, disabled = extract_selected_and_disabled(selected)
options_for_select = container.inject([]) do |options, element|
html_attributes = option_html_attributes(element)
text, value = option_text_and_value(element)
selected_attribute = ' selected="selected"' if option_value_selected?(value, selected)
disabled_attribute = ' disabled="disabled"' if disabled && option_value_selected?(value, disabled)
options << %(<option value="#{html_escape(value.to_s)}"#{selected_attribute}#{disabled_attribute}#{html_attributes}>#{html_escape(text.to_s)}</option>)
end
options_for_select.join("\n").html_safe
end
def option_text_and_value(option)
# Options are [text, value] pairs or strings used for both.
case
when Array === option
option = option.reject { |e| Hash === e }
[option.first, option.last]
when !option.is_a?(String) && option.respond_to?(:first) && option.respond_to?(:last)
[option.first, option.last]
else
[option, option]
end
end
def option_html_attributes(element)
return "" unless Array === element
html_attributes = []
element.select { |e| Hash === e }.reduce({}, :merge).each do |k, v|
html_attributes << " #{k}=\"#{ERB::Util.html_escape(v.to_s)}\""
end
html_attributes.join
end
좀 지저분하지만 옵션입니다. 이 코드를라는 도우미 모듈에 RailsOverrides
넣은 다음 ApplicationHelper
. 원하는 경우 플러그인 / 젬을 사용할 수도 있습니다.
한 가지 문제점은 이러한 메서드를 활용하려면 항상 options_for_select
직접 호출해야한다는 것 입니다. 다음과 같은 단축키
select("post", "person_id", Person.all.collect {|p| [ p.name, p.id, {"data-stuff"=>"html5"} ] })
오래된 결과를 얻을 것입니다. 대신 다음과 같아야합니다.
select("post", "person_id", options_for_select(Person.all.collect {|p| [ p.name, p.id, {"data-stuff"=>"html5"} ] }))
다시 한 번 훌륭한 솔루션은 아니지만 매우 유용한 데이터 속성을 얻을 가치가있을 수 있습니다.
답변
이 문제도 만났고이 문제를 해결하기 위해 “enhanced_select”Ruby Gem을 만들었습니다. 여기에서 찾을 수 있습니다.