Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to transclude content in ui bootstrap modal directive

I've made a custom directive on top of ui bootstrap modal directive so I can use the same modal template everywhere in my app.

My directive works until I try to transclude its content into the template:

http://plnkr.co/edit/YPESA3?p=preview


From index.html

<div ng-controller="ModalDemoCtrl">
  <button class="btn" ng-click="open()">Open me!</button>
  
  <my:modal open="shouldBeOpen" close="close()">
    <h1>Content</h1>
  </my:modal>
</div>

Module code:

angular.module('plunker', ['ui.bootstrap'])

.controller('ModalDemoCtrl', function($scope) {
  $scope.open = function () {
    $scope.shouldBeOpen = true;
  };

  $scope.close = function () {
    $scope.closeMsg = 'I was closed at: ' + new Date();
    $scope.shouldBeOpen = false;
  };

  $scope.items = ['item1', 'item2'];

})


.directive('myModal', function() {
  return {
    restrict : 'E',
    templateUrl: 'myTpl.html',
    //transclude: true,
    scope : {
      open : '=',
      close : '&'
    }
  };
});

Modal template:

<div modal="open">
    <div class="modal-header">
        <h4>I'm a modal!</h4>
    </div>
    <div class="modal-body">
      <!--<div ng-transclude/>-->
    </div>
       
    
    <div class="modal-footer">
      <button class="btn btn-warning cancel" ng-click="close()">Cancel</button>
    </div>
</div>

Uncomment transclude property from the directive and the template and you'll see you get a TypeError: undefined is not a function.

I can't figure what I'm doing wrong.

like image 642
Florian F Avatar asked Mar 07 '13 23:03

Florian F


2 Answers

OP, your snippet is exactly what I was looking to do—thanks!

I managed to get your plunk working by passing replace:true as well as transclude: true

Here's the updated plunk http://plnkr.co/edit/gxCS2V?p=preview

I'm new to Angular, so I was interested to know why:

replace - if set to true then the template will replace the current element, rather than append the template to the element.

(via the Angular docs)

Which, of course makes sense once you know.

Good to know if you want to make your directive especially recyclable. Modals are pretty perfect example.

Related : ui-bootstrap is worth checking out.

like image 175
couzzi Avatar answered Oct 07 '22 04:10

couzzi


Check this solution, you dont need a extra controller or angular-ui for that only pass a simple handler and use it

example.js

angular.module('plunker', [], function() {

})

.directive('modal', function() {
  return {
    restrict : 'E',
    templateUrl: 'myTpl.html',
    transclude: true,
    controller: function($scope) {
      // you need get a better unique generator
      $scope.modal_id = 'modal_' + Math.floor((Math.random()*100+1));
      $scope.handler = $scope.modal_id;
    },
    scope : {
      handler : '='
    }
  };
})
.run();

index.html

<!doctype html>
<html ng-app="plunker">
  <head>    
    <link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet">    
  </head>
<body>

<div ng-init="handler = null">  
  <modal handler="handler">
    <h1>Content</h1>
  </modal>  
  <a href="#{{handler}}" role="button" class="btn primary" data-toggle="modal">Open me</a>
</div>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.js"></script>    
    <script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/js/bootstrap.min.js"></script>
    <script src="example.js"></script>
</body>
</html>

myTpl.html

<div id="{{modal_id}}" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="{{modal_id}}Label" aria-hidden="true">
    <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
        <h4 id="{{modal_id}}Label">I'm a modal!</h4>
    </div>
    <div class="modal-body">
      <div ng-transclude></div>
    </div>    
    <div class="modal-footer">
      <button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
    </div>
</div>

look how works in plunker

like image 45
rkmax Avatar answered Oct 07 '22 03:10

rkmax