Products

Solutions

Resources

Partners

Community

About

New Community Website

Ordinarily, you'd be at the right spot, but we've recently launched a brand new community website... For the community, by the community.

Yay... Take Me to the Community!

The Community Blog is a personal opinion of community members and by no means the official standpoint of DNN Corp or DNN Platform. This is a place to express personal thoughts about DNNPlatform, the community and its ecosystem. Do you have useful information that you would like to share with the DNN Community in a featured article or blog? If so, please contact .

The use of the Community Blog is covered by our Community Blog Guidelines - please read before commenting or posting.


Non-Blocking "Are-You-Sure" Dialog Pattern with AngularJS (300)

In modern web UX we sometimes need to ask the user something - but it's also ok if the user ignores the question. An example of this is when the user accidentally clicks the background of a modal-dialog. Here's how to implement an elegant solution using AngularJS and Angular-Toastr.

    Why we need this pattern

    This is just an example, I'm sure you'll have your own situations. When using bootstrap-style dialogs and modal-dialogs, we often want to offer a "hit-escape" or "click on the background" to get away. Of course we must first check if the model is dirty(nothing changed) - to not loose data. 

    Now in our experience, people would often click on the background by accident. For example, they would be marking text with a mouse and releasing the button on the background. Or they would open a drop-down and not-select something by clicking beside the drop-down. In these cases a JavaScript dialog blocking the UI is very annoying, because it interrupts the use-flow. 

    The image to the side shows the alert as it used to be in the 2sxc-edit dialog before we refactored it. 

      The new solution

      The better solution which we just created for 2sxc 8.4.2 simply shows a toaster using Angular-Toastr by Foxandxss. This is a modern toaster implementation which doesn't need jQuery - something that's always an important issue to us. This has the benefit that

      1. clicking outside the dialog can still be used to quit
      2. pressing escape can still be used
      3. the user is warned about leaving and can choose what she wants
      4. ...but the user can also ignore the question, and it will go away within 3 seconds

      AngularJS Code to Provide this Functionality

        // 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);

          The general Code Explained

          In general the code works as follows

          1. Watch for messages related to closing the modal dialog
          2. If closing is attempted, show the toaster which will go away within 3 seconds
          3. Since creating a toastr is a delayed operation, we add an onShown event which will handle all clicks on the toastr
          4. Once the click happens, check if it was from one of our buttons...
          5. ...and then get out 

            tl;dr

            We believe this pattern will be very important from now on. The toastr still has some optimization potential, as the on-click-handling feels a bit hacky. But except for that I'm convinced it will become used very often - we actually added another such toaster for handling delete-requests, and asking the user if he wants to force-delete if the normal delete didn't work. 

            Hope you love it,
            Daniel 


            Daniel Mettler grew up in the jungles of Indonesia and is founder and CEO of 2sic internet solutions in Switzerland and Liechtenstein, an 20-head web specialist with over 800 DNN projects since 1999. He is also chief architect of 2sxc (see forge), an open source module for creating attractive content and DNN Apps.



            Read more posts by Daniel Mettler

            Comments

            There are currently no comments, be the first to post one.

            Comment Form

            Only registered users may post comments.

            NewsArchives


            Aderson Oliveira (22)
            Alec Whittington (11)
            Alessandra Daniels (3)
            Alex Shirley (10)
            Andrew Hoefling (3)
            Andrew Nurse (30)
            Andy Tryba (1)
            Anthony Glenwright (5)
            Antonio Chagoury (28)
            Ash Prasad (37)
            Ben Schmidt (1)
            Benjamin Hermann (25)
            Benoit Sarton (9)
            Beth Firebaugh (12)
            Bill Walker (36)
            Bob Kruger (5)
            Bogdan Litescu (1)
            Brian Dukes (2)
            Brice Snow (1)
            Bruce Chapman (20)
            Bryan Andrews (1)
            cathal connolly (55)
            Charles Nurse (163)
            Chris Hammond (213)
            Chris Paterra (55)
            Clint Patterson (108)
            Cuong Dang (21)
            Daniel Bartholomew (2)
            Daniel Mettler (181)
            Daniel Valadas (48)
            Dave Buckner (2)
            David Poindexter (12)
            David Rodriguez (3)
            Dennis Shiao (1)
            Doug Howell (11)
            Erik van Ballegoij (30)
            Ernst Peter Tamminga (80)
            Francisco Perez Andres (17)
            Geoff Barlow (12)
            George Alatrash (12)
            Gifford Watkins (3)
            Gilles Le Pigocher (3)
            Ian Robinson (7)
            Israel Martinez (17)
            Jan Blomquist (2)
            Jan Jonas (3)
            Jaspreet Bhatia (1)
            Jenni Merrifield (6)
            Joe Brinkman (274)
            John Mitchell (1)
            Jon Henning (14)
            Jonathan Sheely (4)
            Jordan Coopersmith (1)
            Joseph Craig (2)
            Kan Ma (1)
            Keivan Beigi (3)
            Kelly Ford (4)
            Ken Grierson (10)
            Kevin Schreiner (6)
            Leigh Pointer (31)
            Lorraine Young (60)
            Malik Khan (1)
            Matt Rutledge (2)
            Matthias Schlomann (16)
            Mauricio Márquez (5)
            Michael Doxsey (7)
            Michael Tobisch (3)
            Michael Washington (202)
            Miguel Gatmaytan (3)
            Mike Horton (19)
            Mitchel Sellers (40)
            Nathan Rover (3)
            Navin V Nagiah (14)
            Néstor Sánchez (31)
            Nik Kalyani (14)
            Oliver Hine (1)
            Patricio F. Salinas (1)
            Patrick Ryan (1)
            Peter Donker (54)
            Philip Beadle (135)
            Philipp Becker (4)
            Richard Dumas (22)
            Robert J Collins (5)
            Roger Selwyn (8)
            Ruben Lopez (1)
            Ryan Martinez (1)
            Sacha Trauwaen (1)
            Salar Golestanian (4)
            Sanjay Mehrotra (9)
            Scott McCulloch (1)
            Scott Schlesier (11)
            Scott Wilkinson (3)
            Scott Willhite (97)
            Sebastian Leupold (80)
            Shaun Walker (237)
            Shawn Mehaffie (17)
            Stefan Cullmann (12)
            Stefan Kamphuis (12)
            Steve Fabian (31)
            Steven Fisher (1)
            Tony Henrich (3)
            Torsten Weggen (3)
            Tycho de Waard (4)
            Vicenç Masanas (27)
            Vincent Nguyen (3)
            Vitaly Kozadayev (6)
            Will Morgenweck (40)
            Will Strohl (180)
            William Severance (5)
            What is Liquid Content?
            Find Out
            What is Liquid Content?
            Find Out
            What is Liquid Content?
            Find Out