0

My goal is to show an ArcGIS Server JavaScript v4 map in a Bootstrap modal popup (displayed over a page containing other content), and to print only the contents of the Bootstrap modal popup.

enter image description here I'm using the approach at https://stackoverflow.com/a/12181825/906814 to successfully display the Bootstrap modal and print only its contents.

The issue is that while the ArcGIS map frame, attribution text and buttons print, the map's contents do not. Instead there is a blank section where the map contents should be:

enter image description here

What do I need to change in either the CSS or JavaScript to ensure that the map's contents print?

@media print {
  body * {
    visibility:hidden;
  }
  #printSection, #printSection * {
    visibility:visible;
  }
  #printSection {
    position:absolute;
    left:0;
    top:0;
  }
}

function printElement(elem, append, delimiter) {
   // from https://stackoverflow.com/a/12181825/906814
    var domClone = elem.cloneNode(true);

    var $printSection = document.getElementById("printSection");

    if (!$printSection) {
        $printSection = document.createElement("div");
        $printSection.id = "printSection";
        document.body.appendChild($printSection);
    }

    if (append !== true) {
        $printSection.innerHTML = "";
    }

    else if (append === true) {
        if (typeof (delimiter) === "string") {
            $printSection.innerHTML += delimiter;
        }
        else if (typeof (delimiter) === "object") {
            $printSection.appendChild(delimiter);
        }
    }

    $printSection.appendChild(domClone);
    }

Working demo at https://jsfiddle.net/slead/39Lrpbu8/3/ - press the Open The Modal button to display the map, then press the Print button in the modal's footer to display the print dialog.

3

Unfortunately, cloneNode will not copy image data from a canvas.

A possible solution is to use the Views takeScreenshot method to copy the imageData from the map and then add it to the copied canvas.

    var canvas = domClone.querySelector("canvas");
    $printSection.appendChild(domClone);
    return view
    .takeScreenshot({ area: { ignorePadding: false } })
    .then(function(screenshot) {
      var imageData = screenshot.data;
      var context = canvas.getContext("2d");
      context.putImageData(imageData, 0, 0);
      return;
    });

Here is a fiddle that does this.

You will need to play with the options for takeScreenshot the area width and height for the screenshot to fill in the printable area, but this should be a good start!

1

It seems like it has to do with your css rule:

body * {
  visibility:hidden;
}

When you remove that, the map shows up. So does the non-modal content though, so I think the solution is to find a more fine-grained CSS rule to hide the background but not the map.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.