## Print Template Samples

This sample demonstrates the print and print preview customization features of Microsoft Internet Explorer. You can use these features in C1Editor using methods Print and PrintPreview with the printTemplateFileName paramenter. It includes sample print templates that you can select using the drop-down list box above the browser window. Click the Preview, Print with Prompt, or Print w/o Prompt buttons to open the preview window or print using the currently selected print template. Click the Template Source button to view the template's source code.

The sample templates are presented in a series, beginning with a very minimal template and increasing in complexity until the final template, which includes some user interface elements. The templates provide you with the basic knowledge you need to use print templates, and offer you a taste of the possibilities for customizing print and print preview functionality in Internet Explorer 5.5.

#### Template1.htm: Minimal Template (Print Preview Only)

This example demonstrates a very minimal print template. It supports print preview, but not printing. The template includes only two DEVICERECT elements containing one LAYOUTRECT element each. It doesn't completely render the source document for previewing. The style .rect for the LAYOUTRECT element includes two required properties, width and height; the other properties are not required. Colors and borders on the LAYOUTRECT and DEVICERECT elements (white and yellow respectively) are included to make it easy to see the elements' boundaries. The style .page for the DEVICERECT element includes a width and height set to the standard 8.5 x 11-inch paper size, though these may not be the correct dimensions. See Template6.htm for information about how you can read the true paper size values from the Page Setup options and set the DEVICERECT styles correctly.

#### Template2.htm: Minimal Template Supporting Printing

This template demonstrates a minimal print template with enough support to enable printing as well as previewing. It is the same as Template1.htm with the addition of the TEMPLATEPRINTER element and scripts to provide printing support.

The scripts begin with the function CheckPrint. This function is the onlayoutcomplete event handler for the second LAYOUTRECT element, wrapped in a 100 millisecond timeout. CheckPrint checks the dialogArguments.__IE_PrintType property to determine whether to preview the document, print the document after prompting the user with the Print dialog box, or print without prompting the user at all. The timeout is important because the device context (DC) cannot render to the printer or screen until the onlayoutcomplete event has finished. The timeout delays printing until after the onlayoutcomplete event has been handled. A timeout of as little as one millisecond can be enough to allow the onlayoutcomplete event to finish; to be on the safe side, the timer is set for 100 milliseconds in this example.

PrintPrep is an important function because it sets an onreadystatechange handler to make sure the template's source document has been completely loaded into the template before printing.

#### Template3.htm: Dynamic Creation of LAYOUTRECT Elements (Preview Only)

This template demonstrates how to create LAYOUTRECT elements dynamically as the source document is loaded into the template. The first LAYOUTRECT element is created in the BODY element's onload event handler, AddFirstPage. Additional LAYOUTRECT elements are created by the OnRectComplete function, which is the onlayoutcomplete event handler for each LAYOUTRECT. OnRectComplete checks the event.contentOverflow property. If contentOverflow is true, the function creates HTML for a new DEVICERECT and LAYOUTRECT element. Once the HTML is created, OnRectComplete inserts the new HTML into the page container DIV element using the insertAdjacentHTML method. After the new LAYOUTRECT is inserted, the template can continue to load the template's source document. Notice that OnRectComplete also sets the onlayoutcomplete handler to null for the current LAYOUTRECT element. Setting it to null prevents further calls to OnRectComplete if the print template component reflows the source document into the LAYOUTRECT elements, which happens when the preview window is resized, for instance.

This template only supports print preview.

#### Template4.htm: Adding Headers and Footers (Preview Only)

This template demonstrates how to use the HEADERFOOTER element and add headers and footers to the pages of a print template. This template is similar to Template3.htm. It adds a TEMPLATEPRINTER and a HEADERFOOTER element to the BODY, three functions for adding headers and footers to each page, and two styles to specify the placement of the headers and footers on the pages. The work of adding headers and footers occurs in two functions in this template, OnRectComplete and AddHeaderAndFooterToPage.

The first function is the OnRectComplete function. Once OnRectComplete has generated all the LAYOUTRECT elements (that is, when event.contentOverflow = false), it initializes the HeaderFooter behavior with the header formatting strings, the document title, and the URL, and calls another function to calculate the total number of pages. The OnRectComplete function then loops through all the DEVICERECT elements of the document, calling the function AddHeaderAndFooterToPage, which does the actual work of inserting new HTML into each DEVICERECT element for the header and footer. Notice the Boolean variable bHeadersFootersAdded. Even though the headers and footers are absolutely positioned and shouldn't change the other elements in a DEVICERECT element, the current implementation of the LayoutRect behavior will re-flow the content in the LAYOUTRECT elements when the DEVICERECT elements in a print template change. During re-flow, the onlayoutcomplete event fires again for the LAYOUTRECT elements, leading to an infinite loop of OnRectComplete calls. The variable bHeadersFootersAdded is switched to true after the first pass through the pages to prevent the re-flow from adding headers and footers a second time. Another strategy to deal with this problem is to add headers and footers during the initial creation of LAYOUTRECT elements. The page total is then added after the layout is complete. See Template5.htm for an example.

#### Template5.htm: Adding Headers and Footers 2 (Preview Only)

This template demonstrates another strategy for adding headers and footers to the DEVICERECT elements in a print template. In this example, the headers and footers are added at the same time as the DEVICERECT and LAYOUTRECT elements during the initial loading of the template source document. After all the DEVICERECT and LAYOUTRECT elements have been created, the template calls the AddPageTotalToPages function. AddPageTotalToPages searches for SPAN elements to which the class hfPageTotal is attached. It sets the innerText of those SPAN elements to the page total. Notice that the HeaderFooter behavior is initialized with the document title, URL, and so forth in the AddFirstPage function just before the header and footer are added to the first DEVICERECT element.

While this strategy is a little more complicated, it offers better performance than Template4.htm because the LAYOUTRECT elements do not re-flow twice.

#### Template6.htm: Reading from Page Setup and Synchronizing Threads

This template combines all the elements in the previous templates and adds more robust printing support. The previous templates, for simplicity, have made assumptions about the paper size, margins, unprintable margins, pages to be printed, and so on. Template6.htm actually reads the values set in the Page Setup and Print dialog box settings (well, many of them anyway) to format the pages for printing and previewing and to print only the pages the user wants to print. Be sure to look at the Init function where the styles are set. The measurement values from the printer are expressed in hundredths of an inch. For this reason, divide any calculation made from the measurement values by 100 and append the string "in" before using the calculation to set a style property.

If you compare this template with Template2.htm, you'll see that the CheckPrint function, which has the code to check the print type, is now called from the onlayoutcomplete event handler, OnRectComplete, once the contentOverflow property is false. As in Template2.htm, CheckPrint's execution is delayed by 100 milliseconds by wrapping it in a setTimeout method call.

Be sure to examine the PrintNow function to see how the template determines which pages to print.

#### Template7.htm: Building a User Interface

This sample template demonstrates how to create a print preview user interface of your own. The user interface in this example gives the user access to the Page Setup and Print dialog boxes and enables the user to scale the view of the document. To build the user interface, the BODY element has a SCROLL="no" attribute that prevents it from displaying a scroll bar. The DIV element named "ui" is a fixed, static area of the screen holding the buttons and text box of the user interface. The "overflowcontainer" DIV element defines the area where pages are displayed. Its style class sets the overflow property to "auto" so that the scrollbar will appear on it, when necessary, instead of on the BODY element. That way, users can scroll to any page they want to see without moving the user interface buttons from the top of the screen.

A print template with a user interface must respond to changes in the Page Setup and Print settings. The most important consideration is what to do with unneeded LAYOUTRECT and DEVICERECT elements if the user reduces the number of pages in the document by switching to a bigger paper size (from letter- to legal-size paper, for instance). With the current print template implementation, a template should not destroy LAYOUTRECT elements once they have been created. It is better to hide unneeded LAYOUTRECT elements. While there are a number of ways to do this, one solution that provides good performance is to use absolute positioning to move hidden elements off the screen. Don't use the display property. The current implementation of print templates does not call the onlayoutcomplete event on undisplayed LAYOUTRECT elements.

In this template, the .pagestyle class for the DEVICERECT elements has a left property set to -100 inches. This property is ignored when the position property is unset or set to "static." When it is set to "absolute" on a DEVICERECT element, the page for that DEVICERECT element will disappear from the screen. A function has been added to this template, called ShowFilledPagesAndHideExcessPages, that sets the positioning property on all the DEVICERECT elements to either "static" or "absolute," depending on the value of the headfoot.pageTotal property. The headfoot.pageTotal property is set and ShowFilledPagesAndHideExcessPages is called whenever the contentOverflow property is false in the two onlayoutcomplete event handlers. One of them, OnRectComplete, is the same as the OnRectComplete functions in previous sample templates. It is the onlayoutcomplete handler when a LAYOUTRECT element is first created and is the last LAYOUTRECT in the series. Once another LAYOUTRECT element has been created, the onlayoutcomplete handler is switched to OnRectCompleteSimple in the AddNewPage function. OnRectCompleteSimple doesn't add new pages when the contentOverflow property is true.

The DoPageSetup function is the onmouseup handler for the Page Setup button. When the button is clicked, the Page Setup dialog box is displayed and the .pagestyle, .lorstyle, .headerstyle, and .footerstyle classes are re-initialized to catch any changes. Note that the page layout re-flows (leading to onlayoutrectcomplete events) only when the values in the classes actually change.

To enable the user to scale the page size in print preview, this template adds a function called Zoomer. Zoomer is the onmouseup handler for the Zoom In and Zoom Out buttons and the onkeyup handler for the text box. The function changes the zoom property (which is initially 50%) on the pagecontainer DIV element by 1% when the user clicks either button, or changes the property to the value in the Zoom text box when the box has focus and the user presses ENTER.

The DoPrintFromPreview function is the onmouseup handler for the Print button. The function displays the Print dialog box and calls the same PrintPrep function as in previous templates.

#### Template8.htm: Adjustable Margin UI

This last sample template demonstrates a user interface control that gives the user visual control over the margin settings. It adds four marker images and a fifth invisible marker for calibrating the pixel-to-inch ratio. It also adds three mouse event handlers, and adds a button to the toolbar to hide and display the margin markers.