Rails 3 UJS 干客户端 +服务器端表单验证

发布于 2024-09-28 07:00:37 字数 202 浏览 7 评论 0原文

使用 jQuery 进行表单验证就像向字段添加类名一样简单。使用 Rails 进行表单验证就像将条件放入控制器(和/或模型)中一样简单。

我认为应该有一种方法可以编写一次验证并将它们应用到客户端和服务器端。我一直热衷于编写自己的 javascript,但凭借 Rails3 的不引人注目性,如果 UJS 能够实现这一目标,那么它在这里可能非常值得。

谢谢!!

Form validation with jQuery is as easy as adding a classname to a field. Form validation with rails is as easy as putting a condition in to your controller (and/or model).

I figure there should be a way to write the validations once and have them applied both client and server side. I've always been a fan of writing my own javascript, but with rails3 unobtrusivity UJS might be well worthwhile here if it can accomplish this.

Thanks!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

痕至 2024-10-05 07:00:37

您应该考虑创建自己的表单构建器来自定义 form_for 的行为。您可以执行一些操作,将类设置为属性上定义的验证名称,并将 jQuery 将自身绑定到相应的类名称。让我们从表单生成器的外观开始。

class ValidationFormBuilder < ActionView::Helpers::FormBuilder
  def text_field(object_name, method, options = {})
    options[:class] = object_name.class.validators_on(method).map do |k| 
      # Eg: ActiveModel::Validations::PresenceValidator -> presence
      k.to_s.slice(/[^:]+Validator$/).chomp('Validator').downcase
    end.join(' ')
    super(object_name, method, options)
  end
end

您需要设置 form_for 才能使用 ValidationFormBuilder。

<%= form_for @foo, :builder => ValidationFormBuilder do |f| %>
  <%= f.text_field :bar %>
<% end %>

... becomes something like

<form action="/foo" method="post">
  <input type="text" class="presence" name="foo[bar]" id="foo_bar">
</form>

如果您需要对类名称有更大的灵活性,您可能需要创建一个映射到所需字符串的散列。

class ValidationFormBuilder < ActionView::Helpers::FormBuilder
  MAPPINGS = {
    ActiveModel::Validations::PresenceValidator => 'text'
  }

  def text_field(object_name, method, options = {})
    options[:class] = object_name.class.validators_on(method).map do |k| 
      MAPPINGS[k]
    end.join(' ')
    super(object_name, method, options)
  end
end

您可以通过查看 Rails 源代码的 activemodel/lib/active_model/validations 来查看 Rails 中包含的验证的完整列表。我希望这足以让您开始。

You should look at creating your own form builder for customising the behaviour of form_for. You could do something that sets the class to the name of the validations defined on the attribute and have jQuery bind itself to the respective class names. Let's start with what the form builder might look like.

class ValidationFormBuilder < ActionView::Helpers::FormBuilder
  def text_field(object_name, method, options = {})
    options[:class] = object_name.class.validators_on(method).map do |k| 
      # Eg: ActiveModel::Validations::PresenceValidator -> presence
      k.to_s.slice(/[^:]+Validator$/).chomp('Validator').downcase
    end.join(' ')
    super(object_name, method, options)
  end
end

You'll need to setup form_for to use the ValidationFormBuilder.

<%= form_for @foo, :builder => ValidationFormBuilder do |f| %>
  <%= f.text_field :bar %>
<% end %>

... becomes something like

<form action="/foo" method="post">
  <input type="text" class="presence" name="foo[bar]" id="foo_bar">
</form>

If you need more flexibility over the class names, you might want to create a hash that maps to the desired string.

class ValidationFormBuilder < ActionView::Helpers::FormBuilder
  MAPPINGS = {
    ActiveModel::Validations::PresenceValidator => 'text'
  }

  def text_field(object_name, method, options = {})
    options[:class] = object_name.class.validators_on(method).map do |k| 
      MAPPINGS[k]
    end.join(' ')
    super(object_name, method, options)
  end
end

You can see the complete list of validations included in Rails by peeking in activemodel/lib/active_model/validations of the Rails source code. I hope that's enough to get you started.

苍白女子 2024-10-05 07:00:37

您可以使用 RJS 进行服务器端验证(并且它不取决于您是否使用 UJS):

# create.js.haml
= render :partial => "shared/flash_messages", :locals => { :flash => flash }

- if @message.errors.any?
  $('#reply_message').html('#{escape_javascript(render(:partial => "message_form"))}');
- else
  $('ul.data_grid .list').append('#{escape_javascript(render "message", :message => @message)}');
  $('#reply_message textarea').val('');

You can use server side validation using RJS (and it doesn't depend on you are using UJS or not):

# create.js.haml
= render :partial => "shared/flash_messages", :locals => { :flash => flash }

- if @message.errors.any?
  $('#reply_message').html('#{escape_javascript(render(:partial => "message_form"))}');
- else
  $('ul.data_grid .list').append('#{escape_javascript(render "message", :message => @message)}');
  $('#reply_message textarea').val('');
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文