Search code examples
javascripthtmlangularjsangularjs-directiveangularjs-scope

Parameter elem of the linking function


I've got the following directive:

.directive('confirmOnExit', function () {
    return {link: function ($scope, elem, attrs) {
            window.onbeforeunload = function () {
                if ($scope.contextForm.$dirty) {
                    return "Unsaved data detected.";
                }
            }
        }
    };
})

As you can see, the directive is not really well written as it directly references the form contextForm.

What I wanted to do is something a bit more generic (so I could also use it on other forms):

.directive('confirmOnExit', function ($window) {
    return {link: function ($scope, elem, attrs) {
            // Make sure code is only executed if directive is place on a form
            // Should I even do this here??
            if (elem[0].tagName == "FORM") {
                var form = elem[0];
                $window.onbeforeunload = function () {
                if (form.className.indexOf("ng-dirty") > -1) {
                    return "Unsaved data detected.";
                }
            }
        }
    };
})

You'll notice that the code is still pretty ugly since form.hasClass("ng-dirty") or form.$dirty() didn't work... I also think that accessing elem[0] is not correct...

I'd really appreciate some help!

Thanks!!


Solution

  • From the AngularJS form doc:

    If name attribute is specified, the form controller is published onto the current scope under this name.

    So you can access that controller by using $eval on the name attribute:

    .directive('confirmOnExit', function () {
        return {
            link: function ($scope, elem, attrs) {
                var formCtrl = $scope.$eval(attrs.name);
                window.onbeforeunload = function () {
                    if (formCtrl.$dirty) {
                        return "Unsaved data detected.";
                    }
                }
            }
        };
    });