2

I am trying to disable the function I pass to addEventListener when the user clicks on submit. I put code in to prevent user from leaving page if they have entered data on any of the fields. This works fine. If the user tries to navigate away they get a warning as expected. However, I can't seem to figure out how to disable this feature once all of the fields are populated and the user clicks submit. As it stands, they are prompted to make sure they want to navigate away when they click on submit and I don't want this to happen when the user clicks submit.

I've tried something like the below, to try to unbind the beforeunload function based on submit, but this isn't working. I feel like this is the right general idea, but I'm struggling to make this work as I want it to.

$('form').submit(function() {
  $(window).unbind('beforeunload');
});

$(window).on('beforeunload',function(){
  return '';
});

The code below works as expected:

window.addEventListener('beforeunload', function (event) {
  console.log('checking form');

  let inputValue = document.querySelector('#myInput').value;

  if (inputValue.length > 0) {
    console.log(inputValue);
    event.returnValue = 'Are you sure you wish to leave?';
  }

  event.preventDefault();
});

If the user clicks submit I want the beforeunload function to be turned off essentially.

MTCoster
  • 5,868
  • 3
  • 28
  • 49
Steve Smith
  • 1,019
  • 3
  • 16
  • 38
  • You can't use `element.removeEventListener` with anonymous functions. If you'd like to remove it at some point, you need to make it into a function that can be referenced by name – enhzflep Jan 12 '19 at 21:40
  • @enhzflep Thanks for the information. So I have to write a separate function for removeEventListener? – Steve Smith Jan 12 '19 at 21:45
  • If I understand your question correctly, nope. The function that is to handle the event should have a name. From there, you have the following available: `element.addEventListener('eventName', functionName, false);` and then later-on, `element.removeEventListener('eventName', functionName); – enhzflep Jan 12 '19 at 22:16

3 Answers3

2

Was able to solve this problem using the suggestion that was made by Bipperty via this SO issue...Narrow Down BeforeUnload To Only Fire If Field Is Changed or Updated. Ultimately the code below is what I used to turn off beforeunload when submitting the form....

var submitting = false;

window.addEventListener("beforeunload", function (event) {
  console.log('checking form');

  let inputValue = document.querySelector('#myInput').value;
  if(inputValue.length > 0 && submitting === false) {
    console.log(inputValue);
    event.returnValue = 'Are you sure you wish to leave?';
  }

  event.preventDefault();

});

document.addEventListener("submit", function(event) { 
  submitting = true;
});
Steve Smith
  • 1,019
  • 3
  • 16
  • 38
0

If you bind a handler using .on() you can remove the bound event using .off()

$('form').submit(function() {
  $(window).off('beforeunload');
});

$(window).on('beforeunload',function(){
  return '';
});

However, I feel in your scenario you don't really need the beforeunload at all if you handle your form submit logically.

I've mocked up an example of how you can logically submit the form if a user chooses to submit the form based on a condition (in this case if all fields aren't filled).

$('form').on('submit', function (e) {
  var inputs = $(':text', this);
  console.log(inputs.length)
  var validInputs = inputs.filter(function () {
    return $(this).val().length;
  }).length;
  if (validInputs > 0 && validInputs < inputs.length) {
    var r = confirm("Are you sure you want to leave?");
    if (!r) e.preventDefault()
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<form action="http://google.com" method="get">
  <input name="a" placeholder="Input 1">
  <input name="b" placeholder="Input 2">
  <input name="c" placeholder="Input 3">
  <button type="submit">Submit</button>
</form>
Cue
  • 2,699
  • 1
  • 12
  • 13
  • Thank you for the information. I was doing this previously, but I was trying to get more specific about my form. Today if I use the above, it works, but when the user tries to navigate away from the page using a link, the above fires as well. I was trying to be field specific using the addeventlistener, but now I can't figure out how to disable each eventlistener. If there is a better way to go about what I'm trying to do I'm open to that as well. – Steve Smith Jan 12 '19 at 22:26
  • Are you implying that if, say you have 5 inputs, a user has filled at least 1 field but not all 5 then they are prompted and therefore the form is not submitted? – Cue Jan 12 '19 at 22:27
  • If all of the fields are filled in it still prompts the user to click to make sure they want to submit it. I don't want the are you sure to pop when user clicks on submit. – Steve Smith Jan 12 '19 at 22:42
  • See the code snippet I've created for you. Does this gear toward what you're trying to achieve? – Cue Jan 12 '19 at 22:43
  • I'm testing and it doesn't seem to be firing. The rest of my function is.. – Steve Smith Jan 12 '19 at 22:55
  • I'm using Django forms which is why this won't work. – Steve Smith Jan 12 '19 at 22:58
0

Update

To prompt the user before leaving a form:

window.onbeforeunload = function(){
  return 'Are you sure you want to leave?';
};

See this post


Use the required attribute on each field and you won't need to do all of that. The following demo will refuse any attempts to submit it's form if there's a blank field. It will send to a live test server and a response will be displayed verifying a successful submission.

Demo

window.onbeforeunload = function(){
  return 'Are you sure you want to leave?';
};
label {
  display: inline-block;
  width: 75px
}

[type=submit] {
  margin-left: 200px
}
<form id='form' action='http://httpbin.org/post' method='post' target='response'>


  <label>Name: </label><input name='Name' type='text' required><br>
  <label>Cell: </label><input name='Cell' type='tel' required><br>
  <label>Date: </label><input name='Date' type='date' required><br>

  <input type="submit">


</form>
<iframe src='about:blank' name='response'></iframe>
zer00ne
  • 41,936
  • 6
  • 41
  • 68
  • Thank you for the suggestion. I am trying to prevent user from navigating away from page when they have not completed form and if they have I am trying to allow the submission to work without a prompt. Are you suggesting your code will allow me to accomplish this? – Steve Smith Jan 12 '19 at 22:56
  • Have you tested this demo, yet? It's a real functioning form to a live test server. – zer00ne Jan 12 '19 at 22:57
  • `name.widget.attrs['required'] = 'required'` – zer00ne Jan 12 '19 at 23:02
  • Thank you. Yes I have the form set up to require these fields. That's not my issue. The issue is when I am trying to prevent user from navigating away from the page using the beforeunload function. I can' t seem to work out how to prevent beforeunload from firing when the user clicks submit. – Steve Smith Jan 12 '19 at 23:04
  • Have you tested my demo? After a real submission of data ther page is still there. – zer00ne Jan 12 '19 at 23:08
  • Will your code prevent user from navigating away from a page before they finish filling out the form? – Steve Smith Jan 12 '19 at 23:10
  • That;s hijacking a user's ability to navigate, which in turn is bad UX, – zer00ne Jan 12 '19 at 23:11
  • I want to prevent user from accidentally navigating away from page. They just have to click ok if they have started to fill out the form. – Steve Smith Jan 12 '19 at 23:13
  • Can I removeEvent listener on form submit? $('form').submit(function() { window.removeEventListener("beforeunload",); }); I tried this, but perhaps my syntax is not correct. – Steve Smith Jan 12 '19 at 23:39
  • @SteveSmith Sure but am easier way is t=to listen for a submit then use `e.preventDefault()`, see update, – zer00ne Jan 13 '19 at 00:06
  • Thanks for the suggestion. Will explore that avenue as well. Thanks for your input. I appreciate it. – Steve Smith Jan 13 '19 at 00:14