An older solution (before pdfChip 2.6)
This article is valid for all pdChip versions, but a better solution is available if you are using pdfChip 2.6 or higher. The full description of that is in the previous article here.
A way to resolve the problem of dynamic image loading is the cchip.onPrintReady() function that is built into pdfChip.
The cchip.onPrintReady() function
cchip.onPrintReady( f ) installs a callback function f() that is called when the DOM is ready for printing, e.g. all images are loaded. The normal way to use this function is to first manipulate the DOM, then call cchip.onPrintReady( f ) that calls f() when the DOM is ready and exit the cchipPrintLoop(). The function f() must call cchip.printPages() in order to actually create PDF pages from the DOM and initiate further DOM manipulations and printing if required.
The following example illustrates how this function can be used.
<html>
<head>
<script>
function cchipPrintLoop(){
var img = document.getElementById("myimg");
img.src = "files/image.jpg";
cchip.onPrintReady( cchip.printPages );
}
</script>
</head>
<body>
<img id="myimg" src="files/2.png">
</body>
</html>
The cchipPrintLoop() function is used to place an image (image.jpg) into the DOM. Instead of directly calling cchip.printPages it calls the cchip.onPrintReady function that installs cchip.printPages as a callback function which makes sure that it will only be used after all images have been loaded.
Dynamically load images
cchip.onPrintReady has, however, one severe problem: It cannot be used in a loop, so that iterating over a number of images would not work. Instead a more complex way has to be used.
<html>
<head>
<script type="text/javascript">
function setImage(i) {
if ( i != 1 ) {
cchip.printPages()
}
if (i<9) {
var img = document.getElementById("myimg");
img.src = "files/" + i + ".png";
cchip.onPrintReady(function () {setImage(i+1)} );
}
}
function cchipPrintLoop() {
setImage(1);
}
</script>
</head>
<body>
<img id="myimg" style="width:100mm" src="files/2.png">
</body>
</html>
In this example the cchip.PrintLoop calls a setImage function with a parameter 1. For this first time (i=1) cchip.printPages is not called but the image object on the page is replaced with 1.png and then cchip.onPrintReady calls this function again for the next page. Since cchip.onPrintReady waits until all images are loaded this will only take place after the image is in the DOM and then cchip.printPages will be executed as the first statement in the next setImage run.
Dynamically load images using an array
The previous example is not ideal because image names need to have numbers to address them. The example below uses an array instead that lists all image paths, so that images may have arbitrary names.
It is even possible to use this example and put arbitrary objects into the "data" array and they will be placed into the corresponding CSS ID. Only the type of object identified by the ID has to work with the entries of the data array; in this example it has to be an image.
Dynamically load images using cchipUtils.js
This example uses a utility JavaScript that you may use in your HTML instead. That allows you to get rid of the rather complex code inside of your own JavaScript but to only reference the utility script instead. The utility script provides a function "cchip.modifyAndPrintDom" that can be used inside of a cchipPrintLoop.
<html>
<head>
<script src="js/cchipUtils.js"></script>
<script type="text/javascript">
function setImageArg( urlString ) {
document.getElementById("myimg").src = urlString;
}
function cchipPrintLoop() {
cchip.modifyAndPrintDom( setImageArg,
["files/icon_pdfchip_l_white.png"
,"files/icon_pdfchip_s.png"
,"files/icon_pdfchip.png"
,"files/icon_pdfchip_m.png"
,"files/icon_pdfchip_s_white.png"
,"files/icon_pdfchip_l_white.png"
,"files/icon_pdfchip_m_white.png"
,"files/icon_pdfchip_l.png"] );
}
</script>
</head>
<body >
<img id="myimg" style="width:100mm" src="files/image.jpg">
</body>
</html>
cchip.modifyAndPrintDom takes the name of a function that modifies the DOM as it's first parameter and an array of objects as it's second parameter. The array of objects should contain all objects that are to be feeded into the modifying function for modifying the DOM. The modifying function, in this example "setImageArg", has to have a parameter as placeholder for the new content. The function will be called for each item in the array with the respective item as parameter.
The main purpose of cchip.modifyAndPrintDom is to make sure that the DOM is fully updated with any modifications before it creates a PDF output from the current state of the DOM.