1

I am working on a pdf viewer in angular and I want to display a div on top of a dynamic object. The div displays above the object in every browser but IE. To see this in action here is a plunker : http://plnkr.co/edit/MVzMvS4IwYPC8rEx5M4J?p=preview .

You'll see that it works fine in Chrome, and FireFox but not in IE. Any help would be nice. or even a point in the right direction.

app.js

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope,$sce) {
  $scope.name = 'World';
  $scope.documentSrc = "http://partners.adobe.com/public/developer/en/acrobat/PDFOpenParameters.pdf";

  $scope.frameSrc = $sce.trustAsHtml($scope.documentSrc);
  $scope.frameCode = $sce.trustAsHtml('<object data="http://partners.adobe.com/public/developer/en/acrobat/PDFOpenParameters.pdf" type="application/pdf"></object>');
  $scope.display = false;

  $scope.changeDoc = function(){
    $scope.documentSrc = 'https://media.amazonwebservices.com/AWS_Web_Hosting_Best_Practices.pdf';
  };
  $scope.changeDocAgain = function (){
    $scope.documentSrc = 'http://partners.adobe.com/public/developer/en/acrobat/PDFOpenParameters.pdf';
  };
  $scope.displayDiv = function (){
  if ( $scope.display == false){
    $scope.display = true;
  } else{
    $scope.display = false;
  }
}})

.directive('embedSrc', function () {
   return {
      restrict: 'A',
      link: function(scope, element, attrs) {
        scope.$watch(
          function() {
            return attrs.embedSrc;
          },
          function() {
            element.attr('src', attrs.embedSrc);
          }
  );
}
 };
})
.directive('dynamicObject', function($parse) {
return {
  restrict: 'E',
  link: function(scope, element, attrs) {
    scope.$watch(function() {
      return $parse(attrs.data)(scope);
  }, function(newValue) {
     element.html('<object data="' + newValue + '" type="application/pdf"></object>');
      });
    }
  };
});

index.html

<!DOCTYPE html>
<html ng-app="plunker">

<head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.4.x" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.js" data-semver="1.4.7"></script>
    <script src="app.js"></script>
</head>

<body ng-controller="MainCtrl">
<button ng-click="changeDoc()">Change Doc</button>
<button ng-click="changeDocAgain()">Change Again Doc</button>
<br/><br/>
<button ng-click="displayDiv()" class="mp-float-left mp-more_options_button">
    Search Options
</button>  
<div ng-if="display" class="displayDiv">displayMe!</div>
<br/>  
<dynamic-object data="documentSrc"></dynamic-object>

style.css

.displayDiv{
    position: absolute;
    background: red;
    width: 280px !important;
    z-index: 1000;
    padding:10px 10px 0px !important;
    height: 50px;
}

.pdfView{
    height: 710px;
    width :100%;
    z-index : 50;
}

Above is the demo code used in plunker as an example. The below code is what i have in my project.

.directive('objectReloadable', function ($rootScope) {
    var link = function (scope, element, attrs) {
        var currentElement = element;
        var watchFunction = function () {
            return scope.searchCriteriaService.documentSrc;
        };
        var updateHTML = function (newValue) {
            scope.searchCriteriaService.documentSrc = newValue;
            var html = '';
            if (attrs.datatype == 'pdf') {
                html = '<iframe type="application/pdf" src="' + newValue + '" class="mp-document-size" ></iframe>';
            } else if (attrs.datatype == 'html') {
                html = '<object data="' + newValue + '" type="text/html" class="mp-document-size"></object>';
            } else {
                html = '<img src="' + newValue + '" width="100%" style="overflow:scroll"/>'
            }
            var replacementElement = angular.element(html);
            currentElement.replaceWith(replacementElement);
            currentElement = replacementElement;
        };

        scope.$watch(watchFunction, function (newValue, oldValue) {
            if (newValue !== oldValue) {
                updateHTML(newValue);
            }
        });
        if (scope.searchCriteriaService.documentSrc) {
            updateHTML(scope.searchCriteriaService.documentSrc);
        }
    };
    return {
        restrict: 'E',
        scope: false,
        link: link
    };
})
Sari Rahal
  • 1,897
  • 2
  • 32
  • 53

1 Answers1

1

The following is the smallest working app.js I could make. It uses an iframe and Google Docs viewer to work, found here and here.

var app = angular.module('plunker', []);
    
    app.controller('MainCtrl', function($scope,$sce) {
      $scope.name = 'World';
      $scope.iframeSrc = "http://docs.google.com/gview?url=http://partners.adobe.com/public/developer/en/acrobat/PDFOpenParameters.pdf&embedded=true";
      $scope.display = false;
      $scope.changeDoc = function(){
        $scope.iframeSrc = 'http://docs.google.com/gview?url=https://media.amazonwebservices.com/AWS_Web_Hosting_Best_Practices.pdf&embedded=true';
      };
      $scope.changeDocAgain = function (){
        $scope.iframeSrc = 'http://docs.google.com/gview?url=http://partners.adobe.com/public/developer/en/acrobat/PDFOpenParameters.pdf&embedded=true';
      };
      $scope.displayDiv = function (){
        if ( $scope.display == false){
          $scope.display = true;
        } else{
          $scope.display = false;
        }
          
      }
    })
    
    .directive('iframeSrc', function () {
      return {
        restrict: 'A',
        link: function(scope, element, attrs) {
          scope.$watch(
            function() {
              return attrs.iframeSrc;
            },
            function() {
              element.attr('src', attrs.iframeSrc);
            }
          );
        }
      };
    })
    .directive('dynamicObject', function($parse) {
      return {
        restrict: 'E',
        link: function(scope, element, attrs) {
    
          scope.$watch(function() {
    
            return $parse(attrs.data)(scope);
    
          }, function(newValue) {
    
            element.html('<iframe src="' + newValue + '" type="application/pdf"></iframe>');
          });
        }
      };
    });
.displayDiv{
    position: absolute;
    background: red;
    width: 280px !important;
    z-index: 1000;
    padding:10px 10px 0px !important;
    height: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
    <html ng-app="plunker">
    
      <head>
        <meta charset="utf-8" />
     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
        <title>AngularJS Plunker</title>
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
      <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
        <link rel="stylesheet" href="style.css" />
        <script data-require="angular.js@1.4.x" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.js" data-semver="1.4.7"></script>
        <script src="app.js"></script>
      </head>
    
      <body ng-controller="MainCtrl">
        <button ng-click="changeDoc()">Change Doc</button>
        <button ng-click="changeDocAgain()">Change Again Doc</button>
        <br/><br/>
        <button ng-click="displayDiv()" class="mp-float-left mp-more_options_button">
                    Search Options
        </button>
        <div ng-if="display" class="displayDiv">displayMe!</div>
        <br/>
        <dynamic-object data="iframeSrc"></dynamic-object>
      </body>
    
    </html>
Community
  • 1
  • 1
StardustGogeta
  • 3,331
  • 2
  • 18
  • 32
  • This answer works if the conditions are right. The problem with this answer is it uses an iframe. Iframes aren't the best for IE and isn't always supported without a plugin installed. If it's not installed it tries to download the source. Here is a link to better describe it : http://stackoverflow.com/questions/19654577/html-embedded-pdf-iframe . Is there another way by just changing the way the display box operates? – Sari Rahal Mar 21 '16 at 15:00
  • I encountered that very issue while solving the problem. However, the Google View link is supposed to solve the problem by removing the need for such a plugin. Does it not work? I tested both the raw files and Stack Overflow snippet with IE11 and they worked flawlessly. – StardustGogeta Mar 21 '16 at 15:04
  • I have added the production code in my question to help understand what I am doing with everything. I have tried added the... html = ''; but since I am within https it causes a lot of issues. Also I don't feel that going to google to display a secure pdf is the safest thing. – Sari Rahal Mar 21 '16 at 16:56
  • I am not sure this is an issue with your code as much as it is an issue between the compatibility of this Adobe feature and IE itself. There are many who have documented compatibility issues: http://answers.microsoft.com/en-us/ie/forum/ie11-windows_7/internet-explorer-11-wont-display-embedded-pdfs/9c695a80-264b-4253-a08d-08ffc1a17500?auth=1 – A.Sharma Mar 21 '16 at 17:55
  • @Sari I think I would be able to help you more if I knew which version of IE you are using, why you need IE (and not something like Edge or Chrome), why this iframe does not work, and why you do not trust Google to display it. Which kinds of PDFs do you plan to be showing? – StardustGogeta Mar 21 '16 at 19:00
  • I am currently using IE11, Our customers could be using as low as IE10. When useing an iframe in IE(anyone) it tries to download the PDF instead of display it. I am dealing with secure documents behind an SSL request and when going out to googles non secure pdf viewer it creates a lot of errors. I would like to find a way of doing this with the embed that I am currently using and stay away from an iframe. – Sari Rahal Mar 21 '16 at 20:00
  • @Sari I am sorry, but I simply cannot find a non-iframe solution that works in IE. Have you tried simply changing my google link to "https://"? What errors are you encountering related to the security? – StardustGogeta Mar 21 '16 at 20:30
  • @StardustGogeta, you have given me the only answer that was viable. So congratulations. – Sari Rahal Mar 25 '16 at 19:54
  • Thanks! Sorry that I could not find a perfect solution to your issue. – StardustGogeta Mar 25 '16 at 20:17