Skip to content

Legacy Form Fields

Legacy form fields are the oldest of Word’s three form mechanisms, the ones that live behind FORMTEXT, FORMCHECKBOX and FORMDROPDOWN field codes. UniOffice adds them through the paragraph: AddTextInput, AddCheckBox and AddDropdownList each append a field to the paragraph and hand back a FormField you configure. If you are writing a new document rather than matching an existing one, read the group overview first, because content controls are the mechanism Word itself now prefers.

ConstructorType() reportsValue setters
p.AddCheckBox(name)FormFieldTypeCheckBoxSetChecked(bool), SetSize(pt)
p.AddTextInput(name)FormFieldTypeTextSetValue(string)
p.AddDropdownList(name)FormFieldTypeDropDownSetPossibleValues([]string), SetValue, SetDefaultValue

The drop-down constructor is spelled AddDropdownList, with a lowercase d in the middle. AddDropDownList does not exist and is the most common compile error on this page.

Adding fields

doc := document.New()
defer doc.Close()

cb := doc.AddParagraph().AddCheckBox("agree")
cb.SetSize(20)
cb.SetChecked(true)

doc.AddParagraph().AddTextInput("fullName").SetValue("Ada Lovelace")

planet := doc.AddParagraph().AddDropdownList("planet")
planet.SetPossibleValues([]string{"Mercury", "Venus", "Earth"})
planet.SetValue("Earth")

Each field goes in its own paragraph here only because that is how the example lays it out. Nothing stops you from calling AddRun().AddText("Name: ") on the same paragraph first, so the label and the field sit on one line.

SetValue on a drop-down stores an index into the list, so the possible values have to be set first and the argument has to match one of them exactly. Order matters in the other direction too for SetSize, which replaces the checkbox size element rather than merging into it.

Reading fields back is a document-level call. doc.FormFields() returns every field it finds, each with Name(), Type() and Value().

Limitations

Fields created this way do not survive SaveToFile. AddCheckBox and its siblings put the field name and the type element on the same wml.CT_FFDataChoice, and that type’s MarshalXML writes only the first non-nil child, so the saved w:ffData contains w:name and nothing else. Reopening the file with document.Open reports FormFieldTypeUnknown for every field and an empty Value(). Fields in a document that Word produced are unaffected, because Word writes each child as its own element; see Fill out an existing form.

SetName, SetEnabled and SetCalcOnExit each overwrite the field’s entire property list with a single-entry one. Calling any of them on a field returned by AddCheckBox, AddTextInput or AddDropdownList discards both the name and the field type, and the field then either disappears from FormFields() (which skips unnamed fields) or comes back as FormFieldTypeUnknown. Set the name through the constructor argument and leave the other two alone.

SetPossibleValues appends to the existing entries instead of replacing them. Calling it twice on the same field leaves both sets in the list.

SetValue on a drop-down is a silent no-op when the argument is not one of the possible values. No error is returned and the previous selection stays. SetDefaultValue behaves the same way and does nothing at all on the other two field types.

IsChecked reports true whenever a w:checked element is present, without reading its w:val attribute. A checkbox written as <w:checked w:val="0"/> therefore reads back as checked, and Value() returns "true".

FormFields() skips any field without a w:name, so a field whose name was lost is not merely mistyped, it is absent from the returned slice entirely.

Run the example

The example builds a document with one of each field type, prints what FormFields() finds, and writes filled-form.docx.

git clone https://github.com/unidoc/unioffice-examples.git
cd unioffice-examples/document/form-fields
go run main.go

If this is your first time using UniOffice, follow the getting started guide to create an API key and set up your development environment.

View the full source

Sample output

The example calls SetEnabled and SetCalcOnExit on the checkbox and SetName on the drop-down, so the printed result is affected by the property-list overwrite described above:

found 1 fields
- Name: Solar system Type: FormFieldTypeUnknown Value:

Drop those three calls and the same program reports all three fields with the right types and values.

Document with a checkbox, a text input and a drop-down

Last updated on