Michael Hunziker
Michael Hunziker

Reputation: 2679

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!!

Upvotes: 1

Views: 729

Answers (2)

Dan
Dan

Reputation: 63099

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.";
                }
            }
        }
    };
});

Upvotes: 2

Valentyn Shybanov
Valentyn Shybanov

Reputation: 19391

You should rely on FormController ( http://docs.angularjs.org/api/ng.directive:form.FormController )

So what you can do:

  1. Add "require: '^ngForm'" to request form controller as parameter to you linking function
  2. Add another parameter to your linking function (kind of formCtrl)
  3. use formCtrl.$dirty

If it is not clear for you, create plunker example with directive and I'll try to make these changes on it.

Upvotes: 2

Related Questions