根据复选框值分配模型实例属性

时间:2014-11-04 15:33:01

标签: jquery ruby-on-rails forms checkbox input

我的用户模型具有stage_namereal_name字符串属性。我想要做的是在_form.hmlt.erb的实名输入框旁边有一个复选框,询问,真实姓名是舞台名称吗?。如果选中,则我希望将实名指定为阶段名称,并立即禁用阶段名称input box with real_name`实名作为其值。到目前为止,我有:

_form.html.erb

<%= form_for @user do |f| %>
  <div>
    <%= f.text_field :stage_name %>
    <%= f.text_field :stage_name %> 
  </div>

  <div>
    <%= f.text_field :real_name %>
    <%= f.text_field :real_name %>

    # Not sure how to bind my model code to this checkbox
    <%= f.checkbox %>
    <%= f.label 'Real name is stage name?' %>
  </div>

  <div>
    <%= f.submit %>
  </div>
<% end %>

<script>
  $(function() {
    $("input[type='checkbox']").click(function() {
      var $checkbox   = $(this),
          $secondForm =  $("input[type='text']").eq(2);

      if ($checkbox.is(":checked")) {
        $secondForm.attr("disabled", true).val("<%= @user.real_name %>");
      } else {
          $secondForm.attr("disabled", false).val("");
      }
    });
  )};
</script>

2 个答案:

答案 0 :(得分:1)

您需要做的就是在模型中指定属性访问器。

attr_accessor :real_name_is_stage_name

这将在模型中创建一个非持久属性,您可以在其中一个回调中检查,如果值为1,则设置real_name = stage_name,例如:

before_save do
  if real_name_is_stage_name == "1"
    real_name = stage_name
  end
end

然后设置复选框以与您所做的更改进行交互,以便您可以将复选框的值发送到模型,如下所示:

<%= f.check_box :real_name_is_stage_name %>

如果您这样做,在javascript代码中,只有在选中text_field并且rails将执行剩余工作时才需要禁用舞台名称check_box

<强> Model.rb

class Model < ActiveRecord::Base
  attr_accessor :name_check
  ## Validation
  ## Callbacks
  before_validation do 
    if self.name_check == "1" and self.stage_name.present? and !self.real_name.present?
      self.real_name = self.stage_name
    end
  end
end

<强> _form.html.erb

<%= form_for @user do |f| %>
    <%= render 'shared/error_messages', object: @user %>

    <div>
        <%= f.label :stage_name %><br>
        <%= f.text_field :stage_name %>
    </div>

    <div>
        <%= f.label :real_name %><br>
        <%= f.text_field :real_name %>
        <div>
            <%= f.label :name_check, 'Real Name is Stage Name?' %>
            <%= f.check_box :name_check, value: f.obj.real_name.eql?(f.obj.stage_name)? "1" : "0" if f.obj.real_name.present? and f.obj.stage_name.present? %> %>
        </div>
    </div>

    <div>
        <%= f.label :origin %><br>
        <%= f.text_field :origin %>
    </div>

    <%= f.submit %>
<% end %>

<%= render 'scripts' %>

<强> _scripts.html.erb

<script>
    $(function() {  
        var $nameCheck = $('#artist_name_check'),
            $stageName = $('#artist_stage_name'),
            $realName  = $('#artist_real_name'),
            $originalVal = $stageName.val();

        // Checks and mirrors artist's real name and stage name

        if ($nameCheck.is(':checked')) {
            $stageName.attr("readonly", "readonly");
        }

        $nameCheck.click(function() {
            if ($nameCheck.is(":checked")) {
              $stageName.attr("readonly", "readonly").val($realName.val());
            } else {
                $stageName.attr("readonly", false).val($originalVal).focus();
            }
        });
    });
</script>

答案 1 :(得分:0)

管理创建一个优雅的基于脚本的解决方案,不需要后端逻辑。需要注意的一件非常重要的事情是,使用输入框的disabled属性可以防止保存数据。相反,我使用readonly并在取消选中时将其设置为false。最重要的一点是确定如何保持复选框的选中/取消选中,尽管它不是模型的一部分。通过使用第一个条件使这一切成为可能。

总而言之,当文档加载脚本时,首先检查阶段名称的值是否等于真实姓名的值。如果是,则选中复选框。进入编辑视图后,单击功能用于切换实名输入值的状态。

<强> _form.html.erb

<%= form_for @user do |f| %>
    <%= render 'shared/error_messages', object: @user %>

    <div>
        <%= f.label :stage_name %><br>
        <%= f.text_field :stage_name %>
    </div>

    <div>
        <%= f.label :real_name %><br>
        <%= f.text_field :real_name %>
        <div>
            <%= label_tag 'user_name_check', 'Real Name is Stage Name?' %>
            <%= check_box_tag 'user_name_check' %>
        </div>
    </div>

    <div>
        <%= f.label :origin %><br>
        <%= f.text_field :origin %>
    </div>

    <%= f.submit %>
<% end %>

<%= render 'scripts' %>

<强> _scripts.html.erb

<script>
    $(function() {  
        var $nameCheck = $('#user_name_check'),
            $stageName = $('#user_stage_name'),
            $realName  = $('#user_real_name'),
            $originalVal = $stageName.val();

        // Checks and mirrors user's real name and stage name

        if ($realName.val() == $stageName.val() && $realName.val() != '') 
            $stageName.attr({
              checked:  'checked',
              readonly: 'readonly'
            });
        }

        $nameCheck.click(function() {
            if ($nameCheck.is(':checked')) {
              $stageName.attr('readonly', 'readonly').val($realName.val());
            } else {
                $stageName.attr('readonly', false).val($originalVal).focus();
            }
        });
    });
</script>