禁用提交按钮,直到RAILS中的输入字段填写完毕

3
我希望在我的输入字段填写完毕之前禁用提交按钮。我对rails不是很熟悉,JS和Coffee也不太了解。我一直在尝试运行这个功能,但它没有起作用。我还试图在客户端进行验证,但无法使其工作,代码通过了,但即使所有字段都填写完毕,按钮仍然无法启用。由于某种原因,按钮仍然被禁用。
Html.haml
= simple_form_for @post, html: { multipart: true } do |f|
    - if @post.errors.any?
        #errors
            %h2
                = pluralize(@post.errors.count, "error")
                prevented this Post from saving
            %ul
                - @post.errors.full_messages.each do |msg|
                    %li= msg

    .form-group
        = f.input :title,:label => "Project Name", input_html: { class: 'form-control' }

    .form-group
        %label{:for => "Image"} image
        %input#image.form-control-file{"aria-describedby" => "fileHelp", :type => "file"}/

    .form-group
        %label{:for => "url-input"} Project Link
        %input#url-input.form-control{:type => "url", :value => "https://"}/

    .form-group
        %label{:for => "description"} Description
        %textarea#description.form-control{:rows => "3"}
        %small#descriptionHelp.form-text.text-muted Clear it up please

    %button#add.btn.btn-info{:type => "submit", :disabled => "disabled" } submit

Thanks in advance.


1
最初隐藏输入按钮。然后,在JavaScript中编写一个函数,在输入字段的更改事件上显示该按钮。 - Ajit
2个回答

5
您可以使用 JavaScript 或 jQuery 处理该验证。
$('#url-input, #description').on('blur keypress', function() {
  var urlInputLength = $('#url-input').val().length;
  var descriptionInputLength = $('#description').val().length;
  if (urlInputLength == 0 || descriptionInputLength == 0) {
    $('button').prop('disabled',true);
  } else {
    $('button').prop('disabled',false);
  }
});

确定在表单提交之前需要哪些输入元素。使用这些元素添加blurkeypress事件。使用if语句来确定按钮是启用还是禁用。如果输入长度为空(0),则可以使用.prop()方法禁用按钮元素,如果输入中有文本,则启用按钮。


按钮仍然因某种原因被禁用,即使在填充输入后!!代码虽然通过了,但我认为要么是我没有将JS发布到正确的位置。因为我仍然困惑是否将此代码粘贴到“application.js”还是“posts.coffee”。尽管我尝试了两者,但都没有起作用! - hekmat
%button#add.btn.btn-info{:type => "submit", :disabled => "disabled" } submit 上移除 :disabled => "disabled"。在 keypressblur 事件之外,禁用按钮 $('button').prop('disabled',true);。这是 jQuery,所以只要放在 application.js 中就可以了。 - Jon Lambson
抱歉,我不理解那一部分。在“keypress”和“blur”事件之外,禁用按钮$('button').prop('disabled',true); - hekmat

0

嗨,当进行客户端验证时,您想确保不会呈现新视图并允许客户端查看服务器端验证错误时,这可能会令人沮丧。因此,最好确保您的客户端验证表单具有可靠的自定义JS验证。客户端可以在每个字段中查看表单中的所有错误,直到所有字段都变为绿色和令人满意,然后才能启用提交按钮。最后,作为备份,如果表单仍然被提交,客户端将在创建操作else语句中看到服务器端验证。

首先,在您的new.html.erb视图中,无论您使用简单表格还是只是form_for,它都是相同的概念。

注意:表单包含novalidate:true,因为我想为每个字段创建自定义验证,因为默认浏览器验证缺乏太多。所以我可以根据自己的需求轻松制作自己的验证。

在视图中,确保您默认使用disabled:true, data: {disable_with: false},该按钮始终处于禁用状态,可以使用false禁用。

<%= form_for @post, html: {class: 'some-class some-validation-class', novalidate:true } do |f| %>

...
# All my fields are here

# My submit button important to note data_disabled

<%= f.submit "Publish", class: 'btn btn-sm btn-primary mb-0', id: "publish", disabled:true, data: {disable_with: false} %>

<% end %>

在您的JavaScript中,我假设您已经完成了所有变量,并且已经添加了所有事件监听器myField.addEventListener("input", (event) => {});showErrors();并适当地调用函数,因为用户输入并填写字段、单选框、选择器等。显示红色/绿色和错误,并利用validity.valueMissingvalidity.tooShortvalidity.tooLong甚至进一步自定义它们。当您完成验证时,需要在keyup上添加事件监听器。 在您的验证结束时,使用JavaScript启用/禁用提交按钮
const publishButton = document.getElementById("publish");

document.addEventListener('keyup', function(){ 
  if (isNameValid && isLocationValid && isPhoneValid && isSomethingValid){

    publishButton.disabled = false;

  } else {

    publishButton.disabled = true;
    // do more stuff

  }
});

最后在你的控制器中,如果创建操作失败,你不想渲染新的视图,甚至最终得到/posts的URL。因此,我建议在create操作中这样做。

posts_controller.rb

def create
  @post = current_user.posts.build(posts_params)
  
  if @post.save
    # or you can redirect to posts index, or root path or whatever.
    redirect_to edit_post_path(@post), notice: "Your post has been created successfully"
  else
    redirect_to request.referrer, flash: { error: @post.errors.full_messages.join(", ") }
  end

end

如果用户在前端做了一些奇怪的事情并故意提交了帖子或由于错误而提交了帖子,他们仍将收到完整的验证错误,但当然需要重新填写表格。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接