1

I'm checking the value of a form field and if the value is more than 5 an alert box pops up. This works, but I've noticed that if I fill in the field 1 time, the alert box can be closed normally. If I then enter a new value, also above 5, I need to close the alert box two times, and three times if I would enter a third value. And so on...

I read several related questions on Stackoverflow, but none seemed to be the same issue or related.

window.onload = function() {
  displayField();
};


function displayField() {
  jQuery('#groupnumber').change(function() {
    var amount5 = jQuery('#groupnumber').val();
    if (amount5 > 5) {
      alert('Alert message');
    }
  });
};

//Trigger javascript on leaving field
onblur = "displayField();"

So it "keeps score". If I enter a different value the second time and it is still above 5, I would like the alert box to just show once.

Thanks for any help!

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
Jason
  • 81
  • 1
  • 9
  • A shot into the dark: the codeline with onBlur is the source of your descibed problem. – Reporter May 28 '19 at 09:36
  • Debugging tip: add a `console.log` inside your methods to show when it's called. Add one inside `displayField` (not inside the change handler)) – freedomn-m May 28 '19 at 10:10

2 Answers2

1

The issue is because you call displayField() every time a blur event occurs which in turn adds another change event handler. Therefore when the next change happens all of those handlers are executed.

You can fix this by attaching your event unobtrusively. This way there will only ever be a single event added when the page loads, and it will fire whenever the selected event occurs on the element.

This does work, but has one disadvantage: if one would enter 78, the alert box shows directly after typing the 7, instead of showing when someone is ready with their input. How can that be avoided?

To mitigate that you could 'debounce' the event so that you only show the alert X milliseconds after typing has ended. You can use setTimeout() to do that:

jQuery(function($) {
  var timer;

  $('#groupnumber').on('input', function() {
    clearTimeout(timer);
    timer = setTimeout(function() {
      var amount5 = $('#groupnumber').val();
      if (amount5 > 5) {
        alert('Alert message');
      }
    }, 200);
  }).trigger('input'); // fire the event when the page loads
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="number" id="groupnumber" />

Note the aliasing of $ in the document.ready handler. This means you can still use $ within the block to refer to jQuery, making your code slightly less verbose.

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
  • This does work, but has one disadvantage: if one would enter 78, the alert box shows directly after typing the 7, instead of showing when someone is ready with their input. How can that be avoided? – Jason May 28 '19 at 13:45
  • 1
    You can debounce the event to fix that. Also note that not using a modal `alert()` for the message to the user would help a lot. – Rory McCrossan May 28 '19 at 13:49
  • @Jason [Link to another SO question with info about deboucing](https://stackoverflow.com/questions/56301312/how-to-animate-count-for-two-variables-separately/56301398#56301398) and another [link to SO question with info about roll-you-own dialog messages](https://stackoverflow.com/questions/54764414/prevent-modal-from-scrolling/54777154#54777154) – cssyphus May 28 '19 at 14:15
  • @Rory McCrossan: Thanks, what would you suggest instead of an alert box? – Jason May 28 '19 at 14:17
  • If you're trying to give information to your users try hiding/showing a hidden div with the message. – Rory McCrossan May 28 '19 at 14:18
  • @Jason Replacing the alert box is easier than you might think. See [this](https://stackoverflow.com/questions/54764414/prevent-modal-from-scrolling/54777154#54777154) and [this](http://jsfiddle.net/07bvb5Lz/) – cssyphus May 28 '19 at 14:18
  • @RoryMcCrossan Apologies for barging in on your discussion. I'll remove my comments if you wish. – cssyphus May 28 '19 at 14:20
  • 1
    @gibberish no problem, you can leave them. We're all here to help :) – Rory McCrossan May 28 '19 at 14:21
0

You can wrap your window.onload function with setTimeout so user have enough time to enter their number

window.onload = function() {
setTimeout(function(){
  displayField();
  }, 2000)
};


function displayField() {
  jQuery('#groupnumber').change(function() {
    var amount5 = jQuery('#groupnumber').val();
    if (amount5 > 5) {
      alert('Alert message');
    }
  });
};

//Trigger javascript on leaving field
onblur = "displayField();"
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="number" id="groupnumber" />
TheUnKnown
  • 681
  • 5
  • 29