I am using ngDialog in my application and I would like to create a generic confirm modal , which I can use whenever I need , the confirm message is going to be different .
My questions :
1- Is creating a directive with the ngDialog functionality a good idea and what is its design ?
2- what is the difference between confirm() and openConfirm() in ngDialog code .
Thanks in advance
Well, to answer your questions,
1 - You can create a directive for it, having a scope, say type to which you pass the confirmation type ( i.e. submit for submit confirmations, delete for delete confirmations) and the directive should render the message based on the type you specified.
2 - openConfirm() is a type of ngDialog, which can only be closed by confirming the action (unlike ngDialog.open()), so you don't have the ability here to close the dialog when clicking anywhere in theDOM. confirm() is just a method you use to close the dialog, you use this method to close the dialog and resolve the promise that was returned when opening the modal, so it can go on <button ng-click="confirm()">Confirm</button> inside your dialog.
Hope this helped you
Update
openConfirm()
Opens a dialog that by default does not close when hitting escape or clicking outside the dialog window. The function returns a promise that is either resolved or rejected depending on the way the dialog was closed.
To resolve the promise, your dialog should be like this:
With ngDialog controller
ngDialog.openConfirm({
template: '<div></div>',
controller: ['$scope', function($scope) {
// Controller logic here
}]
}).then(function (success) {
// Success logic here
}, function (error) {
// Error logic here
});
With directive controller
ngDialog.openConfirm({
template: '<div></div>',
scope: $scope, // <- ability to use the scopes from directive controller
}).then(function (success) {
// Success logic here
}, function (error) {
// Error logic here
});
You can use your directive controller as long as you pass scope: $scope inside the dialog
Here is a demo showing you how you can use type
Try switching the type in index.html from confirm to remove and see the updated content and button text in the dialog
Related
I am trying to undertsand angular dialogs. I have created a very simple code to display a custom alert dialog. I am trying to pass a string message to the dialog. Dialog has an OK button which shoudl close it.
The message data is being passed correctly. However for some reason, the OK button is not triggering the dialog controller's function.
Here is my code
Alert.html - Contains template for Alert dialog
<md-dialog>
<md-dialog-content>
{{message}}
</md-dialog-content>
<md-dialog-actions>
<md-button ng-click="alertFunc">
OK
</md-button>
</md-dialog-actions>
</md-dialog>
AlertCtrl.js - Contains Controller for Alert Dialog
app.controller('AlertCtrl', function ($scope, $mdDialog, message) {
$scope.message = message
$scope.alertFunc = function () {
console.log("Closing Alert Dialog")
$mdDialog.hide()
}
})
DialogService.js - Contains API to launch alert dialog
app.service('DialogService', function($mdDialog) {
// Launch Alert Dialog
this.alert = function (message) {
// Show Dialog
$mdDialog.show({ templateUrl: 'Alert.html',
controller: 'AlertCtrl',
clickOutsideToClose: true,
locals: { message: message }
})
}
})
The log inside alertFunc never shows up.
I also tried putting controllerAs : 'ctrl' inside the $mdDialog.show. Then I changed the alertFunc declaration to this.alertFunc = function... and changed ng-click='ctrl.alertFunc'. However this did not work as well.
Can someone help me figure out the problem.
Thank You
It should be ng-click="alertFunc()" instead of ng-click="alertFunc". 2 hours of effort and a stupid parenthesis.
Amazing how ignorant a programmer can get.
I open a dialog with mdDialog when checking a checkbox (in the example checkbox 1).
Within this dialog there are several input fields, which should be connected via ng-modell to a controller - but it seems, that is not the scope used by the main controller (in the example myCtrl).
How can I use the same scope in the dialog and myCtrl? I tried locals to access the parent scope, but this didn't work.
Here is the plunker:
[https://plnkr.co/edit/9biRK5oskpQRhRWyeHWd](https://plnkr.co/edit/9biRK5oskpQRhRWyeHWd)
just pass the $scope to $mdDialog.show
$mdDialog.show({
scope: $scope,
controller: function () {
// ...
}
});
Remove the loacals. It can use myCtrls scope.
<md-radio-group ng-model="dialog_radio1">
Then in the cancel function I was able to log the selected radio value from myCtrls' scope.
$scope.cancel = function () {
$mdDialog.cancel();
console.log($scope.dialog_radio1);
};
I have an application that uses angular-ui bootstrap modal (http://angular-ui.github.io/bootstrap/#/modal) for search from a list and select one of row.
In common using of angular-ui bootstrap modal, we must create two controller (for example ModalDemoCtrl for main modal and ModalInstanceCtrl for modal window).
In second controller, we have two method:
$scope.ok = function () {
$modalInstance.close($scope.selected.item);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
that repeat in several place (when I create several search modal).
How to I create a directive (or service), that contains these two controller and create these two methods inside it.
You are wrong - there is one controller for modal window. Second one is for main page and is not related to modals at all. So if u want to have 10 buttons on page to open 10 different modals, then u will have 11 controllers.
For modals that just displays message or ask to confirm actions it is good to have service, so u can write Myservice.showModal('Are you sure?', function callbackafterok() {...}).
If u just dont like repeating $modalInstance.close - make simple directive for buttons with ng-click binding, to write:
<button closeModalWithData="" >Ok</cancel>
or just
<modalOk/> with template <button ng-click="ok()">Ok</button>...
Petr Averyanov's answer was right. I created a directive and towards the end of the documentation for Angular UI modal directive, When we create a modal window, some property adds to $scope.
One of property is $close that we can use it to close modal.
Like this:
.directive('closeModal', function() {
return {
restrict: 'E',
template: '<button ng-click="$close()">Cancel</button>'
};
})
How can I achieve the following in AngularJS:
If I have my page that will show some widgets and each widget has a button called refresh. When the button is clicked then the content of that widget is reloaded from server. While the content is reloaded I want to show the user a message within that widget, please wait ... with a possible fading effect.
How can I achieve that in AngularJS?
I kind of taught about having a common service for that purpose and then somehow each widget controller will use that service or something like that, maybe also a directive that will show the actual loading/please wait message?
What is your advise?
P.S. There should be also a loading/please wait message with fading for the whole page, when the route is changing ... like switching between pages.
In my recent project I'm using https://github.com/cgross/angular-busy
Very nice thing, all you have to do is put your promise into $scope, and then add cg-busy attr to your element which should have spinner (beside registering module obviously):
Controller:
$scope.myPromise = restangular.get('something',12).then(function(response) { ... })
Html:
<div cg-busy="myPromise"></div>
You can also customize template that's gonna be displayed (which includes spinner and text message).
there are implementations of this available on github : angular-spinner or angular-sham-spinner. Read this BLOG which details how the spinner works with angularjs
if you want to implement it yourself to be reusable...
app.directive("spinner", function(){
return: {
restrict: 'E',
scope: { enable: "=" },
template: '<div class="spinner" ng-show="enable"><img src="content/spinner.gif"></div>'
}
});
i havent tested the code but directive wont be more complex than above...
As harish point out the right way would be a directive, but theres no need if you want of include another dependency, you could do something like this
You can create a nice CSS3 only loading (so not images required) animation with the help of CssLoad
Create a directive with a linking function so you can call and stop the animations within your controller the angular way:
.directive('appLoading', function(){
return {
restrict: 'E',
templateUrl: 'template-file.html', // or template: 'template html code inline' Display none to the code is important so is not visible if youre not caling the methods
replace: true,
link: function(scope, elem) {
scope.$on('app-start-loading', function(){
elem.fadeIn(); //asumming you have jquery otherwise play with toggleClass and visible and invisible classes
});
scope.$on('app-finish-loading', function(){
elem.fadeOut();
});
}
}
})
Include in your html code the directive: <app-loading></app-loading>
Now all you need to do is call the scope methods in your controller like this:
$scope.$broadcast('app-start-loading'); // to start the loading animation
$scope.$broadcast('app-finish-loading'); // to stop the animation
NOTE: if all your widgets share a scope, the loading may be triggered in all of them
I am using the Angular UI Bootstrap popover ( http://angular-ui.github.io/bootstrap/#/popover ) and would like to specify a callback function to execute when it is opened and another for when it is closed. My use case is that I am using the popover to contain filters for a grid of data. I would like to load some remote filtering options on open, apply the selected filters only when the popover is closed.
The documentation only appears to support a few basic options but no indication of callback support. I'm not seeing anything in the source code either. Is my only option to set an interval function to check periodically if the popover is visible in the DOM?
I'm also considering Angular Strap's popover to achieve the same result, but can't seem to find the option to set callbacks there either.
Seems that Koni's and user2453461's answers no longer work as popover.js utilizes tooltip.js that does the emit event. You should be able to do the following:
$scope.$on('tooltip.show.before', function() {
console.log("show before");
});
$scope.$on('tooltip.show', function() {
console.log("show");
});
$scope.$on('tooltip.hide.before', function() {
console.log("hide before");
});
$scope.$on('tooltip.hide', function() {
console.log("hide");
});
Not sure how good an idea this is, though, as the syntax seems to change over versions.
I found a solution for AngularStrap. It emits popover-* events that I can hook into here:
https://github.com/mgcrea/angular-strap/blob/3c8bd1d37ab3b023bd79f9b0c1a6931b18e2ac84/src/directives/popover.js#L110
So using this in my popover controller I can hook into hidden/shown. This is for modals but works the same for the popover with the popover- prefix
https://github.com/mgcrea/angular-strap/issues/107#issuecomment-16701662
For me worked as user2453461 said:
$scope.$on('popover-shown', function() {
console.log("SHOWN");
});
$scope.$on('popover-hidden', function() {
console.log("HIDDEN");
});
Popover "inherits from" $tooltip, which $emits a tooltip.hide.before and then a tooltip.hide event. However, since it is $emiting and not $broadcasting, only the popover's scope (and its children, but it is unlikely to have any) has access to the event.
In my code (coffeescript), this looks like:
.directive 'ngPopoverParent', ($popover) ->
link: (scope, element, attrs) ->
popover = $popover element,
'title': attrs.title
'content': attrs.content
'animation': attrs.animation
'trigger': 'click'
popover.$promise.then ->
popover.$scope.$on 'tooltip.hide', ->
console.log('tooltip hidden!')
Relevant source:
https://github.com/mgcrea/angular-strap/blob/08167f7d5f52424b0f6fe40f3a053e134f550472/src/tooltip/tooltip.js