Jose Rojas
Jose Rojas

Reputation: 1

AngularJS templates + Bootstrap modals

I am trying to create some Bootstrap modals dynamically using AngularJS, as described in here: https://angular-ui.github.io/bootstrap/

For that purpose, I have created a basic script template in AngularJS inside a view of a directive called modalView.html:

<script type="text/ng-template" **id="{{modalId}}.html"**>
<div class="modal-header">
    Header
</div>
<div class="modal-body">
    Body
</div>
<div class="modal-footer">
    Footer
</div>
</script>

And this is my directive (modalDirective.js):

myDirectives.directive('modal', function () {
return {
    restrict: 'A',
    scope: {},
    templateUrl: 'shared/controls/modal/modalView.html',
    link: function (scope, element, attributes) {
        scope.modalId = attributes['modalId'];
    }
}
});

Then, I have another directive that uses the aforementioned directive alongside a textbox that should open the modal when the latter is clicked.

modalTextboxView.html:

<div modal modal-id="{{modalId}}"></div>
<div textbox is-read-only="true" ng-click="openModal()"></div>

modalTextboxDirective.js:

myDirectives.directive('modalTextbox', function ($modal, $log) {
return {
    restrict: 'A',
    scope: {},
    templateUrl: 'shared/controls/modalTextbox/modalTextboxView.html',
    link: function (scope, element, attributes) {
        scope.modalId = attributes['fieldId'];
        scope.openModal = function(modalSize) {
            var modalInstance = $modal.open({
                **templateUrl: scope.modalId + '.html',**
                size: modalSize,
                resolve: {
                    items: function () {
                        return scope.items;
                    }
                }
            });

            modalInstance.result.then(function (selectedItem) {
                scope.selected = selectedItem;
            }, function () {
                $log.info('Modal dismissed at: ' + new Date());
            });
        }
    }
}
});

The html output is as expected. I can see that the script template id of the first view is being set correctly. However, when I click on the textbox I get an error 404. It seems that the modal is trying to be opened but can't find the templateUrl defined, which has been set correctly too. Moreover, if I just type the hardcoded value into the id field of the script template it works flawlessly and it opens the modal. Unfortunately, I need that id to be dynamic as I need to be able to create and generate an undetermined number of modals on my page.

Any ideas?

Upvotes: 0

Views: 1581

Answers (1)

New Dev
New Dev

Reputation: 49590

You can't use the <script type="text/ng-template"> approach to define a dynamically bound template id.

All that Angular is doing (see src) when it encounters this type of <script> tag is that it adds the contents into a $templateCache service with the uninterpolated value of the id attribute; and, in fact, it adds it at compile-time before it could be interpolated.

So, the template is added with a key of "{{modalId}}.html" - literally. And when you request it with templateUrl: "ID123.html", it results in a cache miss and an attempt to download from that non-existent URL.

So, what are you actually trying to get out of this "dynamic" modal URL?

I don't understand the use of your modal directive - all it attempts to do is to dynamically assign an id for the template. Why? If you just need to define N templates and dynamically switch between them, then just define N <script> tags inside your modalTextbox directive:

<script type="text/ng-template" id="modal-type-1">
  template 1
</script>
<script type="text/ng-template" id="modal-type-2">
  template 2
</script>
<div textbox is-read-only="true" ng-click="openModal()"></div>

and in the invocation of $modal, set templateUrl like so:

$modal.open({
   templateUrl: "modal-type-" + scope.modalType,
   // ...
});

Upvotes: 2

Related Questions