如何格式化Rails编辑字段中显示的值?

问题描述:

我想尽可能方便地编辑表单域。例如,对于数字值,我希望字段以逗号(例如number_with_precision)显示。如何格式化Rails编辑字段中显示的值?

这在显示器端很容易,但编辑怎么样?有没有一个好的方法来做到这一点?

我正在使用Rails FormBuilder。经过调查,我发现它使用InstanceTag,它使用<attribute>_value_before_type_cast获取字段的值,这意味着覆盖<attribute>不会被调用。

+0

我已经开始在这个问题上的赏金,因为我想知道如果有一个比JDL和我自己阐述的更好的答案。有它! – 2009-03-04 16:41:08

我想出了迄今为止最好的是这样的:

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

这似乎很多工作。

+0

注意:如果您使用带有逗号或货币符号格式的第一个解决方案,则需要将其排除在控制器的创建和更新方法中。 – LeBleu 2013-08-20 20:06:53

+0

我会避免使用第二种解决方案,在您的模型中引用`ApplicationController`对于养成习惯绝对不是好事。 – 2015-05-01 21:06:14

+0

最后一个对我来说最合适,我的功能仍然可以在我的数据模型中,并且不影响提交或编辑。好的解决方案 – 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