कस्टम विशेषताओं के साथ रेल f.select विकल्पों पर माणिक


115

मेरे पास एक फॉर्म सेलेक्ट स्टेटमेंट है, जैसे:

= 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>
...

2
रेल उस कार्यक्षमता को प्रदान नहीं करती है, आपको उस मार्कअप को बनाने के लिए एक सहायक बनाना होगा। यह भी ध्यान रखें कि आपके द्वारा उल्लेखित उदाहरण मान्य HTML नहीं है।
अगस्तो

मुझे पता है, मेरा उदाहरण HTML मान्य नहीं है ... मुझे लगता है कि मुझे अपने इच्छित परिणाम प्राप्त करने के लिए अपना रास्ता बदलना होगा, thk!
el_quick

जवाबों:


356

मौजूदा विकल्प_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) %>

यदि आपको समूहीकृत विकल्पों की आवश्यकता है, तो आप समूहीकृत समूह का उपयोग कर सकते हैं।

<%= 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) %>

क्रेडिट पाओल @ पोगोडन को जाना चाहिए जिन्होंने इसे डॉक्स में नहीं ढूंढने के बारे में पोस्ट किया था, लेकिन रेल के स्रोत को पढ़कर। https://web.archive.org/web/20130128223827/http://www.pogodan.com/blog/2011/02/24/custom-html-attributes-in-options-for-select


6

आप इस प्रकार कर सकते हैं:

= f.select :country_id, @countries.map{ |c| [c.name, c.id, { 'data-currency-code' => c.currency_code} ] }

सही है, लेकिन पहले से ही एनाटॉर्टोइस हाउस के जवाब में उल्लेख किया गया है।
केल्विन

स्वीकृत जवाब रूबी का उपयोग करके कस्टम विशेषताओं का वर्णन नहीं करता है। यह ऐसा करता है इसलिए मुझे लगता है कि यह बेहतर है क्योंकि यह पहला उत्तर है जो दिखाता है कि इसे माणिक के माध्यम से कैसे किया जाए।
निखिल गुप्ते

5

यह सीधे रेल के साथ संभव नहीं है, और आपको कस्टम विशेषताओं को बनाने के लिए अपना स्वयं का सहायक बनाना होगा। उस ने कहा, आप जो चाहते हैं उसे पूरा करने के दो अलग-अलग तरीके हैं:

(1) HTML5 में एक कस्टम विशेषता नाम का उपयोग करना। HTML5 में आपको कस्टम विशेषता नाम रखने की अनुमति है , लेकिन उन्हें 'डेटा-' के साथ प्री-पेंडिंग होना होगा। इन कस्टम विशेषताओं को आपके फ़ॉर्म के साथ सबमिट नहीं किया जाएगा, लेकिन इनका उपयोग जावास्क्रिप्ट में आपके तत्वों तक पहुंचने के लिए किया जा सकता है। यदि आप इसे पूरा करना चाहते हैं, तो मैं एक सहायक बनाने की सलाह दूंगा जो इस तरह के विकल्प उत्पन्न करे:

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

3
बहुत बढ़िया जवाब। मैंने एप्रोच नंबर 1 का विकल्प चुना है और ब्लॉग किया है कि कैसे मैंने किसी और की मदद करने के मामले में सहायक बनाया। redguava.com.au/2011/03/…
जोएल

अन्य टिप्पणीकारों से सहमत - नीचे अनातोइस का जवाब देखें!
जैकब

23
>>>>>>>>>>>>> गलत जवाब ... रखने स्क्रॉल <<<<<<<<<<<<
stevenspiel

1
यह सीधे रेल में संभव है। देखें: stackoverflow.com/a/9076805/380607
Magne

पैन, कृपया इस भ्रामक उत्तर को हटा दें।
वीएमवी

4

अतिरिक्त विशेषता हैश केवल रेल 3 में समर्थित है।

यदि आप 2.x रेल पर हैं , और ओवरराइड करना चाहते हैंoptions_for_select

मैं मूल रूप से सिर्फ रेल 3 कोड की नकल करता हूं। आपको इन 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

Kinda गन्दा लेकिन यह एक विकल्प है। मैं इस कोड को एक सहायक मॉड्यूल में रखता 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"} ] }))

फिर से एक महान समाधान नहीं है, लेकिन यह कभी भी इतना उपयोगी डेटा-विशेषता प्राप्त करने के लिए इसके लायक हो सकता है।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.