74

Using the example mentioned here, how can I invoke the modal window using JavaScript instead of clicking a button?

I am new to AngularJS and tried searching the documentation here and here without luck.

Thanks

Ahmad Alfy
  • 13,107
  • 6
  • 65
  • 99

6 Answers6

76

OK, so first of all the http://angular-ui.github.io/bootstrap/ has a <modal> directive and the $dialog service and both of those can be used to open modal windows.

The difference is that with the <modal> directive content of a modal is embedded in a hosting template (one that triggers modal window opening). The $dialog service is far more flexible and allow you to load modal's content from a separate file as well as trigger modal windows from any place in AngularJS code (this being a controller, a service or another directive).

Not sure what you mean exactly by "using JavaScript code" but assuming that you mean any place in AngularJS code the $dialog service is probably a way to go.

It is very easy to use and in its simplest form you could just write:

$dialog.dialog({}).open('modalContent.html');  

To illustrate that it can be really triggered by any JavaScript code here is a version that triggers modal with a timer, 3 seconds after a controller was instantiated:

function DialogDemoCtrl($scope, $timeout, $dialog){
  $timeout(function(){
    $dialog.dialog({}).open('modalContent.html');  
  }, 3000);  
}

This can be seen in action in this plunk: http://plnkr.co/edit/u9HHaRlHnko492WDtmRU?p=preview

Finally, here is the full reference documentation to the $dialog service described here: https://github.com/angular-ui/bootstrap/blob/master/src/dialog/README.md

pkozlowski.opensource
  • 117,202
  • 60
  • 326
  • 286
  • 1
    @AhmadAlfy yes, there are some options that allow you to control visual aspects of the modal. But more importantly it has many super-powers and allows you to treat $dialogs almost like AngularJS routes, pass data between the main window and the modal (and back) etc. – pkozlowski.opensource Apr 28 '13 at 18:34
  • Yeah, the readme link is broken on the angular site also. I'd really like to read that file, but I can't figure out where it's hidden. :( – Tim Gautier Aug 28 '13 at 22:21
  • 27
    Seems like $dialog has been replaced by a rewritten version of $modal: https://github.com/angular-ui/bootstrap/tree/d7a48523e437b0a94615350a59be1588dbdd86bd/src – Per Quested Aronsson Sep 17 '13 at 13:36
  • $modal readme is [here](https://github.com/angular-ui/bootstrap/blob/master/src/modal/docs/readme.md). – Mendhak Sep 17 '13 at 15:29
  • 1
    [And here's some more info on the dialog re-write](https://gist.github.com/ajoslin/5477996). – keithl8041 Nov 19 '13 at 17:12
  • 1
    For those, like me, going back to Bootstrap 2.3.2 and Angular-UI-Bootstrap 0.5.0, I *think* the latest docs on the now defunct $dialog would be over here: https://github.com/angular-ui/bootstrap/commit/d7a48523e437b0a94615350a59be1588dbdd86bd – FOR Dec 27 '13 at 14:11
  • i wanted to include (modal) html element in same page rather then creating external html file (externalTemplate.html'). any suggestion ! – Rizwan Patel Jul 13 '16 at 13:08
29

To make angular ui $modal work with bootstrap 3 you need to overwrite the styles

.modal {
    display: block;
}
.modal-body:before,
.modal-body:after {
    display: table;
    content: " ";
}
.modal-header:before,
.modal-header:after {
    display: table;
    content: " ";
}

(The last ones are necessary if you use custom directives) and encapsulate the html with

<div class="modal-dialog">
  <div class="modal-content">
    <div class="modal-header">
      <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
      <h4 class="modal-title">Modal title</h4>
    </div>
    <div class="modal-body">
      ...
    </div>
    <div class="modal-footer">
      <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
      <button type="button" class="btn btn-primary">Save changes</button>
    </div>
  </div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
Hawk
  • 1,513
  • 1
  • 14
  • 17
26

Open modal windows with passing data to dialog

In case if someone interests to pass data to dialog:

app.controller('ModalCtrl', function($scope,  $modal) {
      
      $scope.name = 'theNameHasBeenPassed';

      $scope.showModal = function() {
        
        $scope.opts = {
        backdrop: true,
        backdropClick: true,
        dialogFade: false,
        keyboard: true,
        templateUrl : 'modalContent.html',
        controller : ModalInstanceCtrl,
        resolve: {} // empty storage
          };
          
        
        $scope.opts.resolve.item = function() {
            return angular.copy(
                                {name: $scope.name}
                          ); // pass name to resolve storage
        }
        
          var modalInstance = $modal.open($scope.opts);
          
          modalInstance.result.then(function(){
            //on ok button press 
          },function(){
            //on cancel button press
            console.log("Modal Closed");
          });
      };                   
})

var ModalInstanceCtrl = function($scope, $modalInstance, $modal, item) {
    
     $scope.item = item;
    
      $scope.ok = function () {
        $modalInstance.close();
      };
      
      $scope.cancel = function () {
        $modalInstance.dismiss('cancel');
      };
}

Demo Plunker

Community
  • 1
  • 1
Maxim Shoustin
  • 77,483
  • 27
  • 203
  • 225
17

The AngularJS Bootstrap website hasn't been updated with the latest documentation. About 3 months ago pkozlowski-opensource authored a change to separate out $modal from $dialog commit is below:

https://github.com/angular-ui/bootstrap/commit/d7a48523e437b0a94615350a59be1588dbdd86bd

In that commit he added new documentation for $modal, which can be found below:

https://github.com/angular-ui/bootstrap/blob/d7a48523e437b0a94615350a59be1588dbdd86bd/src/modal/docs/readme.md.

Hope this helps!

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
Craig Ruks
  • 171
  • 1
  • 2
17

Quick and Dirty Way!

It's not a good way, but for me it seems the most simplest.

Add an anchor tag which contains the modal data-target and data-toggle, have an id associated with it. (Can be added mostly anywhere in the html view)

<a href="" data-toggle="modal" data-target="#myModal" id="myModalShower"></a>

Now,

Inside the angular controller, from where you want to trigger the modal just use

angular.element('#myModalShower').trigger('click');

This will mimic a click to the button based on the angular code and the modal will appear.

Gagandeep Singh
  • 299
  • 2
  • 7
  • Is this actually a **good** **practice**? Is this recommended or discouraged? Using this way, how it can affect the performance? *Of course writing a line of code is easier than writing a whole function* **But, Still** – Saiyaff Farouk Jul 27 '16 at 14:32
  • 1
    Like I said "It's not a good way..." because it's inconsistent with the design paradigm of angular. I think it's discouraged because of that reason. For the performance part - I don't think it should cause any difference. But, again if I was the expert, I shouldn't have followed this shortcut approach. It's just a quick and dirty way to get things done. :) Do tell me if you find something regarding this. – Gagandeep Singh Jul 28 '16 at 16:21
  • I'm new to Angular, and to get my modal up-and-running this worked very well indeed. I can come back and do it properly once I've learnt how (and this milestone deadline has passed) – VictorySaber Aug 24 '16 at 08:28
4

Different version similar to the one offered by Maxim Shoustin

I liked the answer but the part that bothered me was the use of <script id="..."> as a container for the modal's template.

I wanted to place the modal's template in a hidden <div> and bind the inner html with a scope variable called modal_html_template mainly because i think it more correct (and more comfortable to process in WebStorm/PyCharm) to place the template's html inside a <div> instead of <script id="...">

this variable will be used when calling $modal({... 'template': $scope.modal_html_template, ...})

in order to bind the inner html, i created inner-html-bind which is a simple directive

check out the example plunker

<div ng-controller="ModalDemoCtrl">

    <div inner-html-bind inner-html="modal_html_template" class="hidden">
        <div class="modal-header">
            <h3>I'm a modal!</h3>
        </div>
        <div class="modal-body">
            <ul>
                <li ng-repeat="item in items">
                    <a ng-click="selected.item = item">{{ item }}</a>
                </li>
            </ul>
            Selected: <b>{{ selected.item }}</b>
        </div>
        <div class="modal-footer">
            <button class="btn btn-primary" ng-click="ok()">OK</button>
            <button class="btn btn-warning" ng-click="cancel()">Cancel</button>
        </div>
    </div>

    <button class="btn" ng-click="open()">Open me!</button>
    <div ng-show="selected">Selection from a modal: {{ selected }}</div>
</div>

inner-html-bind directive:

app.directive('innerHtmlBind', function() {
  return {
    restrict: 'A',
    scope: {
      inner_html: '=innerHtml'
    },
    link: function(scope, element, attrs) {
      scope.inner_html = element.html();
    }
  }
});
Jossef Harush Kadouri
  • 32,361
  • 10
  • 130
  • 129
  • the links for the items don't appear in your plunker - unfortunately i'm still pretty new w/ angular to determine why. – jae Feb 14 '15 at 16:00