AngularJS JavaScript

“Confirm By Typing” Angular UI Bootstrap model

Github has a pretty nice UX for deleting repositories. When you click “Delete”, you aren’t presented with a typical “Are you sure? Yes/No” alert. Instead, you are shown a modal with an in-your-face warning telling you the reprocussions of completing the modal, followed by a text input requiring you to enter a specific value before continuing.\\

githubconfirm

I think this is pretty great for this case. Not all Delete actions warrant this, but some do. So, I created an AngularJS directive to provide this. Feel free to use it, but keep in mind it does require AngularUI Bootstrap (note the $modal dependency).

The directive:

app.directive("confirmByTyping", ["$modal", function ($modal) {
    var getConfirmTypingModalTemplate = function (title, message) {
        var modalTemplate = "<div class=\"modal-header\"> " +
                                "<h3 class=\"modal-title\">" + title + "</h3> " +
                            "</div>  " +
                            "<div class=\"modal-body\"> " + message +
                                "<div class=\"form-group\" ng-class=\"{ 'has-success': confirmInput === expectedInput, 'has-error': confirmInput !== expectedInput }\">" +
                                    "<input class=\"form-control\" auto-focus ng-model=\"confirmInput\" ng-keydown=\"$event.which === 13 && closeConfirmTypingModal(true)\">" +
                                "</div>" +
                            "</div> " +
                            "<div class=\"modal-footer modal-footer-buttons\"> " +
                                "<button class=\"btn btn-primary\" type=\"button\" ng-click=\"closeConfirmTypingModal(true)\" ng-disabled=\"confirmInput !== expectedInput\">OK</button> " +
                                "<button class=\"btn btn-danger\" type=\"button\" ng-click=\"closeConfirmTypingModal()\">Cancel</button> " +
                            "</div>";

        return modalTemplate;
    }

    var getConfirmAlertModalTemplate = function (message) {
        var modalTemplate = "<div class=\"modal-body\"> " + message + "</div> " +
                            "<div class=\"modal-footer modal-footer-buttons\"> " +
                                "<button class=\"btn btn-primary\" type=\"button\" ng-click=\"closeConfirmAlertModal(true)\">Yes</button> " +
                                "<button class=\"btn btn-danger\" type=\"button\" ng-click=\"closeConfirmAlertModal()\">No</button> " +
                            "</div>";

        return modalTemplate;
    }

    return {
        restrict: "A",
        scope: {
            confirmAction: "&"
        },
        link: function (scope, element, attrs) {
            element.bind("click", function ($event) {
                $event.target.blur();

                var message = attrs.modalMessage,
                    title = attrs.modalTitle,
                    value = attrs.confirmValue;

                var confirmTypingModal = function() {
                    $modal.open({
                        backdrop: "static",
                        template: getConfirmTypingModalTemplate(title, message),
                        controller: ["$scope", "$modalInstance", function($scope, $modalInstance) {
                                $scope.expectedInput = value;
                                $scope.confirmInput = "";

                                $scope.closeConfirmTypingModal = function (confirmed) {
                                    if (confirmed) {
                                        if ($scope.expectedInput !== $scope.confirmInput) {
                                            return;
                                        }

                                        scope.confirmAction();
                                    }
                                    $modalInstance.close();
                                };
                            }
                        ]
                    });
                };

                $modal.open({
                    backdrop: "static",
                    template: getConfirmAlertModalTemplate(title, message),
                    controller: ["$scope", "$modalInstance", function ($scope, $modalInstance) {
                        $scope.closeConfirmAlertModal = function (confirmed) {
                            $modalInstance.close();

                            if (confirmed) {
                                confirmTypingModal();
                            }
                        };
                    }]
                });
            });
        }
    }
}]);

Example use:

<button confirm-by-typing confirm-action="deleteSite(site)" confirm-value="{{site.Path}}" alert-message="Are you sure you want to delete '{{site.Name}}'?" modal-title="Are you sure you want to delete '{{site.Name}}'?" modal-message="Enter the site path <strong>'{{site.Path}}'</strong> below to confirm.">
    Delete
</button>

Leave a Reply

Your email address will not be published. Required fields are marked *