Tuco Tuco - 6 months ago 39
jQuery Question

JQuery UI Slider inside Modal Dialog

My JQuery UI Slider widget doesn't show up inside a Modal, it does show in normal content though.

HERE'S THE PLUNKER

<!DOCTYPE html>
<html ng-app="ui.bootstrap.demo">

<head>
<script data-require="jquery@*" data-semver="2.2.0" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<link data-require="jqueryui@*" data-semver="1.10.0" rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.0/css/smoothness/jquery-ui-1.10.0.custom.min.css" />
<script data-require="jqueryui@*" data-semver="1.10.0" src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.0/jquery-ui.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular-animate.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-1.3.3.js"></script>
<script src="example.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
</head>

<body>
<div ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3 class="modal-title">I'm a modal!</h3>
</div>
<div class="modal-body">

<span>SLIDER?</span>
<div class="slider"></div>

</div>
<div class="modal-footer">
<button class="btn btn-primary" type="button" ng-click="ok()">OK</button>
<button class="btn btn-warning" type="button" ng-click="cancel()">Cancel</button>
</div>
</script>
<button type="button" class="btn btn-default" ng-click="open()">Open me!</button>


<div>
<span>SLIDER OK</span>
<div class="slider"></div>
</div>
</div>
</body>
</html>


JavasCript

angular.module('ui.bootstrap.demo', ['ngAnimate', 'ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function($scope, $uibModal, $log) {

$scope.animationsEnabled = true;
$scope.open = function(size) {

var modalInstance = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
items: function() {
return $scope.items;
}
}
});

modalInstance.result.then(function(selectedItem) {

}, function() {
$log.info('Modal dismissed at: ' + new Date());
});
};
});


angular.module('ui.bootstrap.demo').controller('ModalInstanceCtrl', function($scope, $uibModalInstance, items) {



$scope.cancel = function() {
$uibModalInstance.dismiss('cancel');
};
});
$(function() {
$(".slider").slider();
});

Answer

The issue is that the slider is created when the page loads instead of when the modal is open. Then the slider is created at the beginning and fails when in the modal.

A posssible solution would be to create the slider when the modal opens (and specifying in the selector that it will be the slider inside the modal, otherwise it seems that jQuery will create a slider also for the code in the template).

Here is a demo modifying your original code as little as possible (I moved the slider creation to the function that opens and renders the modal):

angular.module('ui.bootstrap.demo', ['ngAnimate', 'ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function($scope, $uibModal, $log) {

  $scope.items = ['item1', 'item2', 'item3'];

  $scope.animationsEnabled = true;

  $scope.open = function(size) {

    var modalInstance = $uibModal.open({
      animation: $scope.animationsEnabled,
      templateUrl: 'myModalContent.html',
      controller: 'ModalInstanceCtrl',
      size: size,
      resolve: {
        items: function() {
          return $scope.items;
        }
      }
    });

    modalInstance.rendered.then( function() {
      $(".modal-body .slider").slider()
    });

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



});

// Please note that $uibModalInstance represents a modal window (instance) dependency.
// It is not the same as the $uibModal service used above.

angular.module('ui.bootstrap.demo').controller('ModalInstanceCtrl', function($scope, $uibModalInstance, items) {
  $scope.cancel = function() {
    $uibModalInstance.dismiss('cancel');
  };
});
<script data-require="jquery@*" data-semver="2.2.0" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<link data-require="jqueryui@*" data-semver="1.10.0" rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.0/css/smoothness/jquery-ui-1.10.0.custom.min.css" />
<script data-require="jqueryui@*" data-semver="1.10.0" src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.0/jquery-ui.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular-animate.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-1.3.3.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />

<div ng-app="ui.bootstrap.demo">
  <div ng-controller="ModalDemoCtrl">
    <script type="text/ng-template" id="myModalContent.html">
      <div class="modal-header">
        <h3 class="modal-title">I'm a modal!</h3>
      </div>
      <div class="modal-body">
        <span>SLIDER?</span>
        <div class="slider"></div>
      </div>
      <div class="modal-footer">
        <button class="btn btn-primary" type="button" ng-click="ok()">OK</button>
        <button class="btn btn-warning" type="button" ng-click="cancel()">Cancel</button>
      </div>
    </script>
    <button type="button" class="btn btn-default" ng-click="open()">Open me!</button>

    <div>
      <span>Slider OK</span>
      <div class="slider"></div>
    </div>
  </div>
</div>