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:

PdfAnnot objCCNumber = objPage.CreateTextbox( "CCNumber", "", "x=100; y=700; width=200; height=17; Border=1", objFont, null );
Dim objCCNumber As PdfAnnot = objPage.CreateTextbox( "CCNumber", "", "x=100; y=700; width=200; height=17; Border=1", objFont, Nothing )

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":

PdfAnnot objReceipt = objPage.CreateCheckbox( "Receipt", "State=1; x=100; y=660; width=15; height=15", null );
Dim objReceipt As PdfAnnot = objPage.CreateCheckbox( "Receipt", "State=1; x=100; y=660; width=15; height=15", Nothing )

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).

PdfAnnot objCCGroup = objPage.CreateRadiobutton("CCType", "Amex", "x=0, y=0, width=0; height=0; NoToggleToOff=true;", null );

PdfAnnot objAmex = objPage.CreateRadiobutton("CCType", "Amex", "x=100;y=723;width=40; height=10; state=1", objCCGroup );

PdfAnnot objVisa = objPage.CreateRadiobutton("CCType", "Visa", "x=150;y=723;width=35; height=10", objCCGroup );

PdfAnnot objMC = objPage.CreateRadiobutton("CCType", "MC", "x=200;y=723;width=30; height=10;", objCCGroup );
Dim objCCGroup As PdfAnnot = objPage.CreateRadiobutton("CCType", "Amex", "x=0, y=0, width=0; height=0; NoToggleToOff=true;", Nothing )

Dim objAmex As PdfAnnot = objPage.CreateRadiobutton("CCType", "Amex", "x=100;y=723;width=40; height=10; state=1", objCCGroup )

Dim objVisa As PdfAnnot = objPage.CreateRadiobutton("CCType", "Visa", "x=150;y=723;width=35; height=10", objCCGroup )

Dim objMC As PdfAnnot = objPage.CreateRadiobutton("CCType", "MC", "x=200;y=723;width=30; height=10;", objCCGroup )

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").

string strMonthOptions = "Jan##Feb##Mar##Apr##May##Jun##Jul##Aug##Sep##Oct##Nov##Dec";

PdfAnnot objCCMonth = objPage.CreateChoice( "CCMonth", strMonthOptions, DateTime.Now.ToString("MMM"), "x=100; y=680; width=50; height=17; Combo=true;Border=1", objFont, null );
Dim strMonthOptions As String = "Jan##Feb##Mar##Apr##May##Jun##Jul##Aug##Sep##Oct##Nov##Dec"

Dim objCCMonth As PdfAnnot = objPage.CreateChoice( "CCMonth", strMonthOptions, DateTime.Now.ToString("MMM"), "x=100; y=680; width=50; height=17; Combo=true;Border=1", objFont, Nothing )

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.

PdfAnnot objSubmitButton = objPage.CreatePushbutton("CCSubmit", "Submit Form", "x=10; y=625; width=70; height=20", objFont, null);

objSubmitButton.SetAction( objDoc.CreateAction("Type=Submit; Html=true", "http://localhost/asppdf/manual_11/11_submit.asp" ) );
Dim objSubmitButton As PdfAnnot = objPage.CreatePushbutton("CCSubmit", "Submit Form", "x=10; y=625; width=70; height=20", objFont, Nothing)

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)

PdfManager objPdf = new PdfManager();

// Create empty document
PdfDocument objDoc = objPdf.CreateDocument();

PdfPage objPage = objDoc.Pages.Add();

// Draw gray background
objPage.Canvas.SetFillColor( .64f, .78f, .66f );
objPage.Canvas.FillRect( 0, 0, objPage.Width, objPage.Height );

PdfAnnot objCheckbox = objPage.CreateCheckbox( "Receipt", "x=100; y=660; width=30; height=30", null );

PdfGraphics objGrayBack = objDoc.CreateGraphics("Left=0; Right=30; Bottom=0; Top=30");
objGrayBack.Canvas.SetFillColor( .5f, .5f, .5f );
objGrayBack.Canvas.FillRect( 0, 0, 30, 30 );

PdfGraphics objWhiteBack = objDoc.CreateGraphics("Left=0; Right=30; Bottom=0; Top=30");
objWhiteBack.Canvas.SetFillColor( 1, 1, 1 );
objWhiteBack.Canvas.FillRect( 0, 0, 30, 30 );

PdfGraphics objLiteBack = objDoc.CreateGraphics("Left=0; Right=30; Bottom=0; Top=30");
objLiteBack.Canvas.SetFillColor( .82f, .82f, .1f );
objLiteBack.Canvas.FillRect( 0, 0, 30, 30 );

PdfGraphics 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.Graphics[0, "Off"] = objWhiteBack;
objCheckbox.Graphics[1, "Off"] = objLiteBack;
objCheckbox.Graphics[2, "Off"] = objGrayBack;

PdfFont objFont = objDoc.Fonts["ZapfDingbats"];

PdfGraphics 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 );

PdfGraphics 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 );

PdfGraphics 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.Graphics[0, "Yes"] = objWhiteBackChecked;
objCheckbox.Graphics[1, "Yes"] = objLiteBackChecked;
objCheckbox.Graphics[2, "Yes"] = objGrayBackChecked;

// Save document, the Save method returns generated file name
string strFilename = objDoc.Save( Server.MapPath("form.pdf"), false );
Dim objPdf As PdfManager = New PdfManager()

' Create empty document
Dim objDoc As PdfDocument = objPdf.CreateDocument()

Dim objPage As PdfPage = objDoc.Pages.Add()

' Draw gray background
objPage.Canvas.SetFillColor(0.64F, 0.78F, 0.66F)
objPage.Canvas.FillRect(0, 0, objPage.Width, objPage.Height)

Dim objCheckbox As PdfAnnot = _
objPage.CreateCheckbox("Receipt", "x=100; y=660; width=30; height=30", Nothing)

Dim objGrayBack As PdfGraphics = objDoc.CreateGraphics("Left=0; Right=30; Bottom=0; Top=30")
objGrayBack.Canvas.SetFillColor(0.5F, 0.5F, 0.5F)
objGrayBack.Canvas.FillRect(0, 0, 30, 30)

Dim objWhiteBack As PdfGraphics = objDoc.CreateGraphics("Left=0; Right=30; Bottom=0; Top=30")
objWhiteBack.Canvas.SetFillColor(1, 1, 1)
objWhiteBack.Canvas.FillRect(0, 0, 30, 30)

Dim objLiteBack As PdfGraphics = objDoc.CreateGraphics("Left=0; Right=30; Bottom=0; Top=30")
objLiteBack.Canvas.SetFillColor(0.82F, 0.82F, 0.1F)
objLiteBack.Canvas.FillRect(0, 0, 30, 30)

Dim objOutline As PdfGraphics = objDoc.CreateGraphics("Left=0; Right=30; Bottom=0; Top=30")
Dim LineWidth As Single = 3

objOutline.Canvas.SetColor(0.35F, 0.6F, 0.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(0.82F, 0.89F, 0.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(0.64F, 0.78F, 0.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.Graphics(0, "Off") = objWhiteBack
objCheckbox.Graphics(1, "Off") = objLiteBack
objCheckbox.Graphics(2, "Off") = objGrayBack

Dim objFont As PdfFont = objDoc.Fonts("ZapfDingbats")

Dim objGrayBackChecked As PdfGraphics = 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)

Dim objWhiteBackChecked As PdfGraphics = 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)

Dim objLiteBackChecked As PdfGraphics = 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.Graphics(0, "Yes") = objWhiteBackChecked
objCheckbox.Graphics(1, "Yes") = objLiteBackChecked
objCheckbox.Graphics(2, "Yes") = objGrayBackChecked

' Save document, the Save method returns generated file name
Dim strFilename As String = 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.