3

In this plunk I have an Angular UI modal that has a related class the-modal to set the height and the width, they are initially set at 300px and 500px respectively.

What I need is to set the height and the width programmatically when the modal is opened, say at 100px and 200px.

I cannot use ng-class as I want the user to be able to define the height and width. For example, newHeight and newWidth below will be taken from a database and used to set the modal dimensions. Any ideas how to make this work?

Javascript

var app = angular.module("app", ['ui.bootstrap']);
app.controller("ctl", function($scope,$uibModal) {


  /*
  * these values are taken from a database
  * and should be used to set the height and width of the modal
  */
  var newHeight = 100;
  var newWidth = 200;


  $scope.open = function () {
    var modalInstance = $uibModal.open({
          animation: false,
          windowClass: 'the-modal',
          templateUrl: 'myModalContent.html'
        });

    };

});

HTML

    <style>
      .the-modal .modal-content{
          width:500px;
          height:300px;
      }
   </style>


  </head>

  <body ng-app="app" ng-controller="ctl">

    <script type="text/ng-template" id="myModalContent.html">
        <p>Some content</p>
    </script>

    <button type="button" class="btn btn-default" ng-click="open()">Open me!</button>

   </body>
ps0604
  • 1,227
  • 23
  • 133
  • 330
  • `I want the user to be able to define the height and width.` how ? – svarog Jan 27 '17 at 08:36
  • The high and width will be stored in a database. When the modal loads it will take the values and set them. I adjusted the plunk to be clearer. – ps0604 Jan 27 '17 at 13:02
  • One thing you _could_ do is programmatically generate a style tag with the width and height, and assign the modal a class that you also put into the style tag. Then you'd just have to clean up the style tag on the dom when the modal closes. – Seiyria Jan 30 '17 at 18:39
  • how exactly can I generate programmatically a style tag? – ps0604 Jan 31 '17 at 02:38

4 Answers4

2

Inject the height and width to your modal controller and use ngStyle, it will add to any style you may already apply using css.

JS:

var newHeight = 400;
var newWidth = 200;

$scope.open = function () {
    var modalInstance = $uibModal.open({
        animation: false,
        windowClass: 'the-modal',
        templateUrl: 'myModalContent.html',
        resolve: {
          height: newHeight,
          width: newWidth
        },
        controller: function($scope, height, width) {
          $scope.height = height;
          $scope.width = width;
        }
});

HTML:

<script type="text/ng-template" id="myModalContent.html">
<div ng-style="{height: height + 'px', width: width + 'px'};">
    <p>Some content</p> height: {{height}}, width: {{width}}
</script>

Forked plunk

svarog
  • 9,477
  • 4
  • 61
  • 77
  • thanks, but it doesn't seem to work. it changes the `content` height/width, and I need to change the `modal` height/width. Also, you're missing the closing `div`. – ps0604 Jan 27 '17 at 17:09
  • maybe `windowTemplateUrl` is what you are looking for ? http://stackoverflow.com/questions/24696224/angular-ui-bootstrap-modal-use-custom-modal-window – svarog Jan 30 '17 at 22:48
1

If possible, move your controller up to the html tag level like this plunker. Then your style tag can change dynamically.

   <style>
      .the-modal .modal-content{
          width:{{dimension.newWidth}}px;
          height:{{dimension.newHeight}}px;
      }
   </style>

Otherwise, you can create a directive that resizes the parent element like this plunker.

Markup:

<script type="text/ng-template" id="myModalContent.html">
  <div parent-dimension="" parent-width="{{vm.width}}" parent-height="{{vm.height}}">
    <p>I am {{vm.width}}px wide and {{vm.height}}px high</p>
  </div>
</script>

JS:

app.directive('parentDimension', [function() {
    return {
        restrict: 'A',
        link: function(scope, elem, attr) {
            var setDimension = function(dimension, val) {
                val = val && parseInt(val);
                if (val) {
                  // Set the dimension of the parent element
                    elem[0].parentNode.style[dimension] = val + 'px';
                }
            };

            // Watch for changes in width and set accordingly
            attr.$observe('parentWidth', function(newVal) {
                setDimension('width', newVal);
            });

            // Watch for changes in height and set accordingly
            attr.$observe('parentHeight', function(newVal) {
                setDimension('height', newVal);
            });
        }
    }
}]);
logee
  • 5,017
  • 1
  • 26
  • 34
1

Might not be the best solution, but I think it solves Your problem.

I created directive adjustModal with hardcoded height/width values, but You can pass them aswell. If you put this directive on first element in modal template, the parent element will be .modal-content so You can change width/height directly using jqLite.

modal template:

<script type="text/ng-template" id="myModalContent.html">
    <div adjust-modal>
      <p>Some content</p>
    </div>
</script>

directive:

app.directive('adjustModal', function() {
      return {
        link: function (scope, element) {
          var height = '100px';
          var width = '100px';
          element.parent().css("width", width)
          element.parent().css("height", height)
        }
      }
    });

working plunker

Kasper Ziemianek
  • 1,329
  • 8
  • 15
0

Hum, what about adding a new stylesheet line to your CSS that you will be using for your popup modal;

var app = angular.module("app", ['ui.bootstrap']);
    app.controller("ctl", function($scope,$uibModal) {

      /*
      * these values are taken from a database
      * and should be used to set the height and width of the modal
      */
      var newHeight = 100;
      var newWidth = 200;

    var style = document.getElementsByTagName("style")[0];

      $scope.open = function () {
      style.sheet.insertRule(".the-modal-changed .modal-content { height: "+newHeight+"px; width: "+newWidth+"px; background:red; }", 0);

        var modalInstance = $uibModal.open({
              animation: false,
              windowClass: 'the-modal-changed',
              templateUrl: 'myModalContent.html'
            });

        };

    });

So I get the content of the current style tag, and added a new style with the rule .the-modal-changed .modal-content { height: "+newHeight+"px; width: "+newWidth+"px; background:red; }

This way, the-modal-changed class will be the class that you want to use for your modal. So I changed the model's windowClass property to this.

Works just fine, but since I'm sure that you are doing something more complex that what your demo shows, not sure if it would work for your situation. Also I made the background red to demonstration.

Here is the forked plunker.

Burak Tokak
  • 1,810
  • 1
  • 20
  • 27