0

I have a lightbox directive that when it transcludes, it injects in the content. Technically, wherever I put the actual call to the directive. But essentially, I need it to transclude to the body so that the backdrop can cover the entire page viewport, and so that it centers to the viewport and not the container is transcluding to right now.

The directive is written this way:

(function() {
    'use strict';

    angular
        .module('app.core')
        .directive('lightboxDirective', lightboxDirective);

        function lightboxDirective() {
            return {
              restrict: 'E',
              transclude: true,
              scope: {},
              template: '<section class="md-lightbox" ng-transclude></section>',
            };
        }

})();

The lightbox is located in the page this way:

<div id="scala-media-media" class="page-layout">
     <div class="center" flex>
          <div class="header">
               <img ng-src="{{vm.media.images[0].url}}" ng-click="showLightBox = true">
          </div>
          <div class="content">
               ... the page content here ...
          </div>
     </div>
</div>

<lightbox-directive class="angular-lightbox" ng-class="{ removed : !showLightBox }">
      ... the code for my lightbox content (which works fine by the way) ...
</lightbox-directive>

At first I thought I'd specify the parent as I would normally do in a $mdDialog (Angular Material) with parent: angular.element($document.body), but that didn't work out. parent is not a recognized callback I assume.

Notice in the image where it is injected. Right where I place it! What's the point of using a directive if I can just place the code there and will do the same thing without the directive? right? dev tool screenshot

Here is a screenshot of what is happening. Notice the backdrop and centering issue I am having on the left side, as opposed to what I desire in the right side with a dialog. enter image description here

I am using this angular lightbox found in this CODEPEN

UPDATE

I moved the lightbox to its own template file, so as to not feel guilty for using the code directly on the page which makes the use of a directive redundant. And restructured my directive as it shows below. But the rendering on runtime is still a problem. The template injects where it is called. Now if only I could declare the body as the parent for it to append to! lol

New directive:

function lightboxDirective() {
    return {
        restrict: 'E',
        templateUrl: function(elem,attrs) {
            return attrs.templateUrl || 'app/main/pages/scala-media/views/lightbox-template.html'
        }
    };
}

Thanks in advance!

LOTUSMS
  • 10,317
  • 15
  • 71
  • 140

1 Answers1

1

You can make the element reposition itself just before the closing body tag with

.directive("lightboxDirective", function() {
  return {
    restrict: 'E',
    transclude: true,
    scope: {},
    template: '<section class="md-lightbox" ng-transclude></section>',
    link: function(scope, elem) {
      angular.element(document).find("body").append(elem);
    }
  };
});
K Scandrett
  • 16,390
  • 4
  • 40
  • 65
  • That said, I don't think node positioning is your problem because the CodePen demo you linked to has a style called `section` which should cover the page no matter where the directive sits. Maybe you're missing that? Otherwise, I suspect the website is using an `Iframe` and you will need to access the Iframe's parent and append to that (assuming there are no iframe restrictions - see http://stackoverflow.com/a/5604884/1544886) – K Scandrett Apr 11 '17 at 07:11
  • That worked beautifully! I am using it sllightly different than the codepen demo. All I had to modify from your answer was the scope{}, and it worked perfect after that! Million thanks mate! – LOTUSMS Apr 11 '17 at 12:52