2009-02-26 12 views
29

できるだけユーザーフレンドリーな編集フォームフィールドを作りたいと思います。たとえば、数値の場合は、フィールドをカンマで表示することができます(number_with_precisionなど)。Railsの編集フィールドに表示される値をどのようにフォーマットできますか?

これはディスプレイ側では簡単ですが、編集はどうですか?これを行う良い方法はありますか?

私はRails FormBuilderを使用しています。調べると、<attribute>_value_before_type_castを使ってフィールドの値を取得するInstanceTagを使用していることがわかりました。つまり、<attribute>が呼び出されることはありません。

+0

私があるのか​​どうかを知りたいので、私はこの質問に恵みを開始しました:

<%= f.text_field :my_number, :value => number_to_human(f.object.my_number, :separator => '', :unit => '', :delimiter => '', :precision => 0) %> 

あまりにも利用できるより多くの属性があります。 JDLと私自身が述べたものよりも良い答えです。それを持ってください! –

答えて

37

私は今のところ出ている最高のは、このようなものです:

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

+0

私は2番目の解決法を使用しないでください。あなたのモデルの中から 'ApplicationController'を参照することは、習慣を習うのは良いことではありません。 –

+0

最後の1つは私のためにはうまくいっていますが、私の関数はまだ私のデータモデルにある可能性があり、投稿や編集には影響しません。ニースの解決策! –

9

あなたの最初の回答が好きで、書式設定はビューで行います。ただし、モデルで書式設定を実行する場合は、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オブジェクトでこれをカバーしました。これの本当に巧妙な部分は、検証エラーを処理する方法です。それだけでそのエピソードを見る価値がある。

3

編集中にフォーマットを作成または維持する場合は、「マスク」を実装するためにJavascriptを追加する必要があります。 Here is a demo.

these resultsで最初にヒットしました。

+0

デモがもうありません。新しいものがあります:https://igorescobar.github.io/jQuery-Mask-Plugin/ – fatfrog

1

私は似たようなことをしました。カスタムフォームビルダを使用して、時間と長さをフォーマットします。これは、既存の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 %> 

最終結果は基づいて、適切な単位の値でありますシステム(Metric、Imperial)およびIEの小数=インチまたはミリメートルでの選択をオフにします。

私は基本的にtext_field_tagを使用する既存のフォームビルダからtext_fieldメソッドをコピーしました。

2つの問題があります:1)オブジェクトフィールドの名前とオブジェクトにアクセスして、書式設定する値を取得する方法を知っています。 2)フォームが提出されたときに正しい名前を取得すると、正しいparamsハッシュの一部になります。

フォームビルダには、クラス変数@objectが与えられています。 .sendメソッドを使用してフィールドの値を取得できます。私の場合は、@ objectにfeed_size_min_wというラベルを送り、長さを戻します。それから私の望む形式に変換し、それをtext_field_tagに渡します。

フィールドの名前は、paramsハッシュで終わるための鍵です。私のインスタンスでは、params [:sections] oneです。私はこれを担当するfield_nameという小さなヘルパー関数を作った。

最後に、そのラベルにエラーがある場合、has_errorはエラーdiv内のフィールドをラップします。

3

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の溶液を用いて上記を組み合わせることができ、これは実際には必要ではないが、編集中に小数点と数千の区切り文字をユーザーに強制的に維持させることができます。

+0

良いアイデア。私が今日テストしたRails 3では動作しません。 – Cheng

関連する問題