Lars335
Lars335

Reputation: 1880

Simple modal dialog service using AngularJS & Kendo UI

I am quite new to Angular and need some help creating a resuable service or similar for displaying a very simple Yes/No dialog.

I am using Kendo UI's window component to display the modal dialog, but I find myself duplicating pretty much identical code / HTML everywhere I need a confirmation dialog:

<div kendo-window="myDialogWindow" k-modal="true" k-visible="false" k-width="250">
  <div style="text-align: center; width:100%">
      <div style="margin:10px 0 15px 0">{{ dialog.message }}</div>
      <button class="k-button k-primary" id="yesButton" ng-click="onYes()">Yes</button>
      <button class="k-button" id="noButton" ng-click="onNo()">No</button>
  </div>
</div>

Then from some click event or similar, I call a method to open and center the dialog:

$scope.showDialog = function(title, message) {
   $scope.dialog.message = message;
   $scope.myDialogWindow.title(title);
   $scope.myDialogWindow.center();
   $scope.myDialogWindow.open();
}

I would like to minimize code duplication and create something reusable for this.

First I was figuring a custom directive would work well, but then I would need to create a two-way bound variable in the isolate scope and put a watch on it to know when to open the dialog + create a couple of method-bindings for when the user clicks on a button. I would also need to put the directive in the HTML.

I have been searching for a solution, but the stuff I have found have been way overkill for my modest needs (and I also like to use Kendo UI, for a consistent theme).

From what I have found, it seems like an Angular service might be the best approach (inject the dialog into the DOM), with a promise to let me know what was clicked. The service should be very simple to use - something like this:

dialogService.display("Some title", "The message").then(
   function() {
       // Yes clicked...
   }, function() {
       // No clicked...
   });

Here is a simple plunker that just opens a kendo dialog when the button is clicked: http://plnkr.co/edit/ywCc3ZqFAXl3JEAu9XHW?p=preview

To recap: how can I create a service that will display the Yes/No dialog, with a promise to tell me what was clicked? If possible, please update the plunker to demonstrate solution.

Of course I am open to suggestions if there is a better approach.

Upvotes: 6

Views: 9070

Answers (1)

Lars335
Lars335

Reputation: 1880

I came up with the solution below, in case it helps somebody.

dialogService.js:

(function () {
    'use strict';

    var serviceId = 'dialogService';
    angular.module('app').factory(serviceId, ['$q', dialogService]);

    function dialogService($q) {
        var service = {
            showDialog: showDialog
        };

        return service;

        function showDialog(title, message) {
            var deferred = $q.defer();

            var html = 
              '<div id="myDialogWindow"> ' +
              ' <div style="text-align: center; width:100%"> ' +
              '   <div style="margin:10px 0 15px 0">' + message + '</div> ' +
              '   <button class="k-button k-primary" id="yesButton">Yes</button> ' +
              '   <button class="k-button" id="noButton"">No</button> ' +
              '   </div> ' +
              '</div> ';

            $('body').append(html);

            var windowDiv = $('#myDialogWindow');
            windowDiv.kendoWindow({
                width: "250px",
                title: title,
                modal: true,
                visible: false
              });

            var dialog = windowDiv.data("kendoWindow");

            $('#yesButton').click(function(e) {
              dialog.close();
              $('#myDialogWindow').remove();
              deferred.resolve();
            });

            $('#noButton').click(function(e) {
              dialog.close();
              $('#myDialogWindow').remove();
              deferred.reject();
            });

            dialog.center();
            dialog.open();

            return deferred.promise;
        }
    }
})();

HTML:

<div ng-controller="myController">
   <button ng-click="showDialog('Delete Confirmation', 'Delete line?')">Click me!</button>
</div>

showDialog method in controller:

$scope.showDialog = function(title, message) {
   dialogService.showDialog(title, message).then(
     function() {
       alert('Yes clicked');
     },
     function() {
       alert('No clicked');
     });
}

New plunker: http://plnkr.co/edit/WY0x1n6PwIKqxK0sKr3u?p=preview

Upvotes: 8

Related Questions