Ruby-on-rails 如何格式化 Rails 编辑字段中显示的值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/591939/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I format the value shown in a Rails edit field?
提问by Luke Francl
I would like to make editing form fields as user-friendly as possible. For example, for numeric values, I would like the field to be displayed with commas (like number_with_precision).
我想让编辑表单字段尽可能方便用户。例如,对于数值,我希望该字段以逗号(如number_with_precision)显示。
This is easy enough on the display side, but what about editing? Is there a good way to do this?
这在显示方面很容易,但是编辑呢?有没有好的方法可以做到这一点?
I am using the Rails FormBuilder. Upon investigation, I found that it uses InstanceTag, which gets the values for fields by using <attribute>_value_before_type_castwhich means overriding <attribute>won't get called.
我正在使用 Rails FormBuilder。经过调查,我发现它使用 InstanceTag,它通过使用<attribute>_value_before_type_cast这意味着<attribute>不会调用覆盖来获取字段的值。
回答by Luke Francl
The best I have come up with so far is something like this:
到目前为止,我想出的最好的东西是这样的:
<%= f.text_field :my_attribute, :value => number_with_precision(f.object.my_attribute) %>
Or my_attributecould return the formatted value, like this:
或者my_attribute可以返回格式化的值,如下所示:
def my_attribute
ApplicationController.helpers.number_with_precision(read_attribute(:my_attribute))
end
But you still have to use :value
但你仍然必须使用 :value
<%= f.text_field :my_attribute, :value => f.object.my_attribute %>
This seems like a lot of work.
这似乎是很多工作。
回答by jdl
I prefer your first answer, with the formatting being done in the view. However, if you want to perform the formatting in the model, you can use wrapper methods for the getter and setter, and avoid having to use the :value option entirely.
我更喜欢你的第一个答案,在视图中完成格式化。但是,如果您想在模型中执行格式化,您可以对 getter 和 setter 使用包装方法,并避免完全使用 :value 选项。
You'd end up with something like this.
你最终会得到这样的东西。
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 covered this with a Time object in a text_field in episode #32. The really clever part of this is how they handle validation errors. It's worth watching the episode for that alone.
Railscasts 在第 32 集的 text_field 中使用 Time 对象对此进行了介绍。真正聪明的部分是他们如何处理验证错误。仅凭这一点就值得观看这一集。
回答by Joshua Harris
This is an old question, but in case anyone comes across this you could use the number_to_X helpers. They have all of the attributes you could ever want for displaying your edit value:
这是一个老问题,但如果有人遇到这个问题,您可以使用 number_to_X 助手。它们具有显示编辑值时可能需要的所有属性:
<%= f.text_field :my_number, :value => number_to_human(f.object.my_number, :separator => '', :unit => '', :delimiter => '', :precision => 0) %>
There are more attributes available too: http://api.rubyonrails.org/classes/ActionView/Helpers/NumberHelper.html
还有更多可用的属性:http: //api.rubyonrails.org/classes/ActionView/Helpers/NumberHelper.html
回答by vladr
You can use the number_formatplugin. By specifying a number_formatfor an existing numeric attribute inside your model, the attribute will now appear as formatted to Rails in all forms and views. It will also be parsed back from that format (when assigned via forms) prior to insertion into the database. (The plugin also creates purely numeric unformatted_<attribute-name>accessors which can continue to be used for arithmetic, or for direct numerical assignment or retrieval by you for seamless integration.)
您可以使用number_format插件。通过number_format为模型中的现有数字属性指定 a ,该属性现在将在所有表单和视图中显示为 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
You can also combine the above with a Javascript solution, which can force the user to maintain the decimal point and thousands separators in place while editing, although this is really not necessary.
您还可以将上述内容与 Javascript 解决方案结合使用,这可以强制用户在编辑时保留小数点和千位分隔符,尽管这确实没有必要。
回答by Ian Terrell
If you want a format to be created or maintained during editing, you will need to add Javascript to implement "masks." Here is a demo.
如果要在编辑期间创建或维护格式,则需要添加 Javascript 来实现“掩码”。 这是一个演示。
It was the first hit in these results.
这是这些结果中的第一次命中。
回答by Tilendor
I have done something similar. We format times and lengths using a custom form builder. It makes use of the existing text_field, but wraps it so the value can be customized:
我做过类似的事情。我们使用自定义表单构建器格式化时间和长度。它利用现有的 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
And it is used like this:
它是这样使用的:
<%= form_for( @section, {:action => 'save', :id => @section.id}, :builder => SuperFormBuilder) do |sf| %>
<%= sf.length_field :feed_size_min_w, :size => 3, :scale => 'small' %>
<% end %>
The end result is a value in the appropriate unit based off their choice on system (Metric, Imperial) and scale IE small = inches or millimeters.
最终结果是基于他们在系统(公制、英制)和比例 IE 上选择的适当单位的值,小 = 英寸或毫米。
I basically copied the text_field method from the existing form builder, which uses the text_field_tag itself.
我基本上是从使用 text_field_tag 本身的现有表单构建器中复制了 text_field 方法。
There are two gotchas: 1) Knowing the name of the object field and how to access the object to get the value which you want to format. 2) Getting the name right so when the form is submitted it is part of the correct params hash.
有两个问题:1) 知道对象字段的名称以及如何访问对象以获取要格式化的值。2)正确获取名称,以便在提交表单时它是正确参数散列的一部分。
The form builder is given a class variable @object. You can get the value of the field using the .send method. In my case I send the label :feed_size_min_w to the @object and get its length back. I then convert it to my desired format, and give it to the text_field_tag.
表单构建器被赋予一个类变量@object。您可以使用 .send 方法获取字段的值。就我而言,我将标签 :feed_size_min_w 发送到 @object 并获取其长度。然后我将其转换为我想要的格式,并将其提供给 text_field_tag。
The name of the field is key to having it end up in the params hash, in my instance the params[:sections] one. I made a little helper function called field_name that takes care of this.
该字段的名称是使其最终出现在 params 哈希中的关键,在我的实例中是 params[:sections] 之一。我做了一个名为 field_name 的小辅助函数来处理这个问题。
Finally the has_error wraps the field in an error div if there are errors on that label.
最后,如果该标签上存在错误,则 has_error 将该字段包装在错误 div 中。

