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
<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>
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 : '&'
}
};
});
<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.
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.
Check this solution, you dont need a extra controller or angular-ui for that only pass a simple handler and use it
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();
<!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>
<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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With