使用后如何防止退出阻止脚本禁用“提交”按钮

时间:2019-02-12 19:39:48

标签: javascript ruby-on-rails twitter-bootstrap simple-form

我有一个脚本来防止导航离开该页面,因此所做的更改不会意外丢失。不幸的是,如果通过提交表单激活​​了脚本,这也会“破坏”页面。因此,在按下提交按钮决定停留在页面上之后,我无法再提交表单。

当导航由提交按钮以外的其他操作完成时,不会禁用提交按钮。

有什么方法可以防止这种情况的发生,并允许我“意外地”多次激活该脚本,同时仍然可以在弹出窗口后使用提交按钮?

<script>
  window.onbeforeunload = function() {
    var inputs = document.getElementsByTagName('input');
    var unfinished = 'false';
    for (var i = 0; i < inputs.length; ++i) {
      if (inputs[i].value != '') {
        unfinished = 'true';
      }
    }
    if (unfinished == 'true') {
      return 'Are you sure you want to leave?';
    }
  }
</script>

在激活退出阻止程序之前(通过提交按钮):

<input type="submit" name="commit" value="Edit product" class="btn btn-warning btn-block" data-disable-with="Edit product">

激活退出阻止程序后(通过提交按钮):

<input type="submit" name="commit" value="Edit product" class="btn btn-warning btn-block" data-disable-with="Edit product" disabled="">

如您所见,由于某种原因,它在我的网站上添加了disabled=""

一种形式:

<%= simple_form_for @pack, url: pack_path(@pack), method: :patch do |f| %>
<%= render 'shared/error_messages', object: f.object %>
  <%= f.input :title, class: "form-control center" %>
  <%= f.input :pack_type, class: "form-control center" %>
  <%= f.input :category_id, prompt: "Select Category", collection: [ "sample-pack", "vocal-pack", "preset-pack", "track-pixel", "track-indie", "track-orchestral"], input_html: { class: "form-control center" } %>
  <%= f.input :price, class: "form-control center" %>
  <%= f.input :audio_embed, class: "form-control center" %>
  <%= f.input :video_embed, class: "form-control center" %>
  <%= f.input :art_link, prompt: "ENTER N/A IF STRACK", class: "form-control center" %>
  <%= f.input :download_url, class: "form-control center" %>
  <%= f.submit "Edit product", class: "btn btn-warning btn-block" %>
<% end %>
  <%= link_to "Cancel", packs_path, class: "btn btn-danger top-drop" %>

1 个答案:

答案 0 :(得分:1)

我花了一些时间,并建立了一个如何处理此类问题的示例。有几件事是不应该的;

  • 我创建了一个全局变量formSubmitting,该变量用于查看是否正在提交表单,并且在表单的onsubmit事件中将其设置为true
  • 我替换了在所有元素上运行的for循环,以使用querySelectorAllfilter的组合。如果您需要支持IE 11,则需要将调用filter替换为for循环进行相同的测试
  • 警告用户的过程如下:
    • 如果未提交表单
    • 如果表单没有disabled属性
    • 如果表单中的任何文本框都不为空为空
      • 警告用户有关离开页面的信息

// Global variable used to determin if the form is being submitted
// This is used to determine if the user is navigating away from the page
// or trying to submit the form
var formSubmitting = false;

function findNonEmptyInputsInForm(formName) {
  // the css selector we are using here breaks down like this
  // -  form[id="' + formName + '"]
  //    Find the specific formwe want to check the textboxes in
  // -  > fieldset 
  //    We are only interested in the fieldsets in that form
  // -  > input[type="text"]
  //    we only want the inputs in that fieldset that are textboxes

  var cssSelector = 'form[id="' + formName + '"] > fieldset > input[type="text"]';

  // Call filter on the Array to only find elements that
  return Array.prototype.filter.call(document.querySelectorAll(cssSelector), (e) => e.value != '')
}

window.onbeforeunload = function(e) {
  // check if the form is being submitted
  // we don't want to block the user from 
  // submittng the form
  if (!formSubmitting) {
    // reset the formSubmitting flag
    formSubmitting = false;
    // pull the disabled attribute from the form
    var formDisabled = document.forms["test"].getAttribute('disabled') === "";

    // check if the disabled attribute has been added
    // to the form, we don't want to prevent navigation
    // if the disabled attribute is on the form
    if (!formDisabled) {
      // find all the textboxes that have a value
      var noneEmptyElements = findNonEmptyInputsInForm('test');
      // check if the user has entered any values in the textbox
      // we don't want to prevent navigation if the user 
      // hasn't modified the form
      if (noneEmptyElements.length > 0) {
        // display the confirmation
        return 'Are you sure you want to leave?';
      }
    }
  }

  // reset the formSubmitting flag
  formSubmitting = false;
}
<form id="test" name="test" action="/" onsubmit="formSubmitting = true;">
  <fieldset form="test">
    <label for="test_input">Test Element 1</label>
    <input id="test_input" type="text" /><br/>


    <label for="test_input2">Test Element 2</label>
    <input id="test_input2" type="text" /><br/>


    <label for="test_input3">Test Element 3</label>
    <input id="test_input3" type="text" /><br/><br />

    <button type="submit">Submit</button>
  </fieldset>
</form>

这里是小提琴的链接,您可以使用它并添加/删除disabled属性。 JsFiddle Example