Question

I am trying to execute a jQuery script on the opened modal in order to transform one of the fields to a jQuery UI Spinner.

I am using the opened promise as documented in Angular UI.

ISSUE: The jQuery selector does not work as expected and doesn't retrieve anything.

So one of my controller's functions looks like that:

var modalInstance = $modal.open({
    templateUrl: 'modalDialog.html',
    controller: modalCtrl,
    resolve: {
        noOfItems: function(){
            return $scope.noOfItems;
        }
    }
});

modalInstance.opened
    .then(function () {
        $(".spinner").spinner({
            max: 20,
            min: 1
        });
    });

modalInstance.result
    .then(function () {
        console.log("modal closed");
    });

And my HTML:

<script type="text/ng-template" id="modalDialog.html">
    <div class="modal-header">
        <h4 class="modal-title">My Modal</h4>
    </div>
    <div class="modal-body">
        <input class="form-control spinner" type="text" ng-model="noOfItems" />
    </div>
    <div class="modal-footer">
        <button class="btn btn-default" ng-click="cancel()">Cancel</button>
        <button class="btn btn-primary" ng-click="save()">Save</button>
    </div>
</script>

The modalCtrl is irrelevant.

HINT: I tried putting a debugger right when the opened promise is called and found out the modal is not opened yet.

FYI, I am using jQuery 1.9.0, jQuery UI 1.10.4, AngularJS 1.2.16 and Angular UI Bootstrap v0.11.

Was it helpful?

Solution

You are approaching the problem from the wrong angle, trying to do a low-level DOM manipulation from a controller. This is a big no-no in the AngularJS world and you will get you into all sort of troubles down the road.

Your UI logic shouldn't be "waiting" for a given DOM node to be added to the DOM tree but rather should be expressed declaratively. In this particular case it means that you should write a "slider" directive, something as simple as:

yourModule.directive('mySpinner', function() {
  return {
    link: function(scope, elm) {
      elm.spinner({
        max: 20,
        min: 1
      });
    }
  };
});

and then use this newly defined directive from within modal's HTML:

<input class="form-control spinner" type="text" my-spinner ng-model="noOfItems"/>

This way you don't need to worry when modal's content gets added to the DOM and you've made yourself a favour of having a reusable way of defining spinners!

Coming back to the $modal-related question - the opened promise is resolved when all the data are ready and modal is about to be shown (animation starts etc.) to be able to display waiting indicators or similar. By no means it was designed to know when modal's content gets inserted into the DOM tree as with AngularJS this knowledge is not really needed most of the time.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top