From 27896534f0aeb79d3948475757ae7781ba100c1d Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 11 Dec 2014 12:05:59 +1100 Subject: [PATCH 1/4] Navigation Callbacks (confirmation to leave) refs A navigation callback could give only a fixed value at load time. Now it can act depending on the site's state just before the page is unloaded. --- .../admin/utils/directives/navigation_check.js.coffee | 5 +++-- app/views/admin/enterprises/_ng_form.html.haml | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/admin/utils/directives/navigation_check.js.coffee b/app/assets/javascripts/admin/utils/directives/navigation_check.js.coffee index 95f52505eb..da25286505 100644 --- a/app/assets/javascripts/admin/utils/directives/navigation_check.js.coffee +++ b/app/assets/javascripts/admin/utils/directives/navigation_check.js.coffee @@ -4,6 +4,7 @@ angular.module("admin.utils").directive "navCheck", (NavigationCheck)-> navCallback: '&' link: (scope,element,attributes) -> # Define navigationCallback on a controller in scope, otherwise this default will be used: - scope.navCallback ||= -> + callback = scope.navCallback() + callback ||= -> "You will lose any unsaved work!" - NavigationCheck.register(scope.navCallback) + NavigationCheck.register(callback) diff --git a/app/views/admin/enterprises/_ng_form.html.haml b/app/views/admin/enterprises/_ng_form.html.haml index 86be5bb0be..d3ea41d88f 100644 --- a/app/views/admin/enterprises/_ng_form.html.haml +++ b/app/views/admin/enterprises/_ng_form.html.haml @@ -1,4 +1,4 @@ -= form_for [main_app, :admin, @enterprise], html: { name: "enterprise", "ng-app" => 'admin.enterprises', "ng-submit" => "navClear()", "ng-controller" => 'enterpriseCtrl' , "nav-check" => '', "nav-callback" => 'enterpriseNavCallback()' } do |f| += form_for [main_app, :admin, @enterprise], html: { name: "enterprise", "ng-app" => 'admin.enterprises', "ng-submit" => "navClear()", "ng-controller" => 'enterpriseCtrl' , "nav-check" => '', "nav-callback" => 'enterpriseNavCallback' } do |f| .row .sixteen.columns.alpha .eleven.columns.alpha.fullwidth_inputs From 11f1261dd3feddb98569660a196fd77298bc6bf2 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 11 Dec 2014 12:07:48 +1100 Subject: [PATCH 2/4] Navigation Callbacks for WebKit --- .../admin/utils/services/navigation_check.js.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/admin/utils/services/navigation_check.js.coffee b/app/assets/javascripts/admin/utils/services/navigation_check.js.coffee index ff1041474c..8bdab1bc9c 100644 --- a/app/assets/javascripts/admin/utils/services/navigation_check.js.coffee +++ b/app/assets/javascripts/admin/utils/services/navigation_check.js.coffee @@ -15,7 +15,8 @@ angular.module("admin.utils") onBeforeUnloadHandler: ($event) => message = @getMessage() if message - ($event or $window.event).preventDefault() + # following: https://developer.mozilla.org/en-US/docs/Web/Events/beforeunload + ($event or $window.event).returnValue = message message # Action for angular navigation. From 76739a47460c22cd203ecbce17b27561402a9c36 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 11 Dec 2014 12:14:51 +1100 Subject: [PATCH 3/4] Unify nav-check and nav-callback attributes in nav-check-callback The value of nav-check was not used and nav-callback was only important if nav-check was given. So we need only one attribute, now named nav-check-callback. --- .../admin/utils/directives/navigation_check.js.coffee | 8 ++++---- app/views/admin/enterprises/_ng_form.html.haml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/admin/utils/directives/navigation_check.js.coffee b/app/assets/javascripts/admin/utils/directives/navigation_check.js.coffee index da25286505..fee80e9acf 100644 --- a/app/assets/javascripts/admin/utils/directives/navigation_check.js.coffee +++ b/app/assets/javascripts/admin/utils/directives/navigation_check.js.coffee @@ -1,10 +1,10 @@ -angular.module("admin.utils").directive "navCheck", (NavigationCheck)-> +angular.module("admin.utils").directive "navCheckCallback", (NavigationCheck)-> restrict: 'A' scope: - navCallback: '&' + navCheckCallback: '&' link: (scope,element,attributes) -> - # Define navigationCallback on a controller in scope, otherwise this default will be used: - callback = scope.navCallback() + # Provide a callback, otherwise this default will be used: + callback = scope.navCheckCallback() callback ||= -> "You will lose any unsaved work!" NavigationCheck.register(callback) diff --git a/app/views/admin/enterprises/_ng_form.html.haml b/app/views/admin/enterprises/_ng_form.html.haml index d3ea41d88f..feb46b840f 100644 --- a/app/views/admin/enterprises/_ng_form.html.haml +++ b/app/views/admin/enterprises/_ng_form.html.haml @@ -1,4 +1,4 @@ -= form_for [main_app, :admin, @enterprise], html: { name: "enterprise", "ng-app" => 'admin.enterprises', "ng-submit" => "navClear()", "ng-controller" => 'enterpriseCtrl' , "nav-check" => '', "nav-callback" => 'enterpriseNavCallback' } do |f| += form_for [main_app, :admin, @enterprise], html: { name: "enterprise", "ng-app" => 'admin.enterprises', "ng-submit" => "navClear()", "ng-controller" => 'enterpriseCtrl', "nav-check-callback" => 'enterpriseNavCallback' } do |f| .row .sixteen.columns.alpha .eleven.columns.alpha.fullwidth_inputs From 440044372b48259b4c584759888c5e022642e531 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 11 Dec 2014 14:27:08 +1100 Subject: [PATCH 4/4] Leave-page-warning only after changing inputs The enterprise form is now set 'dirty' whenever an input changes. The navigation callback confirms to leave the page only if the form is dirty. --- .../controllers/enterprise_controller.js.coffee | 3 ++- app/views/admin/enterprises/_ng_form.html.haml | 12 +++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/admin/enterprises/controllers/enterprise_controller.js.coffee b/app/assets/javascripts/admin/enterprises/controllers/enterprise_controller.js.coffee index e9a1bc077f..4c14a3b096 100644 --- a/app/assets/javascripts/admin/enterprises/controllers/enterprise_controller.js.coffee +++ b/app/assets/javascripts/admin/enterprises/controllers/enterprise_controller.js.coffee @@ -12,7 +12,8 @@ angular.module("admin.enterprises") # from a directive "nav-check" in the page - if we pass it here it will be called in the test suite, # and on all new uses of this contoller, and we might not want that . $scope.enterpriseNavCallback = -> - "You are editing an enterprise!" + if $scope.enterprise.$dirty + "Your changes to the enterprise are not saved yet." for payment_method in $scope.PaymentMethods payment_method.selected = payment_method.id in $scope.Enterprise.payment_method_ids diff --git a/app/views/admin/enterprises/_ng_form.html.haml b/app/views/admin/enterprises/_ng_form.html.haml index feb46b840f..e0a9bef86e 100644 --- a/app/views/admin/enterprises/_ng_form.html.haml +++ b/app/views/admin/enterprises/_ng_form.html.haml @@ -1,4 +1,14 @@ -= form_for [main_app, :admin, @enterprise], html: { name: "enterprise", "ng-app" => 'admin.enterprises', "ng-submit" => "navClear()", "ng-controller" => 'enterpriseCtrl', "nav-check-callback" => 'enterpriseNavCallback' } do |f| +-# Not all inputs are ng inputs, they don't make the form dirty on change. +-# ng-change is only valid for inputs, not for a form. +-# So we use onchange and have to get the scope to access the ng controller +-# The nav-check-callback is warning on leave if the form is dirty. += form_for [main_app, :admin, @enterprise], html: { name: "enterprise", + "ng-app" => 'admin.enterprises', + "ng-submit" => "navClear()", + "ng-controller" => 'enterpriseCtrl', + "nav-check-callback" => 'enterpriseNavCallback', + 'onchange' => 'angular.element(enterprise).scope().enterprise.$setDirty()', + } do |f| .row .sixteen.columns.alpha .eleven.columns.alpha.fullwidth_inputs