Multiple forms on one page using the same directive AND one form inside the element directive

BACKGROUND: I am trying to create a "Stop navigation if the form is dirty" directive. I looked at a few questions / examples about SO, and I put together something that is somewhat functional, but not entirely correct. I am trying to use this directive as an attribute in several forms in our web application.

PROBLEM: I have a page containing two elements <form>("form1" and "form2") that are nested in the elements <tab>. Form2 is further nested in the custom element directive.

When any form is dirty and I try to go to another page (changing the user interface router), I get the expected custom invitation from our online service. However, if I try to reload the page, I get a prompt generated by the browser when form2 is dirty. When form1 is not dirty, a request is not requested.

Can someone help me find out how to generate a browser prompt when form1 is dirty, and is there a window event such as a reboot?


RELATED HTML

<!-- "main" view -->
<tabset>
    <tab heading="Heading1">
        <form name="FORM1" class="form-horizontal" form-dirty>
            <!-- FORM STUFF -->
        </form>
    </tab>  
    <tab heading="Heading2">
        <this-contains-form2 data="objOnScope"></this-contains-form2>
    </tab>
</tabset>

<!-- "thisContainsForm2" template -->
<form name="FORM2" class="form-horizontal" form-dirty>
    <!-- FORM STUFF -->
</form>

RELEVANT JAVASCRIPT

// "form-dirty" directive
angular.module('webapp.shared').directive('formDirty', ['$state', 'DlgPromptService', function($state, DlgPromptService) {      
    return {
        scope: {theForm: '=name'},
        restrict: 'A',
        link: function (scope, element, attrs) {

            scope.$watch('theForm', function () {

                // if there a UI router change    
                scope.$on('$stateChangeStart', function (event, toState, toParams){

                    // WHEN FORM1 DIRTY:  PROMPT AND CONSOLE-LOG BOTH FORMS
                    // WHEN FORM2 DIRTY:  PROMPT AND CONSOLE-LOG BOTH FORMS

                    console.log(scope.theForm);

                    // if form was not modified
                    if ( !scope.theForm.$dirty ) {
                        return;
                    }
                    else {
                        // if form was modified then intervene

                        // halt the route change
                        event.preventDefault();

                        // prompt user
                        DlgPromptService.confirm('Unsaved Changes',
                            'This form has unsaved changes.<br/>'
                            +'Are you sure you want to leave?')
                        .then(function () {
                            // we will proceed with the route change
                            scope.theForm.$setPristine();
                            $state.go(toState.name, toParams);
                        })
                    }
                })

                // if there a window change (reload, etc)
                window.onbeforeunload = function (event) {

                    // WHEN FORM1 DIRTY:  NO PROMPT, NO CONSOLE LOG
                    // WHEN FORM2 DIRTY:  PROMPT AND CONSOLE-LOG FORM2

                    console.log(scope.theForm);

                    // if form was not modified             
                    if ( !scope.theForm.$dirty ) {
                        return;
                    }
                    else {
                        // prompt
                        return "prompt";
                    }
                }

                scope.$on('$destroy', function() {
                    window.onbeforeunload = undefined;
                })  
            })
        }
    }
}])

// "thisContainsForm2" directive
angular.module('webapp.shared').directive('thisContainsForm2', function() {

    var controller = function($scope, $http, $state, DlgPromptService) {
        // CONTROLLER STUFF
    }

    return {
        scope : {data: '='},
        templateUrl : 'shared/thisContainsForm2.html',
        controller : controller
    }
})
+4
source share
1 answer

ui bootstraps, , , "display: none"

form-dirty, , . overloadload

jQuerys, .

, , , →

0

All Articles