Chapter 11: Form Creation
Contents
11.1 Form Overview
Like an HTML page, a PDF document may contain an interactive form (sometimes referred to as an AcroForm) made up of various form fields such as text boxes, checkboxes, radio buttons, drop-down lists, pushbuttons, etc., for gathering information from the user. Unlike an HTML page, there can only be one interactive form per document, possibly spanning multiple pages.
PDF form fields are similar to HTML form items but provide a much wider flexibility:
- The appearance of a PDF form field can be completely customized.
- PDF supports combo boxes. A combo box is a combination of a text box and drop-down list. HTML only allows drop-down lists with no text editing.
- Advanced PDF viewer applications such as Adobe Acrobat provide spell-checking for editable text fields.
In PDF, form fields are a special type of annotations called widgets. Consequently, they are represented by the PdfAnnot object. AspPDF supports five form field types: text boxes, checkboxes, radio buttons, choices, and pushbuttons creatable via CreateTextbox, CreateCheckbox, CreateRadiobutton, CreateChoice, and CreatePushbutton methods of the PdfPage object, respectively.
All five field creation methods share a common set of parameters: a field name, field dimensions, a read-only flag, a no-export flag, and a few others. These methods return an instance of the PdfAnnot object representing the newly created form field. For more information, see the PdfPage reference.
11.1.1 Text Boxes
A text box field is creatable via the PdfPage.CreateTextbox method which takes the following arguments:
- Name uniquely identifies this form field within the form.
- Caption specifies the text string to be displayed in the text box.
- Param is a PdfParam object or parameter string specifying various appearance parameters of the text field, including [X, Y, Width, Height] (required), Multiline, Password, Alignment, MaxLen, Border (all optional), and several others. For the complete list of valid parameters, see the CreateTextbox reference.
- Font specifies the font to be used to draw the text in the field. Can be set to Nothing, "Times-Roman" by default.
- Parent specifies the parent form field. Can be set to Nothing if this is a top-level form field.
The following code segment creates a simple single-line text field with a border:
11.1.2 Checkboxes
A checkbox is creatable via the PdfPage.CreateCheckbox method which takes the following arguments:
- Name uniquely identifies this form field within the form.
- Param is a PdfParam object or parameter string specifying various appearance parameters of the checkbox field, including [X, Y, Width, Height] (required), State (1 - checked, 0 - unchecked, optional, 0 by default), and several others. For the complete list of valid parameters, see the CreateCheckbox reference.
- Parent specifies the parent form field. Can be set to Nothing if this is a top-level form field.
The following code fragment creates a checkbox with the default state set to "checked":
11.1.3 Radio Buttons
A radio button is creatable via the PdfPage.CreateRadiobutton method which takes the following arguments:
- Name uniquely identifies this form field within the form.
- OptionName identifies an individual option within a group of radio buttons. For top-level radio buttons, this argument specifies the option name of a child radio button selected by default (when the form is reset).
- Param is a PdfParam object or parameter string specifying various appearance parameters of the radio button field, including [X, Y, Width, Height] (required), State (1 - checked, 0 - unchecked, optional, 0 by default), NoToggleToOff (optional, False by default), and several others. For the complete list of valid parameters, see the CreateRadiobutton reference.
- Parent specifies the parent form field. Can be set to Nothing if this is a top-level form field.
The Parent argument is very significant for radio buttons. It determines if the resultant PdfAnnot object represents a group of radio buttons, or an individual radio button in a group.
If the Parent argument is set to Nothing, the resultant radio button has no visual appearance of its own, but works as a "group manager" for its child radio buttons. When creating such top-level radio button objects, you may use the NoToggleToOff parameter which, if set to True, makes it so that exactly one radio button in a group is selected at any time. Clicking on the currently selected radio button does not deselect it.
Setting the Parent argument to a top-level radio button object adds a visible radio button to the group.
If the Parent argument is set to Nothing, the OptionName argument specifies the name of a radio button in the group to be selected when the form is reset.
The following code fragment creates a group of three radio buttons, Amex, Visa, and MC, and makes the Amex button selected by default (the 2nd argument to the top-level CreateRadiobutton call is set to "Amex"). Exactly one radio button can be selected at any time (the NoToggleToOff parameter for the top-level object is set to True).
Set Amex = Page.CreateRadiobutton("CCType", "Amex", "x=100;y=723;width=40; height=10; state=1", CCGroup )
Set Visa = Page.CreateRadiobutton("CCType", "Visa", "x=150;y=723;width=35; height=10", CCGroup )
Set MC = Page.CreateRadiobutton("CCType", "MC", "x=200;y=723;width=30; height=10;", CCGroup )
11.1.4 Choices
A choice field is creatable via the PdfPage.CreateChoice method which takes the following arguments:
- Name uniquely identifies this form field within the form.
- Options is list of options for this field where the options are separated from each other with ##, for example "Left##Right##Center". The list may also contain name/value pairs separated by %%. A name is what is displayed on the page, and the value is what gets submitted when this item is selected, for example "Left%%1##Right%%2##Center%%3".
- Selection is a string specifying the initial selection, if any, such as "Left". If this is a multi-select form field, the Selection argument may be a ##-separated list of values.
- Param is a PdfParam object or parameter string specifying various appearance parameters of the choice field, including [X, Y, Width, Height] (required), Combo, Multiselect, Edit, Border, and several others. For the complete list of valid parameters, see the CreateChoice reference.
- Font specifies the font object to be used to draw the field contents. Can be set to Nothing, Times-Roman by default.
- Parent specifies the parent form field. Can be set to Nothing if this is a top-level form field.
By default, a choice field appears as a list box without a border where all options are visible (provided the width and height are adequate). To make it into a drop-down list box, the Combo parameter must be set to True.
The following code fragment creates a drop-down list box, populates it with month names and sets the current selection to the current month. To obtain the current month name in an abbreviated form, we use the expression Pdf.FormatDate( Now, "%b").
Set CCMonth = Page.CreateChoice( "CCMonth", MonthOptions, Pdf.FormatDate(Now, "%b"), "x=100; y=680; width=50; height=17; Combo=true;Border=1", Font, Nothing )
IPdfAnnot objCCMonth = objPage.CreateChoice( "CCMonth", strMonthOptions, objPdf.FormatDate(DateTime.Now, "%b"), "x=100; y=680; width=50; height=17; Combo=true;Border=1", objFont, null );
11.1.5 Pushbuttons
A pushbutton is creatable via the PdfPage.CreatePushbutton method which takes the following arguments:
- Name uniquely identifies this form field within the form.
- Caption specifies the text string to be displayed on the button.
- Param is a PdfParam object or parameter string specifying various appearance parameters of the pushbutton field, including [X, Y, Width, Height] (required), FontSize (optional, 10 by default), and several others. For the complete list of valid parameters, see the CreatePushbutton reference.
- Font specifies the font object to be used to draw the field contents. Can be set to Nothing, Times-Roman by default.
- Parent specifies the parent form field. Can be set to Nothing if this is a top-level form field.
A pushbutton is usually associated with an action via the PdfAnnot.SetAction method. The two most common types of actions associated with pushbuttons are the Reset and Submit actions.
The following code fragment creates a pushbutton and associates it with a Submit action pointing to a URL.
SubmitButton.SetAction Doc.CreateAction("Type=Submit; Html=true", "http://localhost/asppdf/manual_11/11_submit.asp" )
objSubmitButton.SetAction( objDoc.CreateAction("Type=Submit; Html=true", "http://localhost/asppdf/manual_11/11_submit.asp" ) );
11.2 Code Sample
The following code sample uses the field creation methods described above to create an interactive form with one text box, three radio buttons, two drop-down list boxes, one checkbox, and two pushbuttons:
The form submits to an .asp script which displays the raw binary contents of the submission.
The entire code sample is not shown here for brevity, but its various fragments are shown in the previous section.
Click the links below to run this code sample:
11.3 Customizing Field Appearances
Form fields are represented by the PdfAnnot object which provides a way to change its default appearance via the Graphics property. This property was already mentioned in Section 10.3.4 - Changing Default Appearance of Annotations. Via the Graphics property, we can specify graphics objects for the annotation's "normal", "down", and "rollover" appearances.
Changing the default appearance of a form field is slightly more complicated because, unlike regular annotations, some form fields have states.
For example, a checkbox can be in two states: on (checked) and off. Therefore, a checkbox annotation can have up to six graphics objects associated with it: three appearances ("normal", "down", and "rollover") for the "on" state, and three for the "off" state. Note that the "down" and "rollover" appearances are optional and identical to the "normal" appearance by default.
The PdfAnnot.Graphics property accepts two arguments: the type (0 for "normal", 1 for "down" and 2 for "rollover"), and optional state. For a checkbox, the state names are "Yes" and "Off".
The following code sample changes the default appearance of a checkbox to look as follows:
"Yes" State | "Off" State | |
"Normal" Type (0) | ||
"Down" Type (1) | ||
"Rollover" Type (2) |
Set Doc = Pdf.CreateDocument
Set Page = Doc.Pages.Add
' Draw gray background
Page.Canvas.SetFillColor .64, .78, .66
Page.Canvas.FillRect 0, 0, Page.Width, Page.Height
Set Checkbox = Page.CreateCheckbox( "Receipt", "x=100; y=660; width=30; height=30", Nothing )
Set GrayBack = Doc.CreateGraphics("Left=0; Right=30; Bottom=0; Top=30")
GrayBack.Canvas.SetFillColor .5, .5, .5
GrayBack.Canvas.FillRect 0, 0, 30, 30
Set WhiteBack = Doc.CreateGraphics("Left=0; Right=30; Bottom=0; Top=30")
WhiteBack.Canvas.SetFillColor 1, 1, 1
WhiteBack.Canvas.FillRect 0, 0, 30, 30
Set LiteBack = Doc.CreateGraphics("Left=0; Right=30; Bottom=0; Top=30")
LiteBack.Canvas.SetFillColor .82, .82, .1
LiteBack.Canvas.FillRect 0, 0, 30, 30
Set Outline = Doc.CreateGraphics("Left=0; Right=30; Bottom=0; Top=30")
LineWidth = 3
With Outline.Canvas
.SetColor .35, .6, .39
.LineWidth = LineWidth
.MoveTo LineWidth /2, LineWidth /2
.LineTo LineWidth /2, 30 - LineWidth /2
.LineTo 30 - LineWidth /2, 30 - LineWidth /2
.Stroke
.SetColor .82, .89, .83
.MoveTo 0, LineWidth / 2
.LineTo 30 - LineWidth / 2, LineWidth / 2
.LineTo 30 - LineWidth / 2, 30
.Stroke
.SetColor .64, .78, .66
.MoveTo LineWidth, 3 * LineWidth / 2
.LineTo 30 - 3 * LineWidth / 2, 3 * LineWidth / 2
.LineTo 30 - 3 * LineWidth / 2, 30 - LineWidth
.Stroke
.SetColor 0, 0, 0
.MoveTo 3 * LineWidth /2, 4 * LineWidth /2
.LineTo 3 * LineWidth /2, 30 - 3 * LineWidth /2
.LineTo 30 - 4 * LineWidth /2, 30 - 3 * LineWidth /2
.Stroke
End With
GrayBack.Canvas.DrawGraphics Outline, "x=0, y=0"
WhiteBack.Canvas.DrawGraphics Outline, "x=0, y=0"
LiteBack.Canvas.DrawGraphics Outline, "x=0, y=0"
Checkbox.Graphics(0, "Off") = WhiteBack
Checkbox.Graphics(1, "Off") = LiteBack
Checkbox.Graphics(2, "Off") = GrayBack
Set GrayBackChecked = Doc.CreateGraphics("Left=0; Right=30; Bottom=0; Top=30")
GrayBackChecked.Canvas.DrawGraphics GrayBack, "x=0, y=0"
GrayBackChecked.Canvas.DrawText "8", "x=8,y=28,size=20", Doc.Fonts("ZapfDingbats")
Set WhiteBackChecked = Doc.CreateGraphics("Left=0; Right=30; Bottom=0; Top=30")
WhiteBackChecked.Canvas.DrawGraphics WhiteBack, "x=0, y=0"
WhiteBackChecked.Canvas.DrawText "8", "x=8,y=28,size=20", Doc.Fonts("ZapfDingbats")
Set LiteBackChecked = Doc.CreateGraphics("Left=0; Right=30; Bottom=0; Top=30")
LiteBackChecked.Canvas.DrawGraphics LiteBack, "x=0, y=0"
LiteBackChecked.Canvas.DrawText "8", "x=8,y=28,size=20", Doc.Fonts("ZapfDingbats")
Checkbox.Graphics(0, "Yes") = WhiteBackChecked
Checkbox.Graphics(1, "Yes") = LiteBackChecked
Checkbox.Graphics(2, "Yes") = GrayBackChecked
Filename = Doc.Save( Server.MapPath("checkbox.pdf"), False )
IPdfDocument objDoc = objPdf.CreateDocument(Missing.Value);
IPdfPage objPage = objDoc.Pages.Add( Missing.Value, Missing.Value, Missing.Value );
// Draw gray background
objPage.Canvas.SetFillColor( .64f, .78f, .66f );
objPage.Canvas.FillRect( 0, 0, objPage.Width, objPage.Height );
IPdfAnnot objCheckbox = objPage.CreateCheckbox( "Receipt", "x=100; y=660; width=30; height=30", null );
IPdfGraphics objGrayBack = objDoc.CreateGraphics("Left=0; Right=30; Bottom=0; Top=30");
objGrayBack.Canvas.SetFillColor( .5f, .5f, .5f );
objGrayBack.Canvas.FillRect( 0, 0, 30, 30 );
IPdfGraphics objWhiteBack = objDoc.CreateGraphics("Left=0; Right=30; Bottom=0; Top=30");
objWhiteBack.Canvas.SetFillColor( 1, 1, 1 );
objWhiteBack.Canvas.FillRect( 0, 0, 30, 30 );
IPdfGraphics objLiteBack = objDoc.CreateGraphics("Left=0; Right=30; Bottom=0; Top=30");
objLiteBack.Canvas.SetFillColor( .82f, .82f, .1f );
objLiteBack.Canvas.FillRect( 0, 0, 30, 30 );
IPdfGraphics objOutline = objDoc.CreateGraphics("Left=0; Right=30; Bottom=0; Top=30");
float LineWidth = 3;
objOutline.Canvas.SetColor( .35f, .6f, .39f );
objOutline.Canvas.LineWidth = LineWidth;
objOutline.Canvas.MoveTo( LineWidth /2, LineWidth /2 );
objOutline.Canvas.LineTo( LineWidth /2, 30 - LineWidth /2 );
objOutline.Canvas.LineTo( 30 - LineWidth /2, 30 - LineWidth /2 );
objOutline.Canvas.Stroke();
objOutline.Canvas.SetColor( .82f, .89f, .83f );
objOutline.Canvas.MoveTo( 0, LineWidth / 2 );
objOutline.Canvas.LineTo( 30 - LineWidth / 2, LineWidth / 2 );
objOutline.Canvas.LineTo( 30 - LineWidth / 2, 30 );
objOutline.Canvas.Stroke();
objOutline.Canvas.SetColor( .64f, .78f, .66f );
objOutline.Canvas.MoveTo( LineWidth, 3 * LineWidth / 2 );
objOutline.Canvas.LineTo( 30 - 3 * LineWidth / 2, 3 * LineWidth / 2 );
objOutline.Canvas.LineTo( 30 - 3 * LineWidth / 2, 30 - LineWidth );
objOutline.Canvas.Stroke();
objOutline.Canvas.SetColor( 0, 0, 0 );
objOutline.Canvas.MoveTo( 3 * LineWidth /2, 4 * LineWidth /2 );
objOutline.Canvas.LineTo( 3 * LineWidth /2, 30 - 3 * LineWidth /2 );
objOutline.Canvas.LineTo( 30 - 4 * LineWidth /2, 30 - 3 * LineWidth /2 );
objOutline.Canvas.Stroke();
objGrayBack.Canvas.DrawGraphics( objOutline, "x=0, y=0" );
objWhiteBack.Canvas.DrawGraphics( objOutline, "x=0, y=0" );
objLiteBack.Canvas.DrawGraphics( objOutline, "x=0, y=0" );
objCheckbox.set_Graphics(0, "Off", objWhiteBack );
objCheckbox.set_Graphics(1, "Off", objLiteBack );
objCheckbox.set_Graphics(2, "Off", objGrayBack );
IPdfFont objFont = objDoc.Fonts["ZapfDingbats", Missing.Value];
IPdfGraphics objGrayBackChecked = objDoc.CreateGraphics("Left=0; Right=30; Bottom=0; Top=30");
objGrayBackChecked.Canvas.DrawGraphics( objGrayBack, "x=0, y=0" );
objGrayBackChecked.Canvas.DrawText( "8", "x=8,y=28,size=20", objFont );
IPdfGraphics objWhiteBackChecked = objDoc.CreateGraphics("Left=0; Right=30; Bottom=0; Top=30");
objWhiteBackChecked.Canvas.DrawGraphics( objWhiteBack, "x=0, y=0" );
objWhiteBackChecked.Canvas.DrawText( "8", "x=8,y=28,size=20", objFont );
IPdfGraphics objLiteBackChecked = objDoc.CreateGraphics("Left=0; Right=30; Bottom=0; Top=30");
objLiteBackChecked.Canvas.DrawGraphics( objLiteBack, "x=0, y=0" );
objLiteBackChecked.Canvas.DrawText( "8", "x=8,y=28,size=20", objFont );
objCheckbox.set_Graphics(0, "Yes", objWhiteBackChecked );
objCheckbox.set_Graphics(1, "Yes", objLiteBackChecked );
objCheckbox.set_Graphics(2, "Yes", objGrayBackChecked );
// Save document, the Save method returns generated file name
String strFilename = objDoc.Save( Server.MapPath("form.pdf"), false );
Click the links below to run this code sample:
Existing form fill-in is described in the next chapter.