dwmkerr / angular-modal-service Goto Github PK
View Code? Open in Web Editor NEWModal service for AngularJS - supports creating popups and modals via a service.
License: MIT License
Modal service for AngularJS - supports creating popups and modals via a service.
License: MIT License
I followed the sample code and it is kind of working, except that the then() function doesn't get called when I dismiss the dialog. I'm not sure if this is related to the fact I'm also using AngularStrap in the project.
Hi!
I do not find any way to make use of ngAnimate on modal open. The close method allow to specify a time in millisecond for this
Thanks
Hi, I would like to create a modal view with an input suggesting places from google maps api.
Previously to do that I used the angular-google-places-autocomplete library (https://github.com/kuhnza/angular-google-places-autocomplete/), but now when I try to integrate it with the modal it does not work.
What I did is to modify the angularModularService in this way:
var module = angular.module('angularModalService', ['google.places']);
but it didn't worked.
There's a nice cleanup solution at #23:
please delete I was blind :P
Your article clearly show an execution order:
var modalController = $controller(controller, inputs);
var modalElementTemplate = angular.element(template);
var linkFn = $compile(modalElementTemplate);
var modalElement = linkFn(modalScope);
which is confirmed by other - articles.
So far, so good... The code of your service, up to version 0.2.0, was doing that.
Commit bca78f1 broke that, wanting to allow injecting $element into the controller, so calling the controller after the link of directives in the template have been called.
This is apparently a violation of a fundamental rule of AngularJS, for a minor, not so much used feature... ๐
This bites me because I have a directive (from angular-selectize) which takes configuration data at link time, and then creates an instance of Selectize with this configuration. So, it is not a real double-binding and it cannot catch-up the configuration created too late when the controller is ran.
I imagine we can have similar issues with one-time binding (the new 1.3's :: annotation).
Honestly, I have no idea if there is a way to maintain the injection of $element while restoring the proper init order... At worst, you can add an option to the showModal() parameter object, telling $element must be injected, and thus calling the controller later.
Note: I use AngularJS 1.3.15.
Hi,
thanks a lot for your this nice utitilty.
One question: What is the reason behind including a dependency to bootstrap in your bower.json? I actually don't see the need for this except the samples. I am using bootstrap-sass and as all bower dependencies get auto injected during the build of my project, I end up with 2 bootstrap versions.
Any suggestions? Much appreciated ;)
Cheers!
Some build methods preload templates into the template cache. Because of this, templates may never be available directly at their specified URL, so always using $http to get a template might fail.
Hi ,
I want to pass the message to display in the model window? Do you have any samples of that? please let me know.
I was using a template for my model that had the following root element:
<div class="modal fade">
nested content
</div>
If my template included ANYTHING after the closing </div>
, including comments, the modal spawned one additional <div class="modal-backdrop in"></div>
per element. In testing,
In testing, I tried adding <div></div>
after the closing div and TWO of the above extra backdrop classes were added.
The issue with the extra modal-backdrop classes is that they don't get removed from the DOM when the modal is closed, and so the user cannot interact with the UI any longer without refreshing, and of course, if there are any visual styles applied to the backdrop, such as the popular opacity effect, those too remain after closing the modal.
This may not be a problem with the angular-modal-service code, perhaps it is, or perhaps the jQuery selector is overly ambitious? I will look into it further, but post this here in case anyone else runs into this sneaky problem since comments following div tags are commonplace.
Currently the bower.json limits this module to the 1.2.x line. I have been testing it on 1.3.0-rc.4 for a while this morning and have not found any compatibility issues.
More of an informational than an issue, but hopefully useful information as this moves forward.
A really useful sample would be how to create a wizard with the angular modal service.
http://www.panopta.com/static/bootstrap-wizard-plugin/demo/demo.html
I am getting this message "Scripts may close only the windows that were opened by it.", and I can only use the "Cancel" button to close a window. As far as I can tell I am set up exactly as it is in the sample. Even when I use the cancel button, I get the same message but the window does close. Strange...
Hi,
I am using a $timeout to automatically close a modal after 1000 milliseconds. But the scroll bar does not come back into action after this. If I close by clicking on the close button (or anywhere other than the modal) then the scroll bar comes back fine. I have tested this on safari and firefox (on OS X).
I am using the following controller:
app.controller('YesNoController', ['$scope', 'title', 'close', '$timeout', function($scope, title, close, $timeout) {
$scope.title = title;
$timeout( function(){
close('yes', 500); // close, but give 500ms for bootstrap to animate
}, 1000);
$scope.close = function(result) {
close(result, 500); // close, but give 500ms for bootstrap to animate
};
}]);
In the current system, and if i understand it, to use a custom modal, you have to pass a controller already created :
app.controler("SomeController", function($scope, close) {
$scope.dismissModal = function(result) {
close(result, 200);
};
});
ModalService.showModal({
templateUrl: "some/template.html",
controller: "SomeController"
});
I can't find a way to do this without changing the code :
ModalService.showModal({
templateUrl: "some/template.html",
controller: function($scope, close) {
$scope.dismissModal = function(result) {
close(result, 200);
};
}
});
Do you plan to add this feature ?
See comment at:
http://www.dwmkerr.com/the-only-angularjs-modal-service-youll-ever-need/#comment-1810738299
It would be useful to have an API such as:
modalService.closeModals();
which simply closes any open modals. A potential use case is in the application router, where changing a URL should not leave the modal open. Even better would be:
modalService.closeModals(someValue);
Which would close all the modals and resolve their close promises with the value someValue
. This would allow application developers to decide whether they want to allow consumers of modals to be able to handle the cases where they are closed externally explicitly.
It seems the inputs.close
is leaked. Use a memory leak tag on the created scope to see the issue.
I'm using angular 1.3.0 with Ruby on Rails.
Error: [jqLite:nosel] Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element
http://errors.angularjs.org/1.3.0/jqLite/nosel
at REGEX_STRING_REGEXP (http://localhost:3000/assets/angular/lib/angular.js?body=1:81:12)
at Object.JQLite as element
at http://localhost:3000/assets/angular/lib/angular-modal-service.js?body=1:99:48
at processQueue (http://localhost:3000/assets/angular/lib/angular.js?body=1:12915:27)
at http://localhost:3000/assets/angular/lib/angular.js?body=1:12931:27
at Scope.$get.Scope.$eval (http://localhost:3000/assets/angular/lib/angular.js?body=1:14124:28)
at Scope.$get.Scope.$digest (http://localhost:3000/assets/angular/lib/angular.js?body=1:13940:31)
at Scope.$get.Scope.$apply (http://localhost:3000/assets/angular/lib/angular.js?body=1:14228:24)
at HTMLInputElement. (http://localhost:3000/assets/angular/lib/angular.js?body=1:22524:23)
at HTMLInputElement.eventHandler (http://localhost:3000/assets/angular/lib/angular.js?body=1:3014:21)
hi, I want to decide when I close the modal, and that it is only the close button to close the modal, you can .
thank you
Massimo
I am calling ModalService from a directive, which works well when on a particular route view. However, when I change the route to other view where the same directive exists, the ModelService fails to open.
Another issue I observed, when using ModalService in another service and called from any controller, again fails to open.
Everytime I open a modal, .modal-open is still attached to the body of my page.
The overflow: hiddden
property prevent me to slide my page after a modal is opened.
View:
<div class="modal fade">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" ng-click="close(false)" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">{{params.title || 'Are you sure ?'}}</h4>
</div>
<div class="modal-body">
<p>
{{params.text || 'Really ?'}}
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-white" ng-click="close(false)" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" ng-click="close(true)" data-dismiss="modal">Save changes</button>
</div>
</div>
</div>
</div>
Controller:
angular.module('app')
.controller('ConfirmModalCtrl', function ($scope, close, params) {
$scope.params = params;
$scope.close = function(res) {
close(res, 200);
};
});
Call:
ModalService.showModal({
templateUrl: 'views/modals/confirm.modal.view.html',
controller: 'ConfirmModalCtrl',
inputs: {
params: {
title: 'Are you sure ?',
text: '... bla bla bla'
}
}
}).then(function(modal) {
modal.element.modal();
modal.close.then(function(res) {
console.log(res);
});
});
I have seriously no idea where it could come from.
I've already checked all dependencies and they are fine (bootstrap, angular, ModalService)
Hi,
I'd like to see an example for using the appendElement in the call to showModal(). Could you add it to the examples? :-)
Cheers,
Allister
Take your example:
ModalService.showModal({
templateUrl: "some/template.html",
controller: "SomeController"
}).then(function(modal) {
// only called on success...
}).catch(function(error) {
// error contains a detailed error message.
console.log(error);
});
I would be nice to keep the modal open and update it. So, in the error handler, do something like this:
ModalService.showModal({
templateUrl: "some/template.html",
controller: "SomeController"
}).then(function(modal) {
// only called on success...
}).catch(function(error) {
ModalService.updateModal({
templateUrl: "error/template.html",
controller: "errorController"
}).then(function(modal) {
modal.element.modal()
})
});
I'm running into an issue with a modal's $scope. It looks like the modal's $scope is set to rootscope. I'm trying to use $emit to send an event from within the modal and the listener in my AppController never receives it. AppController is attached to the body.
What is the best way to handle this?
I have the following form. i want to preceed with Ok action when enter key is pressed, but cannot get it to work. I have tried various option including jquery but non of it works.
How can i associate Enter Key to certain button like OK.
<div id="modalDialog" class="modal-dialog">
<div class="modal-header">
<h2 style="text-align: center">{{modalOptions.headerText}}</h2>
</div>
<div class="modal-body">
<p>{{modalOptions.bodyText}}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn" data-ng-click="modalOptions.close()"> {{modalOptions.closeButtonText}}</button>
<button type="button" id="OK" class="btn btn-danger" ng-enter="modalOptions.ok();" autofocus data-ng-click="modalOptions.ok();" data-ng-keyup="$event.keycode == 13 && modaloptions.ok()">{{modalOptions.actionButtonText}}</button>
</div>
$("#modalDialog").keydown(function (event) {
console.log("Event mapped")
if (event.keyCode == 13) {
$(this).parent()
.find("button:eq(0)").trigger("click");
return false;
}
});
}); //document
</script>`
I looked through the examples to see if there was already a documented way of properly cleaning up a modal that is dismissed when clicking outside the modal area. I didn't see anything and noticed there were many ng-click directives used to catch the modal closing.
Instead of attaching ng-click directives to all the elements and faking the animation time for the modal to disappear I used the events generated by bootstrap. I inserted this at the top of my controller to make sure the modal is properly cleaned up regardless of how it is closed and waits for the animation to finish. This handles clicking outside the modal to close, data-dismiss="modal", and $element.modal('hide').
$element.on('hidden.bs.modal', close)
I thought this might be useful documentation in the FAQ.
https://rails-assets.org/components -- this is an awesome resource, but seems to be dependent on having release tags in the repo. Possible to add one to this release?
I cannot get this to work with the latest bootstrap CSS (v.3.3.4): The modal appears but remains somewhat faded and there is not control over it. It disappears with any click.
On the other hand when using the bootstrap CSS provided in the example code, everything is fine!
Any insight on this behavior?
Why controller
option is required for showModal
? Maybe make it optional for modals without controllers.
Just started happening today! Did something change? Any clues on why this would happen?
In FAQ "I'm using a Bootstrap Modal and the backdrop doesn't fade away", it mentions: "It will try and make both elements into a modal. This means both elements will get a backdrop. In this case, either remove the extra elements, or find the specific element you need from the provided modal.element property."
I have a scenario where I want to force the user to take an action via a modal dialog. If the user does not take the action and reloads the page, it will open the dialog again with the result that the dialog cannot be closed properly.
How do I find the existing dialog element and remove it?
@dwmkerr, it'd be really great if you can publish this to npm. Since you already have package.json, it is really easy. Here are the simple steps:
cd
to your local reponpm adduser
(and enter your info/creds (don't worry if you don't have an account)... these are the same info/creds that will log you in to npmjs.com)npm publish
That's it! ๐
Demo video: https://docs.npmjs.com/getting-started/publishing-npm-packages
Seem not to be compatible:
Console error: modal is not a function
When a modal is open, and the page behind it is obscured
While you cannot click on anything on that page
You can still tab to move the tab-focus around on the page -- and hit spacebar/enter to trigger the highlighted item
Anyone else have the problem of calling showModal from inside the then function of the close promise? I get a darkened background that gets darker with the nested dialog and then never goes away.
Hello,
I am testing the modals and I don't know how to set backdrop to static like the boostrap modal.
Ej: ModalService.showModal({
templateUrl: "complex/complex.html",
controller: "ComplexController",
backdrop: 'static', <===================== here
inputs: {
title: "A More Complex Example"
}
}).then(function(modal) {
modal.element.modal();
modal.close.then(function(result) {
$scope.complexResult = "Name: " + result.name + ", age: " + result.age;
});
});
Thanks in advance.
Oddly enough, I've used angular-modal-service successfully in other projects, but haven't been able to pinpoint why this project is special. I'm not using bootstrap in any of the projects.
I'm getting this error using 0.3-0.5
Controller:
.controller('SettingsCtrl', ['$scope', 'close', function ($scope, close) {
$scope.close = function(result) {
close(true);
};
$scope.cancel = function() {
close();
};
}])
Launch point:
angular.module('settings',
[
'angularModalService'
])
.controller('CoreCtrl', ['$scope', '$window', 'ModalService', function($scope, $window, ModalService){
$scope.openSettingsDialog = function() {
ModalService.showModal({
templateUrl: 'markup/settings.html',
controller: 'SettingsCtrl'
}).then(function(modal){
modal.close.then(function(result) {
});
});
};
}])
If a scope is provided externally, it is still destroyed by the service. This is unintuitive and leads to problems with lifecycle management.
Thank you for this great addition to angular, I love the flexibility and ease of use.
I am trying to write unit tests for a controller I'm using in a modal and cannot figure out how to inject the close provider into my tests since it looks like there's some angular magic going on. Any tips to help?
it('should implement close()', function () {
inject(function ($controller, $rootScope) {
var scope;
scope = $rootScope.$new();
$controller('TemplateController', { $scope: scope } );
expect(angular.isFunction(scope.close)).toBeTruthy();
});
}); // should implement close()
The controller is as simple as:
TimelineControllers.controller('TemplateController', ['$scope', 'close', function($scope, close) {
$scope.close = function () {
close('i was closed');
};
}]);
I have modals that I want to force users to interact with (ie. disclosures). Is there a feature to enforce this?
It would be extremely useful to document how unit testing works with Angular Modal Service.
Hi Dave,
Excellent tutorial on reusable modal windows.
However I've found some issues in your project.
We need to publish to npm on release as well as bumping version numbers
Code is entered exactly as the example and when the showAModal()
function fires the modal template html is appended to the body while the console outputs this:
TypeError: undefined is not a function
which points to this line modal.element.modal();
Using Angular 1.3.0
Any insight is appreciated.
Code in the controller
$scope.showAModal = function () {
ModalService.showModal({
templateUrl: 'partials/cancel-membership.modal.html',
controller: 'ModalCtrl'
}).then(function (modal) {
//it's a bootstrap element, use 'modal' to show it
modal.element.modal();
modal.close.then(function (result) {
console.log(result);
});
});
};
Hi, is it possible to attach a sample with a 'save' button and showing where is the best place to call the save(record) methode and how to react on a cancel to restore the old values?
many thanks
Useful addition
The latest tag (0.6.6) isn't on NPM which includes the IE8 fix. Could someone publish it there?
Hi can you help me writing unit test for modal controllers ?
I tried but I'm not able to solve these errors:
PLease, can you add a controller test to your complexcontroller example ?
My interesting part of the test code is:
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
PartsEditmenudialogctrlCtrl = $controller('PartsEditmenudialogctrlCtrl', {
$scope: scope
});
and for the controller
.controller('PartsEditmenudialogctrlCtrl', [ '$route', '$scope' , '$log', 'growl', 'MainMenuService', '$element', 'close', 'currMainMenuEditData',
function ($route, $scope, $log, growl, MainMenuService, $element, close, currMainMenuEditData) {
Thanks in advance
Stefano
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.