我想盡可能方便地編輯表單域。例如,對於數字值,我希望字段以逗號(例如number_with_precision
)顯示。如何格式化Rails編輯字段中顯示的值?
這在顯示器端很容易,但編輯怎麼樣?有沒有一個好的方法來做到這一點?
我正在使用Rails FormBuilder。經過調查,我發現它使用InstanceTag,它使用<attribute>_value_before_type_cast
獲取字段的值,這意味着覆蓋<attribute>
不會被調用。
我想盡可能方便地編輯表單域。例如,對於數字值,我希望字段以逗號(例如number_with_precision
)顯示。如何格式化Rails編輯字段中顯示的值?
這在顯示器端很容易,但編輯怎麼樣?有沒有一個好的方法來做到這一點?
我正在使用Rails FormBuilder。經過調查,我發現它使用InstanceTag,它使用<attribute>_value_before_type_cast
獲取字段的值,這意味着覆蓋<attribute>
不會被調用。
我想出了迄今爲止最好的是這樣的:
<%= f.text_field :my_attribute, :value => number_with_precision(f.object.my_attribute) %>
或者my_attribute
可以返回格式化的值,就像這樣:
def my_attribute
ApplicationController.helpers.number_with_precision(read_attribute(:my_attribute))
end
但你仍然必須使用:value
<%= f.text_field :my_attribute, :value => f.object.my_attribute %>
這似乎很多工作。
注意:如果您使用帶有逗號或貨幣符號格式的第一個解決方案,則需要將其排除在控制器的創建和更新方法中。 – LeBleu 2013-08-20 20:06:53
我會避免使用第二種解決方案,在您的模型中引用`ApplicationController`對於養成習慣絕對不是好事。 – 2015-05-01 21:06:14
最後一個對我來說最合適,我的功能仍然可以在我的數據模型中,並且不影響提交或編輯。好的解決方案 – 2016-09-29 15:34:52
我更喜歡你的第一個答案,格式是在視圖中完成的。但是,如果要在模型中執行格式設置,則可以爲getter和setter使用包裝器方法,並避免完全使用:value選項。
你最終會得到類似的東西。
def my_attribute_string
foo_formatter(myattribute)
end
def my_attribute_string=(s)
# Parse "s" or do whatever you need to with it, then set your real attribute.
end
<%= f.text_field :my_attribute_string %>
Railscasts在episode #32的text_field中使用Time對象覆蓋了此事件。這個真正聰明的部分是他們如何處理驗證錯誤。單獨看這段情節是值得的。
如果您想要在編輯過程中創建或維護一種格式,您需要添加Javascript來實現「蒙版」。 Here is a demo.
這是第一次打these results。
我做了類似的事情。我們使用自定義表單構建器來格式化時間和長度。它利用現有text_field的,但包裝它,因此該值可定製:
class SuperFormBuilder < ActionView::Helpers::FormBuilder
include ApplicationHelper
include FormHelper
include ActionView::Helpers::TagHelper
include ActionView::Helpers::FormTagHelper
def length_field(label,*args)
scale = 'medium'
args.each do |v|
if v.has_key?(:scale)
scale = v[:scale]
v.delete(:scale)
end
end
value = length_conversion(@object.send(label.to_sym),scale)
options = (args.length > 0) ? args.pop : {}
return has_error(label, text_field_tag(field_name(label),value,*args) + ' ' + length_unit(scale))
end
private
def field_name(label)
return @object_name + "[#{label}]"
end
def has_error(label, output)
return "<div class='fieldWithErrors'>#{output}</div>" if @object.errors[label]
return output
end
它用於這樣的:
<%= form_for(@section, {:action => 'save', :id => @section.id}, :builder => SuperFormBuilder) do |sf| %>
<%= sf.length_field :feed_size_min_w, :size => 3, :scale => 'small' %>
<% end %>
最終結果是基於在相應的單元中的值關閉他們在系統(公制,英制)上的選擇,並縮放IE小=英寸或毫米。
我基本上從現有的表單構建器中複製text_field方法,它使用text_field_tag本身。
有兩個問題:1)知道對象字段的名稱以及如何訪問對象以獲取要格式化的值。 2)獲取正確的名字,以便在提交表單時它是正確的參數散列的一部分。
表單構建器被賦予一個類變量@object。您可以使用.send方法獲取該字段的值。在我的情況下,我發送標籤:feed_size_min_w到@對象,並獲得其長度。然後將其轉換爲我想要的格式,並將其提供給text_field_tag。
該字段的名稱是使它最終在params散列中的關鍵,在我的實例中是params [:sections]之一。我做了一個叫做field_name的輔助函數來處理這個問題。
最後,如果該標籤上有錯誤,則has_error會將該字段包裝在錯誤div中。
您可以使用number_format插件。通過爲模型中的現有數字屬性指定number_format
,該屬性現在將以所有格式和視圖的格式顯示爲Rails。在插入數據庫之前,它也將從該格式解析(當通過表單分配時)。 (該插件還創建了純數字unformatted_<attribute-name>
存取方法可以繼續用於算術,或可無縫集成直接數值轉讓或獲取由你。)
class MyModel < ActiveRecord::Base
# this model has the balance attribute, which we
# want to display using formatting in views,
# although it is stored as a numeric in the database
number_format :balance,
:precision => 2,
:delimiter => ',',
:strip_trailing_zeros => false
def increment_balance
unformatted_balance += 10
end
您還可以結合上面用JavaScript解決方案,這可以強制用戶在編輯時保持小數點和數千個分隔符,儘管這並不是必要的。
這是一個老問題,但萬一有人遇到這個問題,您可以使用number_to_X助手。他們有所有你所能想顯示你的編輯值的屬性:
<%= f.text_field :my_number, :value => number_to_human(f.object.my_number, :separator => '', :unit => '', :delimiter => '', :precision => 0) %>
有更多的屬性可得:http://api.rubyonrails.org/classes/ActionView/Helpers/NumberHelper.html
我已經開始在這個問題上的賞金,因爲我想知道如果有一個比JDL和我自己闡述的更好的答案。有它! – 2009-03-04 16:41:08