Reputation: 1880
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
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