Rails - 如何实现唯一性的客户端验证?

时间:2021-11-03 16:21:08

I have a building model that consists of many blocks. When a user creates a new block, the name of the block cannot match the name of any other of the blocks associated with that building. I have figured out how to validate this on the backend, but I would also like to provide client-side validation to inform the user that the name is already in use by another block. It seems like this will require AJAX to pull off, but I'm having trouble figuring out how to link AJAX to a controller method. Here is what I have so far:

我有一个由许多块组成的建筑模型。当用户创建新块时,块的名称不能与该建筑物关联的任何其他块的名称匹配。我已经弄清楚如何在后端验证这一点,但我还想提供客户端验证,以通知用户该名称已被另一个块使用。看起来这将需要AJAX启动,但我无法弄清楚如何将AJAX链接到控制器方法。这是我到目前为止:

Blocks/_form.html.erb

<%= form_for(@block, :remote => true, :html => { 'data-controller-name' => controller_name.singularize }) do |f| %>
  <%= f.hidden_field :building_id %>
  …
  <div class="field">
    <%= f.label :name, :class => "required" %>
    <%= f.text_field :name, :class => "required", :placeholder => "Untitled block" %>
  </div>

Blocks.js

$('#block_name').blur(function() {
  $.ajax({
    url: 'blocks/check_name',
    success: function(data, textStatus, jqXHR) {
        $('#block_name').removeClass('error')
    },
    error: function(data, textStatus, jqXHR) {
        $("#block_name").addClass('error')
    }
  });
});

Routes.rb

"/blocks/check_name" => "blocks#check_name"

blocks_controller.rb

def check_name
  @building = Building.find(params[:block][:building_id])

  respond_to do |format|
    Format.json { render :json => @building.block_name_available(params[:block][:name]) }
  end
end

Building.rb

def block_name_available(name)
  @block = Block.where(:building_id => self.id, :name => name)
  Return @block.nil?
end

If there's a better way to go about this, I'm open to suggestions as well.

如果有更好的方法可以解决这个问题,我也愿意接受建议。

2 个解决方案

#1


0  

One strategy you could use with JavaScript would be to place a submit listener on your form, and call event.preventDefault() to stop the form from submitting. You could then make one ajax request that checks for uniqueness, with both success and error callbacks: on success, submit the form as normal, but on error, notify the user however you'd like that the block name must be unique.

您可以使用JavaScript的一种策略是在表单上放置提交侦听器,并调用event.preventDefault()以停止提交表单。然后,您可以使用成功和错误回调来创建一个检查唯一性的ajax请求:成功时,正常提交表单,但出错时,通知用户但是您希望块名称必须是唯一的。

#2


0  

Try :validate => true in the form_for block.

在form_for块中尝试:validate => true。

#1


0  

One strategy you could use with JavaScript would be to place a submit listener on your form, and call event.preventDefault() to stop the form from submitting. You could then make one ajax request that checks for uniqueness, with both success and error callbacks: on success, submit the form as normal, but on error, notify the user however you'd like that the block name must be unique.

您可以使用JavaScript的一种策略是在表单上放置提交侦听器,并调用event.preventDefault()以停止提交表单。然后,您可以使用成功和错误回调来创建一个检查唯一性的ajax请求:成功时,正常提交表单,但出错时,通知用户但是您希望块名称必须是唯一的。

#2


0  

Try :validate => true in the form_for block.

在form_for块中尝试:validate => true。