I have a directive that works correctly when RequireJS is not used, and I'm trying to migrate it to an application based on RequireJS.
The directive wraps an Angular UI modal, and uses transclude to populate the modal elements (modal elements are defined in the controller that declares the directive). The problem is that if loaded with RequireJS, the modal does not show ANY elements (i.e. it's empty).
This is the plunk of the directive that works correctly without RequireJS. You will see a modal populated with elements.
This is the plunk of the directive that is loaded with RequireJS. You will see that the modal is empty.
There are no errors thrown when the modal is displayed empty, so I'm not sure how to tackle this problem. Any help will be greatly appreciated.
This is the directive:
define(['app','uiBootstrap'], function (app) {
'use strict';
app.directive("theModal", function($timeout,$uibModal) {
return {
restrict: "AE",
scope: {
control: '='
},
transclude: true,
link: function (scope, element, attrs, ctrl, transclude) {
scope.control = scope.control || {}
scope.control.openModal = function () {
var instance = $uibModal.open({
animation: false,
scope: scope,
windowClass: 'the-modal',
template: '<div>in the template</div><div class="content"></div>',
appendTo: element
});
$timeout(function (){
transclude(scope.$parent, function(clonedContent){
element.find('.content').append(clonedContent);
})
},10);
};
}
}
});
});
And this is how I invoke it:
<div ng-controller="ctl">
<button ng-click="open()">open it!</button>
<div the-modal control="modalCtl">
<p>some text</p>
<input type="text" ng-model="input1" />
</div>
</div>
The issue is you have circular dependency. The app needs your modal module to display things correctly, but your modal directive needs that app. The solution is to load your modal directive into a separate module.
Define a separate Angular Module for Modal
// contents of modal.js (remove app dependency)
define(['uiBootstrap'], function () {
'use strict';
var mod = angular.module('modal', ['ui.bootstrap']);
mod.directive("theModal", function($timeout, $uibModal) {
return {
restrict: "AE",
scope: {
control: '='
},
transclude: true,
link: function (scope, element, attrs, ctrl, transclude){
// removed code for brevity
}
}
});
mod.directive("theButton", function($timeout) {
return {
restrict: "AE",
scope: {
control: '='
},
transclude: true,
link: function (scope, element, attrs, ctrl, transclude){
// removed code for brevity
}
}
});
return mod;
});
Make app depend on Modal
// contents of app.js
define([
'angular',
'uiBootstrap',
'uiRouter',
'modal' // <--- the modal.js directive
], function (angular) {
'use strict';
return angular.module('app', ['ui.bootstrap','ui.router', 'modal']); // <--- also add it here
});
Related
In my directive I have a html button. I want to call a function when it is clicked. I have not much knowledge about angular js. So I want to open a modal when the button clicked.
I think the path is,
html button -> showModal() function inside the directive. this showModal() is a webservice function which call a modal with webservice.
I have added the ng-click="documentManagerButtonCtrl.showDocumentModal()" in the html.
but it is not calling the directive function. can anyone explain how to open a modal with a service when click the button
<div class="col">
<a class='btn'
ng-click="pimDocumentManagerButtonCtrl.showDocumentModal()"
data-target='demoModal' modal>Create</a>
</div>
(function () {
'use strict';
angular
.module('app.directives')
.directive('documentManagerButton', documentManagerButton);
/* #ngInject */
function documentManagerButton() {
return {
restrict: 'E',
templateUrl: 'directives/document_manager.html',
scope: {
datagroupName: "#",
employeeNumber: "=",
documentTemplateDetails: "=",
employeeService: "="
},
bindToController: true,
link: function (scope, element, attrs) {
},
controller: documentManagerController,
controllerAs: 'DocumentManagerButtonCtrl'
};
}
documentManagerController.$inject = ['webservice', '$q', 'modalHelperService'];
function documentManagerController(webservice, $q) {
var vm = this;
function showDocumentModal(){
modalHelperService.showModal(
'app/document/document_modal.html',
'documentController',
'modal'
);
}
}
})();
Change
controllerAs: 'DocumentManagerButtonCtrl'
to
controllerAs: 'vm'
because you have
var vm = this;
After that you need expose showDocumentModal() function with
vm.showDocumentModal = showDocumentModal;
And then you can call with ng-click:
ng-click="vm.showDocumentModal()"
In this plunk I have an Angular UI modal with an alert popup that should display the modal height. Instead, it shows an empty variable. Where's the error?
HTML
<div the-modal></div>
Javascript
var app = angular.module("app", ['ui.bootstrap']);
app.controller("ctl", function($scope, $compile) {});
app.directive("theModal", function($uibModal, $timeout) {
return {
restrict: "AE",
scope: true,
link: function(scope, element, attrs, ctrl, transclude) {
scope.instance = $uibModal.open({
animation: false,
scope: scope,
template: 'Some Text',
appendTo: element
});
$timeout(function(){
alert("Modal height is: " + element.css("height"));
},500);
}
}
});
The content has been placed inside div with modal-dialog class inside directive modal placeholder element. So ideally you should be looking at element's inner modal-content class.
element[0].querySelector('.modal-dialog').offsetHeight
I have a bootstrap tooltip which isnt rendering within my NG-repeat from my research I see the tooltip wont render on angular driven content and a directive should be created to handle this issue to establish it.
If I have an existing directive relating to this ng-repeat is it possible to include this in the existing directive?
From another stackoverflow article I took on board their tooltip function and tried to apply it to my existing directive but it isn't working:
(function () {
'use strict';
angular
.module("tpAccStatus")
.directive(["tpAccStatusTransactionRow", tpAccStatusTransactionRow], ["tooltip", tooltip]);
function tpAccStatusTransactionRow() {
return {
scope: {
trans: "=tpAccStatusTransactionRow",
accountNumber: "=",
setMessageState: '&'
},
restrict: "A",
replace: true,
templateUrl: "tpAccStatusTransactionRow.directive.html",
bindToController: true,
controller: "tpAccStatusTransactionRowCtrl",
controllerAs: "transCtrl"
};
}
function tooltip() {
return {
restrict: 'A',
link: function (scope, element, attrs) {
$(element).hover(function () {
$(element).tooltip('show');
}, function () {
$(element).tooltip('hide');
});
}
};
}
})();
Within my directive template I then reference:
<td><span tooltip data-toggle="tooltip" title="" data-original-title="Select an Account"><span class="fa fa-sort fa-fw"></span></span></td>
Thanks
I have a search box which I want to use as a custom directive. This is the code for it :
(function(angular) {
'use strict';
angular.module('searchApp', [])
.directive('searchBox', function () {
return {
restrict: 'E',
transclude: true,
scope: {
'btnclick': '&onClick'
},
link: function(scope, elem, attrs) {
});
});
},
templateUrl: 'search-box.html'
}
});
})(window.angular);
In the link part, I need a function that has some JSON data. And then, a directive should have a controller that invokes that function and passes it to the parent scope.
Please show me code for the link function and the controller.
I would create a glossary, using an AngularJS directive. I start with this fiddle
http://jsfiddle.net/angularjsdc/KRVSQ/
I want to change the directive and substitute the modal with a tooltip.
app.directive('glossaryTerm', function () {
return {
controller: 'Glossary',
restrict: 'E',
scope: { /* empty */
},
template: /*HERE MY TOOLTIP TEMPLATE*/,
replace: true,
transclude: true,
compile: function (tElement, tAttrs, transclude) {
return {
pre: function (scope) {
transclude(scope, function (clone) {
scope.term = clone[0].textContent.toLowerCase();
});
},
post: function (scope) {
// load the definition into scope
scope.getDefinition(scope.term);
}
}
}
}
});
Any suggestion? Ideas?
Thanks
In the Angular bootstrap ui example you had to:
include http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.0.js
import the module
var app = angular.module('app', ['app.services', 'ui.bootstrap']);
and surround the variables you were passing into tooltip with {{}}
template: '<span><a class="glossary-term" href="#" tooltip="{{glossary[term]}}">{{term}}</a></span>',
Here's the modified JSFiddle: http://jsfiddle.net/5DuSa/