4

I am trying to focus first empty input inside a html form using angularjs directive. Here is the directive code which I have written so far (and applied on form element):

.directive('focusFirstEmptyInput', ['$timeout', function ($timeout) {
        return {
            restrict: "A",
            link: function (scope, element, attrs) {

                var focustElement = function () {
                    var keepGoing = true;
                    angular.forEach(element[0], function (field) {
                        if (!keepGoing) {
                            return;
                        }

                        if (field.tagName.toLowerCase() !== 'input')
                            return;

                        debugger;
                        var fieldValue = field.value;
                        if (!fieldValue) {
                            field.focus();
                            keepGoing = false;
                        }
                    });
                };

                $timeout(focustElement, 0);
            }
        };
    }]);

I am iterating over all form elements and trying to focus first empty field. However, when I am calling focus(), element doesn't get focused. What can be the reason?

UPDATE:

Weird, but if I remove the debugger statement (or don't open inspector mode at all) and don't pause the javascript code, it will focus first empty element.... (I am using Google Chrome)

Plunker: http://plnkr.co/edit/YT0DoTjUVrrnVwmyrX0v?p=preview

2
  • I added plunker as well. But, I figured out the problem. Check update section. Commented Nov 28, 2013 at 12:49
  • The break point impacting it makes me think it's a race condition... which means its not guaranteed to always work. Commented Nov 28, 2017 at 18:47

2 Answers 2

2

You have the timeout in the wrong place. You could use jquery to do some of the lifting. I'm not sure how to filter on empty inputs, so used a for loop (someone please improve this).

Add this directive to your module, then add the attribute "focus-first" on the parent element you want it to set focus for.

.directive('focusFirst', ['$timeout', function ($timeout) {            
        return {                
            restrict: "A",
            link: function (scope, element, attrs) {                    
                $timeout(function() {
                    var inputs = element.find('input'),
                        count = inputs.length;

                    for (var i = 0; i < count; i++) {
                        if (inputs[i].value) {
                            continue;
                        }
                        inputs[i].focus();
                        break;
                    }
                }, 0);
            }
        };
    }]);
Sign up to request clarification or add additional context in comments.

Comments

0

I did a test and seems to be the 0 value in the $timeout. Change it to 300 or something similar. With 300 work either you have developer tools open or not.

Works for me.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.