angular-toastr icon indicating copy to clipboard operation
angular-toastr copied to clipboard

Handle click-events in a toast - by passing event-object to onHidden

Open iJungleboy opened this issue 9 years ago • 6 comments

I have a use case where a toastr has various buttons (save / cancel) and when clicking them, my vm.something() must be called. I need it because the edit-dialog in a CMS called 2sxc (github.com/2sic/2sxc/) has a backdrop that can be clicked to close the dialog, but I wanted an unblocking "are-you-sure" kind of dialog.

This is very hard to do, because I cannot really pass any JS object into the clicker. My working solution currently is this:

(updated)

        // handle maybe-leave
        vm.maybeLeave = {
            save: function() { vm.save(true); },
            quit: $scope.close,
            handleClick: function(event) {
                var target = event.target || event.srcElement;
                if (target.id === "save" || target.id === "quit") {
                    vm.allowCloseWithoutAsking = true;
                    vm.maybeLeave[target.id]();
                }
            },
            ask: function(e) {
                if (vm.allowCloseWithoutAsking)
                    return;
                var template = "<div>"  // note: this variable must be inside this method, to ensure that translate is pre-loaded before we call it
                    + $translate.instant("Errors.UnsavedChanges") + "<br>"
                    + "<button type='button' id='save' class='btn btn-primary' ><i class='icon-ok'></i>" +  $translate.instant("General.Buttons.Save") + "</button> &nbsp;"
                    + "<button type='button' id='quit' class='btn btn-default' ><i class= 'icon-cancel'></i>" + $translate.instant("General.Buttons.NotSave") + "</button>"
                    + "</div>";
                if (vm.dialog && vm.dialog.isOpened)
                    toastr.clear(vm.dialog);
                vm.dialog = toastr.warning(template, {
                    allowHtml: true,
                    timeOut: 3000,
                    onShown: function (toast) {
                        toast.el[0].onclick = vm.maybeLeave.handleClick;
                    }
                });
                e.preventDefault();
            }
        };

        $scope.$on("modal.closing", vm.maybeLeave.ask);

In my opinion most of this is ok, except what I really don't like is the DOM-manipulation style of click-binding I had to use, namely the part...

                    onShown: function (toast) {
                        toast.el[0].onclick = vm.maybeLeave.handleClick;
                    }

...as it doesn't feel angular-style. So it works, but it's not quite what I believe is sound architecture. I see a few ways to do this, but probably the simplest would be to also give the event-object to the onHidden event, because from there the programmer could check what button was pressed. Currently I only get the toast-object which isn't very useful in figuring out what was clicked.

iJungleboy avatar Apr 22 '16 06:04 iJungleboy

I will open the toasts to use angular code in them so your problem should be easily resolved then. Like the multiple containers thing, when I find a bit of time.

Foxandxss avatar Apr 22 '16 08:04 Foxandxss

no problem, and thanks. BTW: I think my current workaround should actually work for many scenarios, handling clicks and then figuring out what to do. So if you want to publish that as a valid workaround that's fine too - would give you more time to actually implement the angular-view-version

iJungleboy avatar Apr 22 '16 08:04 iJungleboy

+1

baktun14 avatar May 31 '16 22:05 baktun14

Has this change been implemented yet? I'm also looking for ways to embed ng-click handlers in the HTML sent to the toastr. Thanks.

dgodwin1175 avatar Jan 20 '17 06:01 dgodwin1175

Hi @Foxandxss @dgodwin1175 , Any updates on weather this thing is achieved and available??

ng-parth avatar Jul 06 '17 06:07 ng-parth

Apparently yes, there is a second parameter with the toast.

Foxandxss avatar Jul 06 '17 09:07 Foxandxss