How to transclude content in ui bootstrap modal directive
Solution 1
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.
Solution 2
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
Comments
-
Florian F almost 2 years
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.
-
Florian F over 11 yearsThanks for your answer. I'll have a try. However, to be honest, , I'm more intersted to know what is wrong in my example
-
rkmax over 11 yearsI decided to make a solution that does not use angular-ui by a bad experience because angular-ui gave me more problems than solutions. but will watch closely the modal directive from angular-ui