Onblur function keeps running - javascript

I have an onblur event that will cause an error window to popup if incorrect data is input. The problem is, when I try to close the webpage, or click any other window, the onblur event will activate and the popup will come up again... Anyone have an idea how to fix this?
Here is a simplified version of the code
<input id="M3_pos_tab" type="text" maxlength="5" name="Blank" size="5" onblur="CheckFS();"/>
<script type="text/javascript">
function CheckFS()
{
var FS_pos = parseFloat(FS_tab.value);
if ((FS_pos == 0) || (FS_pos == parseFloat(L_tab.value)) || (isNaN(FS_pos))) {
} else {
window.alert("Error");
FS_tab.select();
FS_tab.focus();
return;
}
}

I think your problem is that when the error box appears, it takes the focus and therefore it triggers onblur at the element. I found this out at https://javascript.info/focus-blur, which says
A focus loss can occur for many reasons. One of them is when the visitor clicks somewhere else. But also JavaScript itself may cause it, for instance:
An alert moves focus to itself, so it causes the focus loss at the element (blur event), and when the alert is dismissed, the focus comes back (focus event).
I therefore suggest removing the line
window.alert("Error");
and to see if the problems persists.

If you are using a form you can utilize onsubmit.
<form action="onsubmit.htm" onsubmit="return CheckInput();">
<!-- input -->
<input type="submit" value="send">
</form>
<script type="text/javascript">
function CheckInput () {
// things you want to check
</script>
If CheckInput() returns true the form will be submitted, if it returns false the form will not be sumbitted.

I'm not sure how foolproof this is, but you could check the active element on blur. At least in Chrome, the onblur event will still fire when you click on a different window or tab, but the active element will still be the input, and not something else on the page. Kinda hacky solution, but it might work for you:
Sample fiddle
function CheckFS() {
if (document.activeElement == FS_tab) {
// if the input is still the active element,
// then we haven't focused anything else on the page,
// so we must have focused something else off of the page
return;
}
var FS_pos = parseFloat(FS_tab.value);
if ((FS_pos == 0) || (FS_pos == parseFloat(L_tab.value)) || (isNaN(FS_pos))) {
} else {
window.alert("Error");
FS_tab.select();
FS_tab.focus();
return;
}
}

Related

Narrow Down BeforeUnload To Only Fire If Field Is Changed or Updated

I am trying to figure out how to limit the beforeunload command on my form. I have been able to figure out how to unbind the beforeunload command and then when I go to navigate away from the form this works. However, the unload happens every time regardless of whether or not the form was changed. I'm trying to figure out how to get the beforeunload to only fire if the form was actually updated or changed. If the user clicks the back button on the browser, the beforeunload does not fire. This is perfect. However, if the user clicks on a link on the "form" it pops up the beforeunload prompt. Is this as designed? Perhaps I should be approaching this differently? I'm a newbie..so I'm open to suggestions.
I have read through the MDN link that explains beforeunload...https://developer.mozilla.org/en-US/docs/Web/Events/beforeunload
and can't seem to figure out how to narrow down the beforeunload to only if a field on the form has been changed.
$('form').submit(function() {
$(window).unbind('beforeunload');
});
$(window).on('beforeunload',function(){
return '';
});
I am trying to figure out how to alter the code above so that the beforeunload only fires if a field on my form changes when the user goes to navigate away from this page. It's confusing for the user if there is a pop up asking if they want to navigate away from the page if nothing has been clicked or changed.
Something like this.
We check out simple form and only prompt user if there is a value.
Added variable set when submitting, this allows us to bypass our onunload tests.
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;
});
<form submit="somewhere.htm">
<input id="myInput" type="text" />
<input type="submit" value="Submit">
</form>
Test navigate away

How to display require popup manually?

I'm trying to display the require popup when a certain input is not filled or isn't filled correctly in my form. So, for doing this, I've created this form:
<form id="login">
<input class="form-control require" type="email" placeholder="username" ></input>
<button type="submit">
go
</button>
</form>
and I put the logic inside a js function:
$('#login').submit(function(event)
{
event.preventDefault();
$(event.target).find('.require').each(function()
{
if($(this).val().length == 0)
{
this.setCustomValidity("Field Required!");
}
else
{
this.setCustomValidity('');
}
});
console.log('ajax execution');
});
Now how you can see when the form is submitted I prevent the default event submit, and assign to each control a custom validation error. Now the problem's that if a field is not valorized correctly, for example is blank I get no popup displayed, instead, if I press again the submit button I can see the require popup appear on the UI.
Someone could help me to fix this?
I put an example JSFIDDLE here.
When you press the button for the first time no popup appear, the second time appear correctly but, this should appear the first time or anyway, each time that a particular field is not valid.
if($(this).val().length == 0) this code will not properly if the input field has only space . To avoid that u should use this:
if($.trim($(this).val()).length == 0)
OR
if($.trim($(this).val()) == "")
Your problem seems to be that the submit event is only firing once. I'm not familiar with bootstrap, so I haven't seen the setCustomValidity function before but I would guess that it is probably attaching its own listener, which is prevent the button click from triggering the submit at all.
I notice that if I type something into the text box, and fire setCustomValidity on it, it says "please enter an email address" - which I don't see in your code. If I then enter 'asdf#qwer.dfsgh', it gets validated and submits.
So it looks like you have not understood how setCustomValidity is supposed to be used. I would guess, you are probably supposed to attach it once, when the page first loads, and not repeatedly as you are doing.

Reading an HTML input field entered without a final Return

I have an input element in this jsfiddle: http://jsfiddle.net/stevea/DLe3a/9. If I enter Return after putting something in the field I trigger the change handler and pick up and display the value fine:
$(function() {
$('input#fname').change(function(e) {
$('div#firstName').append(this.value);
});
But what if the user forgets to hit return and closes down the page? I want to come back, in that case, when I sense the page shutting down, and pull out what was entered into the Input field without a Return.
Can I do that? In the jsfiddle I have a button and its handler. Assuming the button click is shutting down the page, how would I respond to the button click to get the value sitting in the input field?
Thanks
Try this sir
$(function() {
$("#fname").change(function(e) {
$("#firstName").append(this.value)
});
$("#getInput").click(function (e) {
});
});
To detect if the page is closing, use the .unload() event
$(window).unload(function() {
var input = $('#fname').val();
});
I believe that you want to do some code when the window is pre-closed.
Here is some sample code: jsDiddle
$('#fname').change(function () {
$('#firstName').append(this.value);
});
window.onbeforeunload = function (e) {
var e = e || window.event;
// get input #fname
$('#firstName').append($('#fname').val());
// do something you want before the window closes
// show confirm message (optional) - if you don't want show message, return '';
//IE & Firefox
if (e) {
e.returnValue = 'You have some unfilled inputs!';
}
// For Safari
return 'You have some unfilled inputs!';
};
The problem isn't detecting a page closing down. The problem is to capture an Input field's content when something external happens before the user enters Return. But after playing around with it more, at this jsfiddle - http://jsfiddle.net/stevea/bT54M/3/ - it turns out that there really is no problem. If you're in the middle of entering text into an Input field and you do something external, like hitting the Get Input button in the jsfiddle above, the change event for the Input is triggered automatically and this.value is what you've entered so far. So the bottom line is that you don't need to hit Return when you're done. Just about anything you do outside of the Input (probably anything that blurs the Input focus) triggers the Input change event.
$(function() {
$('input#fname').change(function(e) {
debugger;
$('div#firstName').append(this.value);
});
$('#getInput').click(function() {
debugger;
$('div#firstName').append(this.value);
});
});

Why is my onchange function called twice when using .focus()?

TLDR
Check this example in chrome.
Type someting and press tab. see one new box appear
type something and press enter. see two new boxes appear, where one is expected.
Intro
I noticed that when using enter rather then tab to change fields, my onchange function on an input field was firing twice. This page was rather large, and still in development (read: numerous other bugs), so I've made a minimal example that shows this behaviour, and in this case it even does it on 'tab'. This is only a problem in Chrome as far as I can tell.
What it should do
I want to make a new input after something is entered into the input-field. This field should get focus.
Example:
javascript - needing jquery
function myOnChange(context,curNum){
alert('onchange start');
nextNum = curNum+1;
$(context.parentNode).append('<input type="text" onchange="return myOnChange(this,'+nextNum+')" id="prefix_'+nextNum+'" >');
$('#prefix_'+nextNum).focus();
return false;
}
HTML-part
<div>
<input type="text" onchange="return myOnChange(this,1);" id="prefix_1">
</div>
the complete code is on pastebin. you need to add your path to jquery in the script
A working example is here on jFiddle
The onchange gets called twice: The myOnChange function is called, makes the new input, calls the focus(), the myOnChange gets called again, makes a new input, the 'inner' myOnChange exits and then the 'outer' myOnchange exits.
I'm assuming this is because the focus change fires the onchange()?. I know there is some difference in behaviour between browsers in this.
I would like to stop the .focus() (which seems to be the problem) to NOT call the onchange(), so myOnChange() doesn't get called twice. Anybody know how?
There's a way easier and more reasonable solution. As you expect onchange fire when the input value changes, you can simply explicitly check, if it was actually changed.
function onChangeHandler(e){
if(this.value==this.oldvalue)return; //not changed really
this.oldvalue=this.value;
// .... your stuff
}
A quick fix (untested) should be to defer the call to focus() via
setTimeout(function() { ... }, 0);
until after the event handler has terminated.
However, it is possible to make it work without such a hack; jQuery-free example code:
<head>
<style>
input { display: block; }
</style>
<body>
<div></div>
<script>
var div = document.getElementsByTagName('div')[0];
var field = document.createElement('input');
field.type = 'text';
field.onchange = function() {
// only add a new field on change of last field
if(this.num === div.getElementsByTagName('input').length)
div.appendChild(createField(this.num + 1));
this.nextSibling.focus();
};
function createField(num) {
var clone = field.cloneNode(false);
clone.num = num;
clone.onchange = field.onchange;
return clone;
}
div.appendChild(createField(1));
</script>
I can confirm myOnChange gets called twice on Chrome. But the context argument is the initial input field on both calls.
If you remove the alert call it only fires once. If you are using the alert for testing only then try using console instead (although you need to remove it for testing in IE).
EDIT: It seems that the change event fires twice on the enter key. The following adds a condition to check for the existence of the new field.
function myOnChange(context, curNum) {
nextNum = curNum+1;
if ($('#prefix_'+nextNum).length) return false;// added to avoid duplication
$(context.parentNode).append('<input type="text" onchange="return myOnChange(this,'+nextNum+')" id="prefix_'+nextNum+'" >');
$('#prefix_'+nextNum)[0].focus();
return false;
}
Update:
The $('#prefix_'+nextNum).focus(); does not get called because focus is a method of the dom object, not jQuery. Fixed it with $('#prefix_'+nextNum)[0].focus();.
The problem is indeed that because of the focus(), the onchange is called again. I don't know if this is a good sollution, but this adding this to the function is a quick sollution:
context.onchange = "";
(The onchange is called again, but is now empty. This is also good because this function should never be called twice. There will be some interface changes in the final product that help with problems that would arise from this (mistakes and all), but in the end this is something I probably would have done anyway).
sollution here: http://jsfiddle.net/k4WKH/2/
As #johnhunter says, the focus does not work in the example, but it does in my complete code. I haven't looked into what's going on there, but that seems to be a separate problem.
maybe this some help to anybody, for any reason, in chrome when you attach an event onchage to a input text, when you press the enterkey, the function in the event, do it twice, i solve this problem chaged the event for onkeypress and evaluate the codes, if i have an enter then do the function, cause i only wait for an enterkey user's, that not works for tab key.
input_txt.onkeypress=function(evt){
evt = evt || window.event;
var charCode = evt.which || evt.keyCode;
if(charCode === 13) evaluate( n_rows );
};
Try this example:
var curNum = 1;
function myOnChange( context )
{
curNum++;
$('<input type="text" onchange="return myOnChange( this )" id="prefix_'+ curNum +'" >').insertAfter( context );
$('#prefix_'+ curNum ).focus();
return false;
}
jsFiddle.

HTML form with single text field + preventing postback in Internet Explorer

I have noticed a rather strange behaviour in IE.
I have a HTML form with a single input text field and a submit button
On Submit click I need to execute a client side JavaScript function that does the necessary.
Now when I want to prevent the postback in the text field (on enter key press).
I have added a key press JavaScript function that looks like this:
<input type=text onkeypress="return OnEnterKeyPress(event)" />
function OnEnterKeyPress(event) {
var keyNum = 0;
if (window.event) // IE
{
keyNum = event.keyCode;
}
else if (event.which) // Netscape/Firefox/Opera
{
keyNum = event.which;
}
else return true;
if (keyNum == 13) // Enter Key pressed, then start search, else do nothing.
{
OnButtonClick();
return false;
}
else
return true;
}
Strangly this doesn't work.
But if I pass the text field to the function :
<input type=text onkeypress="return OnEnterKeyPress(this,event);" />
function OnEnterKeyPress(thisForm,event) {
var keyNum = 0;
if (window.event) // IE
{
keyNum = event.keyCode;
}
else if (event.which) // Netscape/Firefox/Opera
{
keyNum = event.which;
}
else return true;
if (keyNum == 13) // Enter Key pressed, then start search, else do nothing.
{
OnButtonClick();
return false;
}
else
return true;
}
I am able to prevent the postback.
Can anyone confirm what is exactly happening here?
The HTML form has just one text box and a submit button.
The resultant output of the JavaScript function executed on submit is displayed in a HTML text area in a separate div.
Found out a work around for this issue.
i just found out that in IE, if,in a form, there is just one text field and one submit button, pressing enter results in form submit. However if there are more than one text boxes, IE doesn't auto postback the form on enter press, instead it fires the button's onclick event.
So i introduce a hidden text field in the form and everything works magically.
I donot even need to handle the onkeypress event for the text field.
<Form>
<input type="text" />
<input type="text" style="display:none"/>
<input type="submit" onClick="callPageMethod();return false;"/>
</Form>
This works perfectly for me!!
This is not an issue in FF, as pressing enter directly results in call to submit button's onclick event.
Hi you can also disable the default behavior.
jQuery('#yourInput').keydown(function (e) {
if (e.keyCode == 13) {
e.preventDefault();
}
});
Cheers!
Return false in the onsubmit which is used to submit the form via javascript.
There must be some interaction with other code you haven't posted. Your code stops the form submission for me in both variants and there is no reason it shouldn't.
But trapping Enter keypresses is difficult to do properly and is likely to annoy as much as anything else. There is almost always a better way.
For example, as altCognito suggests, have ‘form.onsubmit’ return false so the form never submits in response to user interaction. Also, if you put your AJAX code (assuming that's what you're doing) in the onsubmit handler instead of onclick on a button, you can also make it so that pressing Enter has the same effect as clicking on the submit button, which the user might normally expect.
If you don't want that, there seems to be no reason to include the <form> element at all. It's perfectly valid to just have input elements sitting on their own, if you never expect the browser to submit them anywhere.
Have just come here because of a related observation with at least IE 7 and 8:
If there is only one text input and one submit button on a form and the user presses return key, IE will not include the submit button's name/value-pair in the request. Insead, only the text input's value will be there.
If I add another text input, both text inputs and the submit button's parameters are posted. The second text input can even be hidden: <input type="text" style="display:none"/>
So this is not related to events but rather to simple form submission.
It happens with GET and POST. Adding a select element to the form does not change the behavior. -- very strange.

Categories