TX Text Control .NET Server

Form Fields

Topic

Applications, contracts and questionnaires that users fill out in the browser are built as forms in the Document Editor. The way leads from the available form fields and inserting them through the JavaScript API to a protected form that users fill out, and ends with your code reading the values and exporting the result.

The examples extend the view of the ASP.NET Core tutorial. Fields explains fields in general.

Form Field Types

A form field is a field that users fill out. Users insert form fields on the Form Fields tab of the ribbon. Its Insert Form Fields group has five small buttons: text form field, check box, combo box, drop-down list and date form field. Highlight Form Fields marks the fields in the document:

Order form in the Document Editor with highlighted text, drop-down, date and check box form fields in a table, and the Form Fields tab with the groups Insert Form Fields, Edit Form Fields and Form Validation

In the JavaScript API, TXTextControl.formFields returns a FormFieldCollection with a method for each type:

Form fieldObjectInserted with
Text fieldTextFormFieldaddTextFormField
Check boxCheckFormFieldaddCheckFormField
Drop-down list or combo boxSelectionFormFieldaddSelectionFormField
Date field with a date pickerDateFormFieldaddDateFormField

A selection form field is a drop-down list when users can only choose one of its items, and a combo box when they can also type a value. The inherited setEditable method decides which: false for a drop-down list, true for a combo box.

Insert Form Fields

The methods insert a form field at the current input position. The text, selection and date methods take the width in twips that the field has while it is empty, where 0 stands for a default width. The check box method takes the initial state instead.

The following code inserts one field of each type. Add it below the editor in Views/Home/Index.cshtml:

<input type="button" onclick="insertTextFormField()" value="Text Field" />
<input type="button" onclick="insertCheckBox()" value="Check Box" />
<input type="button" onclick="insertDropDown()" value="Drop-Down List" />
<input type="button" onclick="insertDateField()" value="Date Field" />

<script>
    function logError(error) {
        console.log(error.msg);
    }

    function insertTextFormField() {
        // 0: the default width while the field is empty
        TXTextControl.formFields.addTextFormField(0, function (formField) {
            formField.setName("customer_name", function () {
                formField.setDescriptiveText("Customer name");
            });
        }, logError);
    }

    function insertCheckBox() {
        TXTextControl.formFields.addCheckFormField(false, function (formField) {
            formField.setName("accept_terms");
        }, logError);
    }

    function insertDropDown() {
        TXTextControl.formFields.addSelectionFormField(0, function (formField) {
            formField.setName("shipping_method", function () {
                // false: drop-down list, true: combo box
                formField.setEditable(false, function () {
                    formField.setItems(["Standard", "Express", "Overnight"], function () {
                        formField.setSelectedIndex(0);
                    });
                });
            });
        }, logError);
    }

    function insertDateField() {
        TXTextControl.formFields.addDateFormField(0, function (formField) {
            formField.setName("delivery_date");
        }, logError);
    }
</script>

The code works as follows:

  • Each add method passes the new form field to its callback. setName gives it the name under which your code and exported PDF forms identify the value.
  • setDescriptiveText sets the text that screen readers use for the field.
  • setItems sets the items of the drop-down list; an item can't be an empty string. setSelectedIndex selects the first item; -1 selects none.

Settings of the Form Field Types

FormFieldCollection.getItem passes the form field at the input position, or the field with an ID as the third parameter, and remove removes a form field.

Let Users Fill Out the Form

A form is ready for users when the document is protected so that only the form fields can be changed. This takes two settings: the document permissions of the document allow filling in form fields, and the editor runs in the ReadAndSelect edit mode, in which the text can be read and selected but not changed.

  1. In the editor, open the Permissions tab. In the Restrict Editing group, select Read Only and leave Restrict filling in Form Fields cleared, so that allowEditingFormFields stays true.

  2. Click Enforce Protection.

  3. Save the document, for example in the TX Text Control format, as described in Loading and Saving Documents.

  4. Load the form in a view whose edit mode is ReadAndSelect:

    @using TXTextControl.Web.MVC
    
    @Html.TXTextControl().TextControl(settings => {
        settings.EditMode = TXTextControl.Web.EditMode.ReadAndSelect;
    }).LoadText("Documents/form.tx", TXTextControl.Web.StreamType.InternalUnicodeFormat).Render()
    

TextControlSettings.EditMode sets the edit mode when the view is rendered. In JavaScript, setEditMode changes it while the editor is open, and TXTextControl.documentPermissions returns the permissions with allowEditingFormFields.

In the protected form, users can only fill out the form fields. FormField.setEnabled with false excludes a single field; it takes effect in the ReadAndSelect mode when form fields may be edited.

Validate Form Fields

Forms can contain conditional instructions: rules that enable or disable fields, check values or set a value depending on other fields. Users add them with the Form Validation group of the Form Fields tab: Enable Form Validation turns validation on, Manage Conditional Instructions... creates and edits the rules, and Highlight Invalid Values, Previous Invalid Value and Next Invalid Value show the values that a rule marked as invalid. Conditional Instructions describes the dialog box, the conditions and instructions it offers and a complete booking form.

The rules are applied when the protected form opens and whenever a value they test changes, only while form field validation is turned on, which your code does with setIsFormFieldValidationEnabled:

TXTextControl.addEventListener("documentLoaded", function () {
  TXTextControl.setIsFormFieldValidationEnabled(true);
});

The blog article Building a Credit Card Payment Form with Conditional Instructions builds a form with such rules.

Read the Values

The following code logs every change of a form field, lists the current values and exports the form as a PDF document with the values as static text:

<input type="button" onclick="logValues()" value="Log Values" />
<input type="button" onclick="exportFlattenedPdf()" value="Export Flattened PDF" />

<script>
    TXTextControl.addEventListener("textControlLoaded", function () {
        TXTextControl.addEventListener("formFieldTextChanged", function (e) {
            console.log(e.formField.name + ": " + e.formField.text);
        });
        TXTextControl.addEventListener("formFieldCheckChanged", function (e) {
            console.log(e.formField.name + ": " + e.formField.checked);
        });
        TXTextControl.addEventListener("formFieldSelectionChanged", function (e) {
            console.log(e.formField.name + ": " + e.formField.text);
        });
        TXTextControl.addEventListener("formFieldDateChanged", function (e) {
            // Unix time stamp in milliseconds
            console.log(e.formField.name + ": " + new Date(e.formField.date));
        });
    });

    function logValues() {
        TXTextControl.getTextFieldsByType(TXTextControl.TextFieldType.FormFields, function (fields) {
            fields.forEach(function (field) {
                console.log(field.name + ": " + field.text);
            });
        }, function (error) {
            console.log(error.msg);
        });
    }

    function exportFlattenedPdf() {
        TXTextControl.flattenFormFields(function () {
            TXTextControl.saveDocument(TXTextControl.StreamType.AdobePDF, function (result) {
                // result.data contains the PDF as a Base64 string for your server
                console.log(result.data.length + " characters of PDF data");
            });
        });
    }
</script>
  • The four events are raised when the value of a field has changed, by code or by the user, and not at every keystroke: formFieldCheckChanged when a check box is clicked or toggled with the keyboard, formFieldDateChanged and formFieldSelectionChanged when a date or an item is picked, and these two and formFieldTextChanged when the user has typed a new value and leaves the field. Conditional instructions are evaluated at the same moments. Their handlers receive the field data in formField: the name and text of every form field, checked for check boxes and date for date fields.
  • getTextFieldsByType with FormFields passes the names and texts of all form fields at once.
  • flattenFormFields converts all form fields to static text, so that the values can no longer be changed.
  • saveDocument with AdobePDF saves the result as a PDF document.

To keep the form fillable in the PDF document, save without flattening: form fields are exported as PDF form fields with their names and values. Saved as DOCX, form fields become content controls. PDF Forms explains how to read the values of filled PDF forms on the server.

Next Steps