Reputation: 141
Alert boxes in infinite loop, here I am trying to put a popup alert message on 2 consecutive fields so they cannot be left blank, I know why it is happening - because when onblur event of 1st function is launched it gives focus to second one & when it jumps back to first one onblur of 2nd textfield is launched.
I know validation would be best when done at the form level, but this is the requirement I got.
Any help?
Javascript code
function x()
{
if( document.getElementById("1").value.length==0)
{
alert('1 is required');
document.getElementById("1").focus();
}
}
function y()
{
if(document.getElementById("2").value.length==0)
{
alert('2 is required');
document.getElementById("2").focus();
}
}
HTML code
<input type="text" name="City Name" id="1" onblur="javascript:x();">
<input type="text" name="Kitty Name" id="2" onblur="javascript:y();">
Upvotes: 7
Views: 25896
Reputation: 4989
With the use of timeouts you can disable the onBlur event on the "target" element and go back to the source element. This works in IE.
function focusWithoutEvents(object) {
// Small timeout so that the active element will be the "next" element
setTimeout(function() {
var activeElement = document.activeElement;
// Save the current onblur()
var activeOnblur = activeElement.onblur;
// Disable the onblur event
activeElement.onblur = null;
// Now we can focus without triggering onblur event
object.focus();
// With a small delay, put back the onblur code.
setTimeout(function() {
activeElement.onblur = activeOnblur
}, 100);
}, 100);
}
Upvotes: 0
Reputation: 595
Try Below Js Code. It will solve your problem.
function x()
{
if( document.getElementById("1").value.length==0)
{
if(alert('1 is required')){
document.getElementById("1").focus();
}
else
document.activeElement.blur();
}
}
function y()
{
if(document.getElementById("2").value.length==0)
{
if(alert('2 is required')){
document.getElementById("2").focus();
}
else
document.activeElement.blur();
}
}
Upvotes: 0
Reputation: 1
I have one JS and have one function which is called onblur
event of textbox and onblur
that event is in Infinite loop.
After that, I have declared one global variable (On the top of JS and outside the function Var Isvalid = true;
)
In function, Performing validation code.
if (IsValid == true)
{
if validation is false.
giving alert message.
and updating the IsValid = false;
}
If the validation is true then updating the global variable. Isvalid = true;
In second recursion it will not execute the loop. If in next phase if blur event occurred then variable automatically set to True
.
Upvotes: 0
Reputation: 30500
There is a fundamental problem when trying to refocus on a field on an onblur
when it is invalid. If the user decides to navigate away, the simply can't. When they click away from the field, they are forcibly taken back. I have seen instances where a user is forced to kill their browser session, just to escape an over-zealous onblur
validation.
I realise this might not be the exact solution you are after, but can I recommend another approach that still involves client-side validation.
I recommend you highlight the field as being invalid in some way on the onblur
. E.g. put a star next to it, highlight it red, etc. This way you can dispense with the alert
and user still has control.
When the user comes to submit the form, you perform your client-side checks and display alert to them then (see @Phill Sacre's answer)
Upvotes: 4
Reputation: 1
other code
common.js
if( window.COMMON_JS == undefined ){
window.COMMON_JS = "common.js ver:1.0.0.1";
window.AletMessage = "";
MessageAlert = function( msg ){
if( window.AletMessage == msg ){
return;
}
window.AletMessage = msg;
alert(msg);
setTimeout(function(){
window.AletMessage = "";
},1000);
};
}
test.html
<html>
<head>
<script type="text/javascript" src="common.js"></script>
<script>
var e = function( _id ){
return document.getElementById(_id);
};
window.onload = function(){
e("test").onblur = function(){
if( e("test").value != "11" ){
MessageAlert("Number[11] is only allow");
e("test").focus();
}
};
};
</script>
</head>
<body>
<p>Only 11 allowed.</p>
<input type="text" id="test"/>
</body>
</html>
Upvotes: 0
Reputation: 1
If you modify your code like this. It can be solved.
<html>
<head>
<title>break alert infinite loop </title>
<script>
var e = function( _id ){
return document.getElementById(_id);
};
window.onload = function(){
e("test").onblur = function(){
if( e("test").value != "11" ){
Msg("Number[11] is only allow");
e("test").focus();
}
};
};
/* fix start */
var beforeMsg = "";
/* fix end */
function Msg( msg ){
/* fix start */
if( msg == beforeMsg ){
return;
}
beforeMsg = msg;
/* fix end */
alert(msg);
/* fix start */
setTimeout(function(){
beforeMsg = "";
},1000);
/* fix end */
}
</script>
</head>
<body>
<p>only 11 is allow</p>
<input type="text" id="test"/>
</body>
</html>
Upvotes: 0
Reputation: 91
Instead of handling it in onblur()
event, you can handle it in onchange()
event.
If you still want to use onblur()
, then use the focus inside setTimeout
as shown below.
alert('2 is required');
setTimeout(function() { document.getElementById("2").focus(); }, 100);
Upvotes: 6
Reputation: 471
Here is my solution:
function x()
{
if( document.getElementById("1").value.length==0)
{
alert('1 is required');
document.getElementById("1").focus();
return false;
}
return true
}
function y()
{
if(x() && document.getElementById("2").value.length==0)
{
alert('2 is required');
document.getElementById("2").focus();
}
}
So, if 1 is required, the y
function won't be evaluated
Upvotes: 0
Reputation: 3816
Try this
<html>
<head>
<script>
function x() {
if (document.getElementById("input1").value.length == 0 ) {
alert('1 is required');
document.getElementById("input1").focus();
}
else if (document.getElementById("input2").value.length == 0 ) {
alert('2 is required');
document.getElementById("input2").focus();
}
}
</script>
</head>
<body >
cityname:
<input type="text" name="City Name" id="input1" onblur="javascript:x();">
<br/>
KittyName:
<input type="text" name="Kitty Name" id="input2" onblur="javascript:x();">
</body>
</html>
Upvotes: 0
Reputation: 6030
My be you have to change your way of comparison from
document.getElementById("1").value.length==0
to
document.getElementById("1").value != ''
it seems to me that length is always not equal zero
Upvotes: 0
Reputation: 385194
My recommendation is to temporarily disable the blur
handler during the execution of the other input's handler.
I've also replaced your HTML onblur
with a proper Javascript solution, removed the blank lines and added code indentation.
I've also changed the element IDs, which are not allowed to start with numbers; your script would not have worked at all on compliant browsers.
<html>
<body>
<script type="text/javascript">
window.onload = function() {
document.getElementById("input1").onblur = x;
document.getElementById("input2").onblur = y;
};
function x() {
if (document.getElementById("input1").value.length == 0) {
alert('1 is required');
// temporarily disable binding
document.getElementById("input2").onblur = function() {};
document.getElementById("input1").focus();
// re-bind
document.getElementById("input2").onblur = y;
}
}
function y() {
if (document.getElementById("input2").value.length == 0) {
alert('2 is required');
// temporarily disable binding
document.getElementById("input1").onblur = function() {};
document.getElementById("input2").focus();
// re-bind
document.getElementById("input1").onblur = x;
}
}
</script>
<input type="text" name="City Name" id="input1" onblur="javascript:x();">
<input type="text" name="Kitty Name" id="input2" onblur="javascript:y();">
</body>
</html>
Now, this script is rather verbose and carries a lot of code duplication. But in the interests of staying on-topic, I'll leave further improvements for another day.
I would also suggest not doing this at all; as James said, it's irritating.
Upvotes: 0
Reputation:
My suggestion: consolidate your validation into one method, and check each sequentially in it.
So (pseudo-code):
function validate() {
for (field in fieldlist) {
if (document.getElementById(field).value.length == 0) {
displayerror();
document.getElementById(field).focus();
}
}
}
This way you will only ever display one error at a time.
Upvotes: 1