我有一个用户登录表单:
<%= form_tag(@action, :method => "post", :name => 'signup' ,:onSubmit => 'return validate();') do %>
<%= label_tag(:user, "Username:") %>
<%= text_field_tag(:user) %>
我想在之后检查数据库中是否有用户名:user-field lost focus。我可以使用javascript在表单上覆盖此事件,但我无法从javascipt代码发送Ruby-AJAX请求。
有没有办法检查用户名而不在表单上添加其他控件(按钮,链接)?
答案 0 :(得分:35)
你可以使用一些JavaScript(这是用jQuery编写的)用于AJAX cheking:
$(function() {
$('[data-validate]').blur(function() {
$this = $(this);
$.get($this.data('validate'), {
user: $this.val()
}).success(function() {
$this.removeClass('field_with_errors');
}).error(function() {
$this.addClass('field_with_errors');
});
});
});
此JavaScript将查找属性为data-validate
的所有字段。然后它确定onBlur
事件处理程序(焦点在JavaScript世界中丢失)。模糊处理程序将AJAX请求发送到data-validate
属性中指定的URL,并使用输入值传递参数user
。
接下来修改您的视图,添加带有验证网址的属性data-validate
:
<%= text_field_tag(:user, :'data-validate' => '/users/checkname') %>
接下来添加路线:
resources :users do
collection do
get 'checkname'
end
end
最后一步创建验证:
class UsersController < ApplicationController
def checkname
if User.where('user = ?', params[:user]).count == 0
render :nothing => true, :status => 200
else
render :nothing => true, :status => 409
end
return
end
#... other controller stuff
end
答案 1 :(得分:0)
你为什么不能从javascript代码发送ajax请求?
最好的方法是在焦点丢失时发送GET ajax请求。然后,get请求可以返回true或false,然后您的javascript可以在页面上反映出来。
答案 2 :(得分:0)
我在另一篇文章中回答了这个问题。
如果您不想使用现有的jquery插件从头开始编写表单,那么这是一种验证表单的友好方式。看看吧,如果你愿意,请告诉我!
答案 3 :(得分:0)
@Viacheslav 的解决方案运行良好,我的答案是结合他和我自己的更改(尤其是 JS) 部分。
我们将使用 Ajax
来实现这一目标。
让我们首先在控制器中创建我们的函数
def checkname
if !User.find_by_display_name(params[:dn])
render json: {status: 200}
else
render json: {status: 409}
end
return
end
然后在 routes
routes.rb
resources :yourcontroller do
collection do
get 'checkname'
end
end
现在让我们了解视图。您将在下方看到输入:
.field
= f.text_field :display_name, onblur: "checkDisplayName.validate(this.value)"
%p.error-name.disp-none username exists
现在在JS
的帮助下,我们开始施展魔法了。 Blow JS
的功能很少。 validate
进行实际验证。 getStatus
是我们获取状态的 Ajax
调用,我们使用 showError
和 disableSubmitButton
使我们的表单更生产就绪显示错误和禁用提交按钮。
var checkDisplayName = {
validate: function(dn){
checkDisplayName.getStatus(dn).then(function(result) {
if (!!result){
if (result.status != 200){
checkDisplayName.disableSubmitButton(true);
checkDisplayName.showError();
} else{
checkDisplayName.disableSubmitButton(false);
}
}
});
return false;
},
getStatus: async (dn) => {
const data = await fetch("/pages/checkname?dn=" + dn)
.then(response => response.json())
.then(json => {
return json;
})
.catch(e => {
return false
});
return data;
},
showError: function() {
let errEl = document.getElementsByClassName('error-name')[0];
if (!!errEl) {
errEl.classList.remove("disp-none");
window.setTimeout(function() { errEl.classList.add("disp-none"); },3500);
}
},
disableSubmitButton: function(status){
let button = document.querySelector('[type="submit"]');
button.disabled = status;
}
};