Manpreet Singh Dhillon
Manpreet Singh Dhillon

Reputation: 903

Firefox fires focusout / blur event automatically when input type is number

I have a JavaScript code running perfectly in all browsers except Firefox. I am running it in Firefox Quantum Version 66.0.2 (64-bit). I have three HTML input controls, all have their display style set to none. Clicking on a link shows first input. On focusout event of first input, first input hides and second input becomes visible. Similarly on focusout of second input, second input hides and third becomes visible.

function showFirst() {
    //Show first input
    $('#first').css('display', 'inline');
    $('#first').focus();
}

$(document).ready(function () {
    $('#first').focusout(function (event) {
        //Write log
        $('body').append('first focusout <br/>');

        //hide itself
        event.currentTarget.style.display = 'none';
        //show next input i.e. second
        $('#second').css('display', 'inline');
        $('#second').focus();
    });
    $('#second').focusout(function (event) {
        //Write log
        $('body').append('second focusout <br/>');

        //hide itself
        event.currentTarget.style.display = 'none';

         //show next input i.e. third
        $('#third').css('display', 'inline');
        $('#third').focus();
    });
    $('#third').focusout(function (event) {
        //Write log
        $('body').append('third focusout <br/>');

        //hide itself
        event.currentTarget.style.display = 'none';

         //show next input i.e. first
        $('#first').css('display', 'inline');
        $('#first').focus();
    });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<!--It will show first input-->
<a href="#" onclick="showFirst();">Click to show first</a>

<!--Its focusout event will hide it and will show second input-->
<input type="text" id="first" value="" style="display:none;background-color:yellow; color:black;" placeholder="First" />

<!--Its focusout event will hide it and will show third input-->
<input type="number" id="second" value="" style="display:none;background-color:red; color:white;" placeholder="Second" />

<!--Its focusout event will hide it and will show first input-->
<input type="number" id="third" value="" style="display:none;background-color:green; color:white;" placeholder="Third" />
<br />
<br />
<a href="#">&nbsp;</a> <!--Just to receive focus-->

The Problem:

When 'Click to show first' is clicked, it shows 'first' input. When tab is pressed then focusout events of 'second' and 'third' are fired by itself and 'second' and 'third' inputs are never shown. Interestingly if input type of all is changed from number to text then same code works fine.

Open this JSFiddle in Firefox to see it in action.

Upvotes: 1

Views: 1012

Answers (2)

Manpreet Singh Dhillon
Manpreet Singh Dhillon

Reputation: 903

Finally, I am able to solve it. It is a bug in Firefox version 60, 66, 67 and 68. See bug reports in bugzilla here and here. "Alice0775 White" suggested here to add timeout to focus. I just added timeout and it started working. Following is the working code:

    $(document).ready(function () {
        $('#first').focusout(function (event) {
            $('body').append('first focusout <br/>');
            event.currentTarget.style.display = 'none';
            $('#second').css('display', 'inline');

            //add timeout to focus
            setTimeout(function () {
                $('#second').focus();
            }, 0)
        });
        $('#second').focusout(function (event) {
            $('body').append('second focusout <br/>');
            event.currentTarget.style.display = 'none';
            $('#third').css('display', 'inline');

            //add timeout to focus
            setTimeout(function () {
                $('#third').focus();
            }, 0)
        });
        $('#third').focusout(function (event) {
            $('body').append('third focusout <br/>');
            event.currentTarget.style.display = 'none';
            $('#first').css('display', 'inline');

            //add timeout to focus
            setTimeout(function () {
                $('#first').focus();
            }, 0)
        });
    });

Upvotes: 0

Pablo Darde
Pablo Darde

Reputation: 6432

You need to set the listener for the next input after trigger the previous input focusout event.

Try the below code.

function showFirst() {
        //Show first input
        $('#first').css('display', 'inline');
        $('#first').focus();
    }
    $(document).ready(function () {
        $('#first').focusout(function (event) {
            //Write log
            $('body').append('first focusout <br/>');

            //hide itself
            event.currentTarget.style.display = 'none';
            //show next input i.e. second
            $('#second').css('display', 'inline');
            $('#second').focus();
            
            $('#second').focusout(function (event) {
                //Write log
                $('body').append('second focusout <br/>');

                //hide itself
                event.currentTarget.style.display = 'none';

                 //show next input i.e. third
                $('#third').css('display', 'inline');
                $('#third').focus();
                
                $('#third').focusout(function (event) {
           	 		
                //Write log
            		$('body').append('third focusout <br/>');

                  //hide itself
                  event.currentTarget.style.display = 'none';

                   //show next input i.e. first
                  $('#first').css('display', 'inline');
                  $('#first').focus();
              });
            });
        });
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<!--It will show first input-->
<a href="#" onclick="showFirst();">Click to show first</a>

<!--Its focusout event will hide it and will show second input-->
<input type="text" id="first" value="" style="display:none;background-color:yellow; color:black;" placeholder="First" />

<!--Its focusout event will hide it and will show third input-->
<input type="number" id="second" value="" style="display:none;background-color:red; color:white;" placeholder="Second" />

<!--Its focusout event will hide it and will show first input-->
<input type="number" id="third" value="" style="display:none;background-color:green; color:white;" placeholder="Third" />
<br />
<br />
<a href="#">&nbsp;</a> <!--Just to receive focus-->

Upvotes: 1

Related Questions