Preventing modal from scrolling when clicking on the ace editor

I have a modal window that contains the ace editor . With the modal open, I scroll down and click inside ace editor

to add text. And suddenly the window automatically scrolls. Again I scroll down, click inside the editor and scroll again. Finally, for the third time, I can paste the text into the editor. This happens when the modal is high enough that the editor is not displayed unless you scroll down.

Why? How can I prevent this auto-scrolling behavior?

Here is the plunker: http://plnkr.co/edit/NHHkUtrw8SIDIzViNiqw?p=preview

Controller:

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

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

  $scope.open = function (size) {

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

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

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

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

  $scope.items = items;
  $scope.selected = {
    item: $scope.items[0]
  };

  $scope.editor = {
    text: 'Hello, how are you getting on?'
  };

  $scope.aceOptions = function (mode) {
    return {
      mode: mode,
      onLoad: function (_ace) {
        // HACK to have the ace instance in the scope...
        $scope.modeChanged = function () {
          _ace.getSession().setMode("ace/mode/" + mode);
        };
      }
    };
  };

  $scope.ok = function () {
    $modalInstance.close($scope.selected.item);
  };

  $scope.cancel = function () {
    $modalInstance.dismiss('cancel');
  };
});

      

HTML:

<!doctype html>
<html ng-app="ui.bootstrap.demo">
  <head>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.js"></script>
    <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.12.0.js"></script>
    <script src="//rawgit.com/ajaxorg/ace-builds/v1.2.6/src-min-noconflict/ace.js"></script>
    <script src="//rawgithub.com/ajaxorg/ace-builds/master/src-min-noconflict/mode-css.js"></script>
    <script src="//rawgithub.com/angular-ui/ui-ace/bower/ui-ace.min.js"></script>
    <script src="example.js"></script>
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/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">
            <ul>
                <li ng-repeat="item in items">
                    <a ng-click="selected.item = item">{{ item }}</a>
                </li>
            </ul>
            Selected: <b>{{ selected.item }}</b>
            <p>
            Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
            </p>
            <p>Editor:</p>
            <div ui-ace="{
              useWrapMode : true,
              showGutter: true,
              theme:'twilight',
              mode: 'markdown',
              rendererOptions: {
                maxLines: 5,
                minLines: 3
              }
            }" ng-model="editor.text"></div>

        </div>
        <div class="modal-footer">
            <button class="btn btn-primary" ng-click="ok()">OK</button>
            <button class="btn btn-warning" ng-click="cancel()">Cancel</button>
        </div>
    </script>

    <button class="btn btn-default" ng-click="open()">Open me!</button>
    <button class="btn btn-default" ng-click="open('lg')">Large modal</button>
    <button class="btn btn-default" ng-click="open('sm')">Small modal</button>
    <div ng-show="selected">Selection from a modal: {{ selected }}</div>
</div>
  </body>
</html>

      

+3


source to share


2 answers


Browsers scroll the text box when it is focused. This causes all of the overflow problems: hidden elements get scrolled and the editor jumps on click.

Ace tries to prevent this by setting a fixed position to make sure the textarea is on screen, but there is a bug in the position spec: fixed, https://bugs.chromium.org/p/chromium/issues/detail?id=20574 . which creates position: fixed work as position: absolute with respect to the transformed element.

If you don't have a way to remove the transform from the parent elements of the ace, the best solution is to add css to make the .ace_text-input always absolutely positioned.



TL; DR add following page to page

.ace_text-input {
    position: absolute!important;
}

      

+1


source


If you set focus manually, it doesn't seem to jump (testing on Chrome 58). You can set focus to an element manually after initializing it.

Add event onLoad

to ui-ace parameters and then add it to ModalInstanceCtrl

:



$scope.focusEditor = function(editor) {
  editor.focus();
}

      

0


source







All Articles