Welcome to Community Week 2025! Join us to learn, connect, and be recognized as we celebrate the spirit of Community and the power of AI. Get the details  

How to Run a Function after Modal is Closed in Widget

Mark Endsley
Tera Guru

I'm trying to run code after a Modal is closed on a widget. I am opening the modal in my widget and using .then. What I have noticed though is that the .then never runs if the user closes the Modal instead of pushing 'Ok'.

 

		spModal.open({
			widget:'widget-form',
			widgetInput:{table:parms.table, sys_id:parms.sys_id},
			size:'lg'
		}).then(function(name){
			myEl.removeClass('disabledbutton');
		});
		

 

In my example the class is never removed in the case that the user pushes the X in the top right corner of the modal.

in a uib modal there is a .closed.then apparently, but this doesn't work with spModal

If this is not possible it would be good if I could just find a way to run this code once the Modal has loaded up, that is fine too.

1 ACCEPTED SOLUTION

Ok, so my solution to this ended up being to go to 

/scripts/app.$sp/service.spModal.js
 
I then copied the code into my widget and made some modifications. The end result looking like this:
 
		var myEl = angular.element( document.querySelector( '#mainFrame' ) );
		
		myEl.addClass('disabledbutton');
		
		var options = {
			widget:'widget-form',
			widgetInput:{table:parms.table, sys_id:parms.sys_id},
			size:'lg'
		};
		
		options = initOptions(options);
        var defer = $q.defer();
        if (options.widget) {
            var widgetURL = spUtil.getWidgetURL(options.widget);
            $http.post(widgetURL, options.widgetInput).success(function(response) {
                options.widget = response.result;
                options.widget.options.shared = options.shared;
                openModal(options, defer);
            });
        } else
            openModal(options, defer);
       // return defer.promise;
		
		
		
		
var openModal = function (options, defer) {
        var pageRoot = angular.element('.sp-page-root');
        var modal = $uibModal.open({
            templateUrl: 'sp-modal.html',
            controller: spModalCtrl,
            size: options.size,
            backdrop: options.backdrop != undefined ? options.backdrop : true,
            keyboard: options.keyboard != undefined ? options.keyboard : true,
            resolve: {
                options: function() {
                    return options;
                }
            }
        });
        modal.result.then(function(result) {
            if (options.input) {
                defer.resolve(result.input, result.button);
            } else {
                defer.resolve(result.button);
            }
        }, function() {
            defer.reject();
        });
        modal.rendered.then(function() {
            var h1 = angular.element('#modal-title');
            var modal = h1.closest('div.modal');
            modal.attr('aria-labelledby', 'modal-title');
            pageRoot.attr('aria-hidden', 'true');
					
        });
        modal.closed.then(function() {
            pageRoot.attr('aria-hidden', 'false');
						myEl.removeClass('disabledbutton');
        });
    }
		
		
		function initOptions(options) {
        var defaults = {
            title: '',
            message: '',
            messageOnly: false,
            errorMessage: '',
            input: false,
            label: '',
            size: '',
            value: '',
            required: false,
            values: false,
            onSubmit: null,
            widget: null,
            widgetInput: null,
            noDismiss: false,
            buttons: [{
                    label: i18n.getMessage('Cancel'),
                    cancel: true
                },
                {
                    label: i18n.getMessage('OK'),
                    primary: true
                }
            ]
        };
        options = options || {};
        for (var key in defaults) {
            if (options[key] === undefined) {
                options[key] = defaults[key];
            }
        }
        if (options.messageOnly) {
            options.headerStyle = {
                border: 'none'
            }
            options.footerStyle = {
                border: 'none',
                'padding-top': 0
            }
        }
        if (options.noDismiss)
            options.headerStyle = {
                display: 'none'
            };
        return options;
    }
		
		
		
		    function spModalCtrl($scope, options) {
        $scope.input = {
            value: options.value
        };
        $scope.options = options;
        $scope.form = {};
        if (!options.input) {
            options.buttons.forEach(function(b) {
                if (b.primary)
                    b.focus = true;
            })
        }
        $scope.buttonClicked = function(button) {
            if (button.cancel) {
                $scope.$dismiss();
                return;
            }
            if (options.input && $scope.form.xpForm.$invalid) {
                $scope.changed = true;
                return;
            }
            if (options.onSubmit) {
                var promise = options.onSubmit();
                promise.then(function(res) {
                    if (!res.status) {
                        $scope.options.errorMessage = res.errorMessage;
                        return;
                    } else {
                        $scope.$close({
                            button: button,
                            input: $scope.input.value
                        });
                    }
                });
            } else {
                $scope.$close({
                    button: button,
                    input: $scope.input.value
                });
            }
        }
        $scope.submit = function() {
            var ok;
            angular.forEach($scope.options.buttons, function(button) {
                if (button.primary)
                    ok = button;
            })
            if (ok) $scope.buttonClicked(ok);
        }
        $scope.keyPress = function(keyCode) {
            if (keyCode === 13) {
                $scope.submit();
            }
        }
    }

View solution in original post

3 REPLIES 3

Community Alums
Not applicable

I do not believe there is a .closed event for spModal.

If you wanted something to trigger inside the modal, you can embed it within <script>  tags inside the modal template if you are using one.

In this case you are using a widget, so you may have to clone the widget and make modifications to it to run certain scripts on load.

 

The other option is to remove the class when the Modal is opened instead of waiting till after, if they have a popup on their screen they may not be able to see the element in question.

 

Another option again is to modify the modal open options and remove specific buttons so they can only close it the way you want to, you may also need to modify the modal behaviour so they can't just click away and close the window.

Hi Aidan,

The issue I've run into with removing the class when the modal loads is that the class is removed far before the modal loads up. I can use setTimeout but then I'm just guessing on the modal load time.

The modal is running the form widget so sometimes it takes a bit of time to appear and load.

I am working on modifying the modal, what I think I'm going to try next is skipping the spModal entirely and just making my own UIB Modal.

Ok, so my solution to this ended up being to go to 

/scripts/app.$sp/service.spModal.js
 
I then copied the code into my widget and made some modifications. The end result looking like this:
 
		var myEl = angular.element( document.querySelector( '#mainFrame' ) );
		
		myEl.addClass('disabledbutton');
		
		var options = {
			widget:'widget-form',
			widgetInput:{table:parms.table, sys_id:parms.sys_id},
			size:'lg'
		};
		
		options = initOptions(options);
        var defer = $q.defer();
        if (options.widget) {
            var widgetURL = spUtil.getWidgetURL(options.widget);
            $http.post(widgetURL, options.widgetInput).success(function(response) {
                options.widget = response.result;
                options.widget.options.shared = options.shared;
                openModal(options, defer);
            });
        } else
            openModal(options, defer);
       // return defer.promise;
		
		
		
		
var openModal = function (options, defer) {
        var pageRoot = angular.element('.sp-page-root');
        var modal = $uibModal.open({
            templateUrl: 'sp-modal.html',
            controller: spModalCtrl,
            size: options.size,
            backdrop: options.backdrop != undefined ? options.backdrop : true,
            keyboard: options.keyboard != undefined ? options.keyboard : true,
            resolve: {
                options: function() {
                    return options;
                }
            }
        });
        modal.result.then(function(result) {
            if (options.input) {
                defer.resolve(result.input, result.button);
            } else {
                defer.resolve(result.button);
            }
        }, function() {
            defer.reject();
        });
        modal.rendered.then(function() {
            var h1 = angular.element('#modal-title');
            var modal = h1.closest('div.modal');
            modal.attr('aria-labelledby', 'modal-title');
            pageRoot.attr('aria-hidden', 'true');
					
        });
        modal.closed.then(function() {
            pageRoot.attr('aria-hidden', 'false');
						myEl.removeClass('disabledbutton');
        });
    }
		
		
		function initOptions(options) {
        var defaults = {
            title: '',
            message: '',
            messageOnly: false,
            errorMessage: '',
            input: false,
            label: '',
            size: '',
            value: '',
            required: false,
            values: false,
            onSubmit: null,
            widget: null,
            widgetInput: null,
            noDismiss: false,
            buttons: [{
                    label: i18n.getMessage('Cancel'),
                    cancel: true
                },
                {
                    label: i18n.getMessage('OK'),
                    primary: true
                }
            ]
        };
        options = options || {};
        for (var key in defaults) {
            if (options[key] === undefined) {
                options[key] = defaults[key];
            }
        }
        if (options.messageOnly) {
            options.headerStyle = {
                border: 'none'
            }
            options.footerStyle = {
                border: 'none',
                'padding-top': 0
            }
        }
        if (options.noDismiss)
            options.headerStyle = {
                display: 'none'
            };
        return options;
    }
		
		
		
		    function spModalCtrl($scope, options) {
        $scope.input = {
            value: options.value
        };
        $scope.options = options;
        $scope.form = {};
        if (!options.input) {
            options.buttons.forEach(function(b) {
                if (b.primary)
                    b.focus = true;
            })
        }
        $scope.buttonClicked = function(button) {
            if (button.cancel) {
                $scope.$dismiss();
                return;
            }
            if (options.input && $scope.form.xpForm.$invalid) {
                $scope.changed = true;
                return;
            }
            if (options.onSubmit) {
                var promise = options.onSubmit();
                promise.then(function(res) {
                    if (!res.status) {
                        $scope.options.errorMessage = res.errorMessage;
                        return;
                    } else {
                        $scope.$close({
                            button: button,
                            input: $scope.input.value
                        });
                    }
                });
            } else {
                $scope.$close({
                    button: button,
                    input: $scope.input.value
                });
            }
        }
        $scope.submit = function() {
            var ok;
            angular.forEach($scope.options.buttons, function(button) {
                if (button.primary)
                    ok = button;
            })
            if (ok) $scope.buttonClicked(ok);
        }
        $scope.keyPress = function(keyCode) {
            if (keyCode === 13) {
                $scope.submit();
            }
        }
    }