2012-05-30 17 views
0

我有一个表单需要根据选择框中的不同选项进行更改。我需要的选择框有以下选项: 付费&礼品(均显示这两个字段), 仅付费(仅显示付费字段), 仅礼品(仅显示礼品字段)。Rails 3:如何用选择框更改表单?

这涉及2个属性:付费和:礼物。有没有办法让两个属性都有一个f.collection选择框?我知道我可能必须使用jQuery来显示和隐藏表单字段,并且这些字段是强制性的(validates_presence_of),基于选择...有关如何执行此操作的任何建议?

_rewards_step.html.erb

<h2>rewards</h2> 

    <p> 
<%= f.collection_select :pay, Upload::REWARDS, :to_s, :to_s %> 
    </p> 
    <p id="payfields"> 
    <%= f.label :pay %><br /> 
    <%= f.text_field :pay %> 
    </p> 
    <p id="giftsfields"> 
    <%= f.label :gifts %><br /> 
    <%= f.text_field :gifts %> 
    </p> 

upload.rb

class Upload < ActiveRecord::Base 
attr_accessible :pay, :gifts 
attr_writer :current_step 

validates_presence_of :pay, :if => lambda { |u| u.current_step == "rewards" } 
validates_presence_of :gifts, :if => lambda { |u| u.current_step == "rewards" } 

REWARDS = ['Pay & Gifts', 'Pay Only', 'Gifts Only'] 

回答

1

您正在将选择和输入的付费字段用作文本。它可能不会很好,我建议你创建一个额外的领域供选择。如果它只是一个虚拟属性就足够了,不需要将它存储在数据库中,但是您需要它来进行验证。

jQuery的部分隐藏字段:

$("#rewards").change(function(){ 
    if ($("#rewards").val()=="Pay Only") {$("#gift_field").hide(); $("#pay_field").show(); } 
    if ($("#rewards").val()=="Gift Only") {$("#gift_field").show(); $("#pay_field").hide(); } 
    if ($("#rewards").val()=="Pay & Gift") {$("#gift_field").show(); $("#pay_field").show(); } 
}) 

当然,你需要的ID和值调整到您的代码。

验证的一部分能够与:if

attr_accessor :reward_type 
validates_presence_of :pay, :if => lambda { |u| u.current_step == "rewards" && reward_type != "Gift Only" } 
validates_presence_of :gifts, :if => lambda { |u| u.current_step == "rewards" && reward_type != "Pay Only" } 

被欺骗,这只是解决方案的骨架,想想吧。

+0

感谢您的信息...我一直有一个问题分配一个id到选择框。这是我目前有的:<%= f.collection_select:reward_type,Upload :: REWARDS,:to_s,:to_s,:id =>“奖励”%>。这条线有什么问题吗? – user1341808

+0

是的,你的id用作select的选项,而不是HTML选项。试试这个:<%= f.collection_select:reward_type,Upload :: REWARDS,:to_s,:to_s,{},{:id =>“奖励”}%>' – Matzi

+0

woohoo!这样可行 – user1341808

0

嗯,一般来说,你是对的,你将不得不使用JavaScript来更新基于DOM在选择框中进行选择。您可以绑定到选择框本身的“更改”事件。类似于:

$('select#my_select_box_id').change(function(){ 
    //take a decision based on $(this).val() 
    $('p#giftsfield').show() //or hide based on what you want 
}) 

但我不确定您的代码是否可以像这样工作。您将选择框命名为“付费”,并在下方有一个具有相同名称的文本字段。我认为第二个属性会覆盖第一个属性。此外,您的条件验证采用与条件相同的lambda。因此,这两个属性将在满足条件时进行验证。但我当然不完全知道这个例子:-)。

+0

你会推荐为选择框创建一个单独的属性吗? – user1341808

+0

当然。下面的东西看起来不错。虽然我认为没有必要将to_s符号传递给collection_select。 – Renra

相关问题