web-dev-qa-db-fra.com

AngularUI modal pour pouvoir être déplacé et redimensionné

J'ai une fenêtre modale angularUi encapsulée dans une directive:

html:

<!doctype html>
<html ng-app="plunker">
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.8/angular.js"></script>
    <script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.10.0.js"></script>
    <script src="main.js"></script>
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
  </head>
  <body>
    <div my-modal="{ data: 'test2'}">test2</div>

  </body>
</html>

javascript:

angular.module('plunker', ['ui.bootstrap', 'myModal']);

angular.module("myModal", []).directive("myModal", function ($modal) {
    "use strict";
    return {
      template: '<div ng-click="clickMe(rowData)" ng-transclude></div>',
      replace: true,
      transclude: true,
      scope: {
        rowData: '&myModal' 
      },
      link: function (scope, element, attrs) {
        scope.clickMe = function () {
            $modal.open({
            template: "<div>Created By:" + scope.rowData().data + "</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>",
            controller: function ($scope, $modalInstance) {
                $scope.ok = function () {
                    $modalInstance.close({ test: "test"});
                };

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

plunker: http://plnkr.co/edit/yzxtWwZQdq94Tagdiswa?p=preview

Je veux rendre le modal glissable et redimensionnable. J'ai cherché sur Internet et j'ai pu trouver la solution suivante pour implémenter draggable: 

http://plnkr.co/edit/jHS4SJ?p=preview

C'est la partie importante:

app.directive('dragable', function(){   
  return {
    restrict: 'A',
    link : function(scope,elem,attr){
      $(elem).draggable();
    }
  }  
});

mais n'a pas pu le faire fonctionner avec mon exemple. Quelqu'un peut il m'aider avec ça? Je me demande s'il est possible d'utiliser jqueryui modal dans une directive (au lieu de bootstrap)? Je ne suis pas très bon en javascript et je serai très reconnaissant pour tout exemple de travail avec les deux options. Merci

MODIFIER:

J'ai ajouté jqueryui reference et j'ai réussi à rendre le modal glissable en ajoutant cette ligne:

 $(".modal-dialog").draggable();

Le problème est que je ne sais pas quand ajouter cette ligne. Au moment où j'ai ajouté ceci dans la méthode cancel (juste pour le faire fonctionner):

$ scope.cancel = function () { $ (". modal-dialog"). draggable (); };

Ainsi, lorsque le modal est ouvert, j'ai besoin d'appeler annuler et ce n'est qu'alors que le modal est déplaçable. Si je l’appelle plus tôt, le dialogue .modal n’existe pas. Suggestions? 

mise à jour: http://plnkr.co/edit/yzxtWwZQdq94Tagdiswa?p=preview

Il me manque quelque chose, puis-je donner un exemple de travail?

19
Mdb

J'ai créé une directive native pour rendre le modal draggable. Vous n’avez besoin que d’AngularJs et de jQuery. La directive utilise la classe "modal-dialog" de Ui-Bootstrap modal et vous ne pouvez déplacer le modal que dans l'en-tête.

.directive('modalDialog', function(){
  return {
    restrict: 'AC',
    link: function($scope, element) {
        var draggableStr = "draggableModal";
        var header = $(".modal-header", element);

        header.on('mousedown', (mouseDownEvent) => {
          var modalDialog = element;
          var offset = header.offset();

          modalDialog.addClass(draggableStr).parents().on('mousemove', (mouseMoveEvent) => {
                $("." + draggableStr, modalDialog.parents()).offset({
                    top: mouseMoveEvent.pageY - (mouseDownEvent.pageY - offset.top),
                    left: mouseMoveEvent.pageX - (mouseDownEvent.pageX - offset.left)
                });
            }).on('mouseup', () => {
                 modalDialog.removeClass(draggableStr);
            });
        });    
     }
  }  
});
13
squadwuschel

Si vous ne souhaitez pas modifier les modèles intégrés, vous pouvez écrire une directive qui cible modalWindow:

.directive('modalWindow', function(){
    return {
      restrict: 'EA',
      link: function(scope, element) {
        element.draggable();
      }
    }  
  });

Veuillez noter que vous devrez charger les scripts jQuery et jQuery UI before AngularJS.

NOTE: Gardez également à l'esprit que les versions les plus récentes du bootstrap de l'interface utilisateur angulaire ont été précédées du préfixe "uib", de sorte que "modalWindow" devient "uibModalWindow" avec @valepu.

9

J'ai combiné les deux réponses ci-dessus et rendu mon modal draggable.

.directive('modalWindow', function(){
  return {
    restrict: 'EA',
    link: function(scope, element) {
      $(".modal-dialog").draggable();
    }
  }  
});
5
Manas

un modal d'interface utilisateur angulaire avec une barre de titre déplaçable

REMARQUE: vous devez charger les interfaces utilisateur jQuery et jQuery avant les scripts AngularJS.

angular.module('xxApp')
    .directive('uibModalWindow', function () {
        return {
            restrict: 'EA',
            link: function (scope, element) {
                $('.modal-content').draggable({handle: ".modal-header"});
            }
        }
    });
1
dzcxzl

Essayez d'utiliser 

$(elem).closest('div.modal-dialog').draggable();

en fonction de lien

0
Ramu

Merci pour vos exemples. J'ai un peu peaufiné votre code et voici mon résultat final. à ma solution cela fonctionne parfaitement :-)

HTML:

<div class="draggableModal ui-widget-content">

   <div class="modal-header">
     ...    
   </div>
</div>

angular.module('posProductsManager').directive('modalDialog', function () {
    var definition = {
        restrict: 'AC',
        link: function ($scope, element) {
            var draggableStr = "draggableModal";
            var header = $(".modal-header", element);
            var modalDialog = element;

            var clickPosition = null;
            var clickOffset = null;

            header[0].addEventListener('mousedown', function (position) {

                clickPosition = position;
                clickOffset = position;

                window.addEventListener('mouseup', mouseUpEvent);
                window.addEventListener('mousemove', mouseMoveEvent);
            });

            function mouseUpEvent() {
                clickPosition = null;
                window.removeEventListener('mouseup', mouseUpEvent);
                window.removeEventListener('mousemove', mouseMoveEvent);
            }

            function mouseMoveEvent(position) {

                var offset = modalDialog.parents().offset();

                $("." + draggableStr, modalDialog.parents()).offset({
                    left: clickPosition.pageX + (position.pageX - clickPosition.pageX) - clickOffset.offsetX,
                    top: clickPosition.pageY + (position.pageY - clickPosition.pageY) - clickOffset.offsetY,
                });

                clickPosition = position;
            }


        }
    };

    return definition;
});
0
Ivanhoe