# 自定义表单属性对话框

本章节将介绍如何替换默认表单属性对话框,并使用内置表单属性编辑组件构建新的属性对话框。我们还将展示如何利用 PDFFormProperty 创建一个新的表单属性编辑组件。

注意:

如果您的应用是基于 PDFViewCtrl 实现,而不是基于 UIExtension 实现,则本章内容不适用。

# 替换默认表单属性对话框

在某些情况下,默认的表单属性对话框可能无法满足您的需求。例如,您可能需要添加自定义表单属性或修改现有属性的配置方式。

要替换默认表单属性对话框,可以通过以下两种方法实现。

# 1. 使用自定义的对话框组件替换

这种替换方式适用于对话框组件是基于 UIExtension 框架实现的。您可以通过重载 doShown 方法来替换默认表单属性对话框。

注意:

对话框的 name 属性名称必须设定为 fv--form-designer-widget-properties-dialog,否则不会被识别。

# 步骤

  • 创建自定义对话框: 根据您的需求,设计并实现一个自定义对话框组件。以下是一个简单的示例。

    class CustomDialogComponent extends UIExtension.SeniorComponentFactory.createSuperClass({
        template: `
            <layer @var.dialog="$component">
                <layer-header
                    @draggable="{type: 'parent'}"
                    title="Widget Properties Dialog"
                ></layer-header>
                <div>
                    Field Name: @{dialog.properties.fieldName}
                </div>
            </layer>
        `
    }) {
        static getName() {
            return 'widget-properties-dialog'
        }
        properties = {
            fieldName: ''
        }
        doShown() {
            this.pdfUI.getAllActivatedElements().then(([widgetComponent]) => {
                if(widgetComponent.annot?.getType() === 'widget') {
                    this.properties.fieldName = widgetComponent.annot.getField().getName();
                } else {
                    this.properties.fieldName = 'No Widget Selected';
                }
                this.digest();
            })
            super.doShown();
        }
    }
    
  • 注册对话框到自定义模块中

    const customFormDesignerModule = UIExtension.modular.module('custom-form-designer', []);
    customFormDesignerModule.registerComponent(CustomDialogComponent);
    
  • 通过 UI Fragment 配置替换内置的对话框组件

    new UIExtension.PDFUI({
        appearance: UIExtension.appearances.adaptive.extend({
            getDefaultFragments() {
                return [{
                    target: 'fv--form-designer-widget-properties-dialog',
                    action: 'replace',
                    template: `<custom-form-designer:widget-properties-dialog name="fv--form-designer-widget-properties-dialog"></custom-form-designer:widget-properties-dialog>`
                }];
            }
        }),
        // ...其他配置
    })
    

# 完整示例

以下是完整的示例,请自行运行并打开一个带表单的 PDF 文档以查看效果。

# 2. 替换表单右键菜单项

如果属性对话框不是通过 UIExtension 框架或者 layer 组件实现,但仍需要通过右键菜单触发显示,可以通过以下步骤来替换右键菜单。

# 步骤

  • 创建自定义表单属性对话框:根据您的需求,设计并实现一个自定义对话框组件。以下仅以一个简单的原生 dialog 实现的对话框为例。

    定义对话框的 HTML 结构:

    <dialog id="form-properties-dialog">
        <label>
            <span>field name:</span>
            <input type="text" name="fieldName">
        </label>
        <button type="button" id="close-form-properties-dialog-button">Close</button>
    <dialog>
    

    定义对话框的 JavaScript 实现类:

    class CustomFormPropertiesDialog {
        constructor(dialogId, pdfUI) {
            this.dialogId = dialogId;
            this.pdfUI = pdfUI;
            this.dialogElement = document.getElementById(this.dialogId);
            this.fieldNameElement = this.dialogElement.querySelector('input[name="fieldName"]');
            this.closeDialogBtn = this.dialogElement.querySelector('#close-form-properties-dialog-button');
            this.closeDialogBtn.addEventListener('click', () => {
                this.dialogElement.close();
            })
        }
        show() {
            this.pdfUI.getAllActivatedElements().then(([widgetComponent]) => {
                let fieldName;
                if(widgetComponent.annot?.getType() === 'widget') {
                    fieldName = widgetComponent.annot.getField().getName();
                } else {
                    fieldName = 'No Widget Selected';
                }
                this.fieldNameElement.value = fieldName;
            })
            this.dialogElement.showModal();
        }
    }
    
  • 创建一个 Controller,用于处理右键菜单项的点击事件

    const customFormDesignerModule = UIExtension.modular.module('custom-form-designer', []);
    customFormDesignerModule.registerController(
        class ShowCustomFormPropertiesDialogController extends UIExtension.Controller {
            static getName() {
                return 'ShowCustomFormPropertiesDialogController'
            }
            mounted() {
                super.mounted();
                this.dialog = new CustomFormPropertiesDialog('form-properties-dialog', this.pdfUI);
            }
            handle() {
                this.dialog.show();
            }
        }
    )
    
  • 替换右键菜单项

    new UIExtension.PDFUI({
        appearance: UIExtension.appearances.adaptive.extend({
            getDefaultFragments() {
                return [{
                    target: 'fv--ui-show-widget-properties-contextmenu-item',
                    action: 'replace',
                    template: `<contextmenu-item @controller="custom-form-designer:ShowCustomFormPropertiesDialogController">Show properties</contextmenu-item>`
                }];
            }
        }),
        // ...其他配置
    })
    

# 完整示例

以下是完整的示例,请自行运行并打开一个带表单的 PDF 文档以查看效果。

# 自定义表单属性对话框布局

在表单属性对话框中,我们针对不同的属性类型提供了细粒度的属性编辑组件(详见 内置表单属性编辑组件)。通过这些组件,您可以根据需求复用属性编辑组件,并自定义表单属性对话框的布局。