{"id":13452221,"url":"https://github.com/dwmkerr/angular-modal-service","last_synced_at":"2025-05-15T13:09:01.859Z","repository":{"id":17606429,"uuid":"20410279","full_name":"dwmkerr/angular-modal-service","owner":"dwmkerr","description":"Modal service for AngularJS - supports creating popups and modals via a service.","archived":false,"fork":false,"pushed_at":"2020-11-10T21:39:56.000Z","size":4776,"stargazers_count":623,"open_issues_count":53,"forks_count":319,"subscribers_count":30,"default_branch":"master","last_synced_at":"2025-04-15T03:49:59.792Z","etag":null,"topics":["angular","javascript"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dwmkerr.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":"dwmkerr"}},"created_at":"2014-06-02T16:07:09.000Z","updated_at":"2025-03-24T11:39:43.000Z","dependencies_parsed_at":"2022-09-09T06:00:29.965Z","dependency_job_id":null,"html_url":"https://github.com/dwmkerr/angular-modal-service","commit_stats":null,"previous_names":[],"tags_count":33,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dwmkerr%2Fangular-modal-service","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dwmkerr%2Fangular-modal-service/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dwmkerr%2Fangular-modal-service/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dwmkerr%2Fangular-modal-service/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dwmkerr","download_url":"https://codeload.github.com/dwmkerr/angular-modal-service/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254270641,"owners_count":22042858,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular","javascript"],"created_at":"2024-07-31T07:01:17.293Z","updated_at":"2025-05-15T13:08:56.940Z","avatar_url":"https://github.com/dwmkerr.png","language":"JavaScript","funding_links":["https://github.com/sponsors/dwmkerr"],"categories":["Uncategorized","JavaScript"],"sub_categories":["Uncategorized"],"readme":"# angular-modal-service\n\n[![CircleCI](https://circleci.com/gh/dwmkerr/angular-modal-service.svg?style=shield)](https://circleci.com/gh/dwmkerr/angular-modal-service)\n[![codecov](https://codecov.io/gh/dwmkerr/angular-modal-service/branch/master/graph/badge.svg)](https://codecov.io/gh/dwmkerr/angular-modal-service)\n[![Dependencies](https://david-dm.org/dwmkerr/angular-modal-service.svg?theme=shields.io)](https://david-dm.org/dwmkerr/angular-modal-service)\n[![Dev Dependencies](https://david-dm.org/dwmkerr/angular-modal-service/dev-status.svg?theme=shields.io)](https://david-dm.org/dwmkerr/angular-modal-service#info=devDependencies)\n[![Greenkeeper badge](https://badges.greenkeeper.io/dwmkerr/angular-modal-service.svg)](https://greenkeeper.io/) [![GuardRails badge](https://badges.production.guardrails.io/dwmkerr/angular-modal-service.svg)](https://www.guardrails.io)\n\nModal service for AngularJS - supports creating popups and modals via a service. Full support for Angular 1.5+ components. See [a quick fiddle](http://jsfiddle.net/dwmkerr/8MVLJ/) or a full set of samples at [dwmkerr.github.io/angular-modal-service](http://dwmkerr.github.io/angular-modal-service).\n\n\u003c!-- vim-markdown-toc GFM --\u003e\n\n* [Usage](#usage)\n* [Support for AngularJS 1.5.x Components](#support-for-angularjs-15x-components)\n    * [ShowModal Options](#showmodal-options)\n    * [The Modal Object](#the-modal-object)\n    * [The Modal Controller](#the-modal-controller)\n    * [Closing All Modals](#closing-all-modals)\n    * [Animation](#animation)\n    * [Error Handing](#error-handing)\n    * [Global Options Configuration](#global-options-configuration)\n* [Developing](#developing)\n* [Tests](#tests)\n* [Releasing](#releasing)\n* [FAQ](#faq)\n* [Thanks](#thanks)\n\n\u003c!-- vim-markdown-toc --\u003e\n\n## Usage\n\nInstall with Bower (or NPM):\n\n```bash\nbower install angular-modal-service\n# or...\nnpm install angular-modal-service\n```\n\nThen reference the minified script:\n\n```html\n\u003cscript src=\"bower_components/angular-modal-service/dst/angular-modal-service.min.js\"\u003e\u003c/script\u003e\n```\n\nSpecify the modal service as a dependency of your application:\n\n```js\nvar app = angular.module('sampleapp', ['angularModalService']);\n```\n\nNow just inject the modal service into any controller, service or directive where you need it.\n\n```js\napp.controller('SampleController', [\"$scope\", \"ModalService\", function($scope, ModalService) {\n\n  $scope.showAModal = function() {\n\n  \t// Just provide a template url, a controller and call 'showModal'.\n    ModalService.showModal({\n      templateUrl: \"yesno/yesno.html\",\n      controller: \"YesNoController\"\n    }).then(function(modal) {\n      // The modal object has the element built, if this is a bootstrap modal\n      // you can call 'modal' to show it, if it's a custom modal just show or hide\n      // it as you need to.\n      modal.element.modal();\n      modal.close.then(function(result) {\n        $scope.message = result ? \"You said Yes\" : \"You said No\";\n      });\n    });\n\n  };\n\n}]);\n```\n\nCalling `showModal` returns a promise which is resolved when the modal DOM element is created\nand the controller for it is created. The promise returns a `modal` object which contains the\nelement created, the controller, the scope and two promises: `close` and `closed`. Both are\nresolved to the result of the modal close function, but `close` is resolved as soon as the\nmodal close function is called, while `closed` is only resolved once the modal has finished\nanimating and has been completely removed from the DOM.\n\nThe modal controller can be any controller that you like, just remember that it is always\nprovided with one extra parameter - the `close` function. Here's an example controller\nfor a bootstrap modal:\n\n```js\napp.controller('SampleModalController', function($scope, close) {\n\n $scope.dismissModal = function(result) {\n \tclose(result, 200); // close, but give 200ms for bootstrap to animate\n };\n\n});\n```\n\nThe `close` function is automatically injected to the modal controller and takes the result\nobject (which is passed to the `close` and `closed` promises used by the caller). It can\ntake an optional second parameter, the number of milliseconds to wait before destroying the\nDOM element. This is so that you can have a delay before destroying the DOM element if you\nare animating the closure. See [Global Config](#global-options-configuration) for setting a default delay.\n\nNow just make sure the `close` function is called by your modal controller when the modal\nshould be closed and that's it. Quick hint - if you are using Bootstrap for your modals,\nthen make sure the modal template only contains one root level element, see the [FAQ](#faq)\nfor the gritty details of why.\n\nTo pass data into the modal controller, use the `inputs` field of the modal options. For example:\n\n```js\nModalService.showModal({\n  templateUrl: \"exampletemplate.html\",\n  controller: \"ExampleController\",\n  inputs: {\n    name: \"Fry\",\n    year: 3001\n  }\n})\n```\n\ninjects the `name` and `year` values into the controller:\n\n```js\napp.controller('ExampleController', function($scope, name, year, close) {\n});\n```\n\nYou can also provide a controller function directly to the modal, with or without the `controllerAs` attribute.\nBut if you provide `controller` attribute with `as` syntax and `controllerAs` attribute together, `controllerAs`\nwill have high priority.\n\n```js\nModalService.showModal({\n  template: \"\u003cdiv\u003eFry lives in {{futurama.city}}\u003c/div\u003e\",\n  controller: function() {\n    this.city = \"New New York\";\n  },\n  controllerAs : \"futurama\"\n})\n\n```\n\n\n## Support for AngularJS 1.5.x Components\n\nIt's also possible to specify a component, rather than a template and controller. This can be done by providing a `component` and an optional `bindings` value to the `showModal` function.\n\n```js\nModalService.showModal({\n  component: 'myComponent',\n  bindings: {\n    name: 'Foo',\n    myRecord: { id: '123' }\n  }\n})\n```\n\n\n### ShowModal Options\n\nThe `showModal` function takes an object with these fields:\n\n* `controller`: The name of the controller to create. It could be a function.\n* `controllerAs` : The name of the variable on the scope instance of the controller is assigned to - (optional).\n* `templateUrl`: The URL of the HTML template to use for the modal.\n* `template`: If `templateUrl` is not specified, you can specify `template` as raw\n  HTML for the modal.\n* `inputs`: A set of values to pass as inputs to the controller. Each value provided\n  is injected into the controller constructor.\n* `component`: Renders a modal with the provided component as its template\n* `bindings`: Optional. If `component` is provided, all properties in `bindings` will be bound to the rendered `component`.\n* `appendElement`: The custom angular element or selector (such as `#element-id`) to append the modal to instead of default `body` element.\n* `scope`: Optional. If provided, the modal controller will use a new scope as a child of `scope` (created by calling `scope.$new()`) rather than a new scope created as a child of `$rootScope`.\n* `bodyClass`: Optional. The custom css class to append to the body while the modal is open (optional, useful when not using Bootstrap).\n* `preClose`: Optional. A function which will be called before the process of closing a modal starts. The signature is `function preClose(modal, result, delay)`. It is provided the `modal` object, the `result` which was passed to `close` and the `delay` which was passed to close.\n* `locationChangeSuccess`: Optional. Allows the closing of the modal when the location changes to be configured. If no value is set, the modal is closed immediately when the `$locationChangeSuccess` event fires. If `false` is set, event is not fired. If a number `n` is set, then the event fires after `n` milliseconds.\n\n### The Modal Object\n\nThe `modal` object returned by `showModal` has this structure:\n\n* `modal.element` - The created DOM element. This is a jquery lite object (or jquery if full\n  jquery is used). If you are using a bootstrap modal, you can call `modal` on this object\n  to show the modal.\n* `modal.scope` - The new scope created for the modal DOM and controller.\n* `modal.controller` - The new controller created for the modal.\n* `modal.close` - A promise which is resolved when the modal `close` function is called.\n* `modal.closed` - A promise which is resolved once the modal has finished animating out of the DOM.\n\n### The Modal Controller\n\nThe controller that is used for the modal always has one extra parameter injected, a function\ncalled `close`. Call this function with any parameter (the result). This result parameter is\nthen passed as the parameter of the `close` and `closed` promises used by the caller.\n\n### Closing All Modals\n\nSometimes you may way to forcibly close all open modals, for example if you are going to transition routes. You can use the `ModalService.closeModals` function for this:\n\n```js\nModalService.closeModals(optionalResult, optionalDelay);\n```\n\nThe `optionalResult` parameter is pased into all `close` promises, the `optionalDelay` parameter has the same effect as the controller `close` function delay parameter.\n\n### Animation\n\n`ModalService` cooperates with Angular's `$animate` service to allow easy implementation of\ncustom animation. Specifically, `showModal` will trigger the `ng-enter` hook, and calling\n`close` will trigger the `ng-leave` hook. For example, if the `ngAnimate` module is\ninstalled, the following CSS rules will add fade in/fade out animations to a modal with the\nclass `modal`:\n\n```css\n.modal.ng-enter {\n  transition: opacity .5s ease-out;\n  opacity: 0;\n}\n.modal.ng-enter.ng-enter-active {\n  opacity: 1;\n}\n.modal.ng-leave {\n  transition: opacity .5s ease-out;\n  opacity: 1;\n}\n.modal.ng-leave.ng-leave-active {\n  opacity: 0;\n}\n```\n\n### Error Handing\n\nAs the `ModalService` exposes only one function, `showModal`, error handling is always performed in the same way.\nThe `showModal` function returns a promise - if any part of the process fails, the promise will be rejected, meaning\nthat a promise error handling function or `catch` function can be used to get the error details:\n\n```js\nModalService.showModal({\n  templateUrl: \"some/template.html\",\n  controller: \"SomeController\"\n}).then(function(modal) {\n  // only called on success...\n}).catch(function(error) {\n  // error contains a detailed error message.\n  console.log(error);\n});\n```\n\n### Global Options Configuration\n\nTo configure the default options that will apply to all modals call `configureOptions` on the `ModalServiceProvider`.\n\n```js\napp.config([\"ModalServiceProvider\", function(ModalServiceProvider) {\n\n  ModalServiceProvider.configureOptions({closeDelay:500});\n\n}]);\n```\n\nHere are the available global options:\n* `closeDelay` - This sets the default number of milliseconds to use in the close handler. This delay will also be used in the `closeModals` method and as the default for `locationChangeSuccess`.\n\n## Developing\n\nTo work with the code, just run:\n\n```\nnpm install\nnpm test\nnpm start\n```\n\nThe dependencies will install, the tests will be run (always a useful sanity check after a clean checkout) and the code will run. You can open the browser at localhost:8080 to see the samples. As you change the code in the `src/` folder, it will be re-built and the browser will be updated.\n\nThe easiest way to adapt the code is to play with some of the examples in the ``samples`` folder.\n\n## Tests\n\nRun tests with:\n\n```\nnpm test\n```\n\nA coverage report is written to `build\\coverage`.\n\nDebug tests with:\n\n```\nnpm run test-debug\n```\n\nThis will run the tests in Chrome, allowing you to debug.\n\n## Releasing\n\nTo create a release:\n\n- Create the `dst` pack with `npm run build`\n- Merge your work to master\n- Use `npm run release` to tag, bump the version numbers and update the changelog\n- Push and deploy `git push --follow-tags \u0026\u0026 npm publish`\n\n## FAQ\n\nHaving problems? Check this FAQ first.\n\n**I'm using a Bootstrap Modal and the backdrop doesn't fade away**\n\nThis can happen if your modal template contains more than one top level element.\nImagine this case:\n\n```html\n\u003c!-- Some comment --\u003e\n\u003cdiv\u003e...some modal\u003c/div\u003e\n```\n\nWhen you create the modal, the Angular Modal Service will add both of these elements\nto the page, then pass the elements to you as a jQuery selector. When you call bootstrap's\n`modal` function on it, like this:\n\n```js\nmodal.element.modal();\n```\n\nIt will try and make both elements into a modal. This means both elements will get a backdrop.\nIn this case, either remove the extra elements, or find the specific element you need\nfrom the provided `modal.element` property.\n\n**The backdrop STILL does not fade away after I call `close` OR I don't want to use the 'data-dismiss' attribute on a button, how can I close a modal manually?**\n\nYou can check the 'Complex' sample ([complexcontroller.js](samples/complex/complexcontroller.js)). The 'Cancel' button closes without using the `data-dismiss` attribute. In this case, just use the `preClose` option to ensure the bootstrap modal is removed:\n\n```js\nModalService.showModal({\n  templateUrl: \"some/bootstrap-template.html\",\n  controller: \"SomeController\",\n  preClose: (modal) =\u003e { modal.element.modal('hide'); }\n}).then(function(modal) {\n  // etc\n});\n```\n\nAnother option is to grab the modal element in your controller, then call the bootstrap `modal` function\nto manually close the modal. Then call the `close` function as normal:\n\n```js\napp.controller('ExampleModalController', [\n  '$scope', '$element', 'close',\n  function($scope, $element, close) {\n\n  $scope.closeModal = function() {\n\n    //  Manually hide the modal using bootstrap.\n    $element.modal('hide');\n\n    //  Now close as normal, but give 500ms for bootstrap to animate\n    close(null, 500);\n  };\n\n}]);\n```\n\n**I'm using a Bootstrap Modal and the dialog doesn't show up**\n\nCode is entered exactly as shown the example but when the showAModal() function fires the modal template html is appended to the body while the console outputs:\n\n```\nTypeError: undefined is not a function\n```\n\nPointing to the code: `modal.element.modal();`. This occurs if you are using a Bootstap modal but have not included the Bootstrap JavaScript. The recommendation is to include the modal JavaScript before AngularJS.\n\n**How can I prevent a Bootstrap modal from being closed?**\n\nIf you are using a bootstrap modal and want to make sure that only the `close` function will close the modal (not a click outside or escape), use the following attributes:\n\n```html\n\u003cdiv class=\"modal\" data-backdrop=\"static\" data-keyboard=\"false\"\u003e\n```\n\nTo do this programatically, use:\n\n```js\nModalService.showModal({\n  templateUrl: \"whatever.html\",\n  controller: \"WhateverController\"\n}).then(function(modal) {\n  modal.element.modal({\n    backdrop: 'static',\n    keyboard: false\n  });\n  modal.close.then(function(result) {\n    //  ...etc\n  });\n});\n```\n\nThanks [lindamarieb](https://github.com/lindamarieb) and [ledgeJumper](https://github.com/ledgeJumper)!\n\n**Problems with Nested Modals**\n\nIf you are trying to nest Bootstrap modals, you will run into issues. From Bootstrap:\n\n\u003e Bootstrap only supports one modal window at a time. Nested modals aren’t supported as we believe them to be poor user experiences.\n\nSee: https://v4-alpha.getbootstrap.com/components/modal/#how-it-works\n\nSome people have been able to get them working (see https://github.com/dwmkerr/angular-modal-service/issues/176). Unfortunately, due to the lack of support in Bootstrap is has proven troublesome to support this in angular-modal-service.\n\n## Thanks\n\nThanks go the the following contributors:\n\n* [DougKeller](https://github.com/DougKeller) - Adding support for Angular 1.5 components.\n* [joshvillbrandt](https://github.com/joshvillbrandt) - Adding support for `$templateCache`.\n* [cointilt](https://github.com/cointilt) - Allowing the modal to be added to a custom element, not just the body.\n* [kernowjoe](https://github.com/kernowjoe) - controllerAs\n* [poporul](https://github.com/poporul) - Improving the core logic around compilation and inputs.\n* [jonasnas](https://github.com/jonasnas) - Fixing template cache logic.\n* [maxdow](https://github.com/maxdow) - Added support for controller inlining.\n* [kernowjoe](https://github.com/kernowjoe) - Robustness around locationChange\n* [arthur-xavier](https://github.com/arthur-xavier) - Robustness when `body` element changes.\n* [stormpooper](https://github.com/StormPooper) - The new `bodyClass` feature.\n* [decherneyge](https://github.com/decherneyge) - Provider features, global configuration, `appendElement` improvements.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdwmkerr%2Fangular-modal-service","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdwmkerr%2Fangular-modal-service","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdwmkerr%2Fangular-modal-service/lists"}