neos/form-yamlbuilder

基于Flow表单框架的图形用户界面,用于创建和编辑表单

资助包维护!
shop.neos.io/neosfunding

安装量: 13,374

依赖项: 0

建议者: 0

安全性: 0

星标: 6

关注者: 6

分支: 6

开放问题: 1

语言:JavaScript

类型:neos-package

3.0.1 2019-07-02 12:31 UTC

This package is auto-updated.

Last update: 2024-08-29 04:31:30 UTC


README

此包实现了一个基于Web的IDE,可用于创建和编辑Neos.Form包的YAML定义。

你现在阅读的是API文档的入口点。对于一般介绍和使用示例,我们建议查看Neos.Form包中包含的文档。

相关包

请确保查看其他Flow表单框架相关包

赞助

本作品得到了AKOM360 - 多渠道营销慷慨赞助

由以下人员实现

许可证

我们将Form YAML Builder许可给GNU Lesser General Public License(LGPL)版本2.1或更高版本。

扩展点

Form YAML Builder旨在可扩展,以下是一些点

  • 您可以调整CSS样式
  • 您可以覆盖Handlebars模板以调整表单构建器的HTML标记
  • 您可以通过继承Neos.Form.YamlBuilder.View.Editor.AbstractPropertyEditor来编写新的编辑器,这些编辑器将在编辑面板中显示
  • 您可以通过继承Neos.Form.YamlBuilder.View.Editor.ValidatorEditor.DefaultValidatorEditor来编写新的验证器编辑器,这些编辑器将在编辑面板中的验证器下方显示
  • 您可以通过类似创建新的验证器编辑器的方式编写新的完成器编辑器,这些编辑器将在完成器下方显示

如果您想扩展表单构建器,则需要EmberJS和JavaScript知识。

调整CSS样式和加载额外的JavaScript文件

表单构建器UI中包含的CSS文件和使用的JavaScript文件使用路径Settings.yaml中的Neos.Form.YamlBuilder.stylesheetsNeos.Form.YamlBuilder.javaScripts进行配置。

它们具有相同的结构,因此我们只需关注如下所示的CSS样式配置

Neos:
  Form:
    YamlBuilder:
      stylesheets:
        slickGrid:
          sorting: 10
          files: ['resource://Neos.Form.YamlBuilder/Public/Library/SlickGrid/slick.grid.wrapped.css']
        # … some more definitions here …
        application:
          sorting: 100
          files: ['resource://Neos.Form.YamlBuilder/Public/Css/FormBuilder.css']

Neos.Form.YamlBuilder.stylesheets下方有一个“bundle”列表,需要包含。对于每个bundle,“files”数组指向应适当包含的资源。排序决定了包含顺序(数字低者先包含)。

您甚至可以设置特定的样式表为NULL以禁用其包含

Neos:
  Form:
    YamlBuilder:
      stylesheets:
        slickGrid: ~

JavaScript文件的包含和修改可以以完全相同的方式进行。

覆盖Handlebars模板

您应该首先了解Handlebars模板,因为它们被EmberJS使用--如果需要,请在其文档中阅读

Form Builder使用的每个handlebars模板都在Settings.yaml中注册

Neos:
  Form:
    YamlBuilder:
      handlebarsTemplates:
        ValidatorEditor: 'resource://Neos.Form.YamlBuilder/Private/Templates/FormBuilder/ValidatorEditor.html'
        # here follow lots of other handlebars templates

handlebarsTemplates下方存储了一个关联数组,其中Ember.View中使用的templateName,而是模板存储在文件系统中的位置。

您可以将这样的模板轻松复制到另一个包中,并更新相应的设置。这样,您可以随意调整表单构建器。

当表单构建器加载时,handlebars 模板将直接插入到 HTML 标记中,这是在 EmberJS 内处理 handlebars 模板的首选方式。

实现自定义编辑器

为了实现自定义编辑器,您需要执行以下操作

  • 创建一个新的 JavaScript 文件,并使用上述解释的 JavaScript 加载机制加载它
  • (可能)创建一个新的 Handlebars 模板,并按照上述解释在设置中注册它
  • 实现您的编辑器;您始终可以查看现有的编辑器

内部结构 - 开发和编译过程

如果您想开发表单构建器的核心,那么您需要了解以下章节中概述的内容。

使用 Docker 的前端开发/构建环境

由于我们需要特定版本的 NPM、Gem 和 CoffeeScript,我们已经将前端构建过程改为在 Docker 中封装。

以下概述的内容仍然正确;但它运行在 Docker 环境中。

安装

  • 确保您已安装 Docker
  • 运行 make build

CoffeeScript、SASS、API 文档

本项目使用 CoffeeScript 作为 JavaScript 预处理器,使用 SASS 作为 CSS 预处理器。此外,它使用 docco-husky 项目来生成文档。

然后,您可以在包的顶级目录中运行 cake,并将获取可以执行的构建目标列表。以下目标存在

  • build:编译 CoffeeScript 和 SASS 到 JavaScript 和 CSS
  • buildDocumentation:使用 docco-husky 构建 API 文档
  • wrapCssFile:在升级外部 JavaScript 库后,您需要调用此命令。它将它们的 CSS 文件包装在用于特定页面部分的特定选择器中。

单元测试

表单构建器为模型提供了 JavaScript 单元测试,您可以通过在浏览器中打开 Tests/JavaScript/SpecRunner.html 来运行它们。

命名和约定

表单 YAML 构建器按以下结构构建,并使用以下名称

+------------------------------------------------------------+
|                                                            |
|   Header                                                   |
+-------------------+----------------------+-----------------+
|                   |                      |                 |
|                   |                      |                 |
|                   |                      |                 |
|      Structure    |                      |                 |
|      Panel        |                      |                 |
|                   |                      |                 |
|                   |                      |                 |
+-------------------+      Stage           |  Element Options|
|                   |                      |  Panel          |
|                   |                      |                 |
|                   |                      |                 |
|      Insert       |                      |                 |
|      Element      |                      |                 |
|      Panel        |                      |                 |
|                   |                      |                 |
|                   |                      |                 |
|                   |                      |                 |
+-------------------+----------------------+-----------------+

配置表单构建器

在此指南之后,您将学习如何通过设置 配置表单构建器

在“创建元素”内部添加新表单元素

假设您已创建表单元素,并希望在表单构建器中使其可用。为此,您需要一些如下所示的 YAML 配置

# we are now inside Neos:Form:presets:[presetName]
formElementTypes:
  'Your.Package:YourFormElement':
    # the definitions for your form element
    formBuilder:
      label: 'Your New Form Element'
      group: custom
      sorting: 200

为了确定表单元素是否在表单构建器中可见,您必须将 formBuilder:group 设置为有效的组。一个 表单元素组 用于将可用的表单元素一起进行视觉分组。在默认配置文件中,已配置以下组

  • input
  • select
  • custom
  • container

label - 如您所预期的那样 - 是可读性标签,而 sorting 决定了表单元素在表单元素组内的排序顺序。

创建新的表单元素组

所有表单元素组都在预设中的 formElementGroups 内定义,因此您可以这样添加新组

# we are now inside Neos:Form:presets:[presetName]
formElementGroups:
  specialCustom:
    sorting: 500
    label: 'My special custom group'

对于每个组,您需要指定一个可读的 labelsorting(它决定了组的排序顺序)。

设置表单元素的默认值

当创建一个表单元素时,您可以直接在表单元素上设置一些默认值。举个例子,假设您想要构建一个ProgrammingLanguageSelect,用户可以选择他喜欢的编程语言。

在这种情况下,我们想要定义一些默认的编程语言,但构建表单的集成商也应该能够添加自定义选项。这些默认选项可以使用Settings.yaml中的formBuilder:predefinedDefaults键来设置。

以下是ProgrammingLanguageSelect的完整配置(这是一个从Neos.FormExample包中提取的示例)

# we are now inside Neos:Form:presets:[presetName]
formElementTypes:
  'Neos.FormExample:ProgrammingLanguageSelect':
    superTypes:
      'Neos.Form:SingleSelectRadiobuttons': TRUE
    renderingOptions:
      templatePathPattern: 'resource://Neos.Form/Private/Form/SingleSelectRadiobuttons.html'

      # here follow the form builder specific options
      formBuilder:
        group: custom
        label: 'Programming Language Select'
      
        # we now set some defaults which are applied once the form element is inserted to the form
        predefinedDefaults:
          properties:
            options:
              0:
            _key: 'php'
            _value: 'PHP'
              1:
            _key: 'java'
            _value: 'Java etc'
              2:
            _key: 'js'
            _value: 'JavaScript'

对比用例:性别选择

创建新的表单元素中,我们实现了一个特殊的性别选择。让我们思考一下性别选择编程语言选择示例之间的区别

对于性别选择字段,使用表单构建器的集成商不需要为此表单元素设置任何选项,因为这些可用的选项(FemaleMale)已在表单元素模板内部预定义。

对于编程语言选择,我们只想为集成商设置一些合理的默认值,但希望他能够调整这些值。

选择使用哪种策略主要取决于预期的使用模式

  • 性别选择示例中,如果之后向列表中添加了新的选项,这将直接反映在所有使用此输入字段的表单中。
  • 如果您使用predefinedDefaults,则更改这些设置将仅应用于新元素,而不是现有元素。

注意:为了使性别选择与表单构建器很好地协同工作,我们应该禁用options编辑器,如下所示(因为选项不应由实施者编辑)

# we are now inside Neos:Form:presets:[presetName]
formElementTypes:
  'Neos.FormExample:GenderSelect':
    formBuilder:
      editors:
        # Disable "options" editor
        options: ~

提示:使用formBuilder:predefinedDefaults和使用表单元素类型定义之间的区别也可以用来添加其他元素,如ValidatorsFinishers

标记验证器和完成器为必填项

有时,您想简化表单构建器的用户界面,并使某些选项对您的用户来说更容易使用。一个常见的用例是您希望某些验证器,如StringLength验证器,始终在用户界面中显示,因为它非常常用。

这可以按照以下方式配置

# we are now inside Neos:Form:presets:[presetName]
formElementTypes:
  'Neos.Form:TextMixin': # or any other type here
    formBuilder:
      editors:
        validation:
          availableValidators:
            'Neos.Flow:StringLength': # or any other validator
              # mark this validator required such that it is always shown.
              required: true

完成器

同样的,这也适用于完成器,例如以下配置使电子邮件完成器成为必填项

# we are now inside Neos:Form:presets:[presetName]
formElementTypes:
  'Neos.Form:Form':
    formBuilder:
      editors:
        finishers:
          availableFinishers:
            'Neos.Form:Email': # or any other finisher
              # mark this finisher required such that it is always shown.
              required: true

完成

现在,您应该有一些修改表单构建器的技巧。阅读下一章以获取更多高级帮助。

扩展表单构建器

完成本指南后,您将学习

  • 如何将自定义CSS包含到表单构建器中

  • 如何编写自定义完成器编辑器

  • 如何调整表单构建器

有关如何使用自定义JavaScript扩展表单构建器的深入参考可以在表单构建器API文档的起始页找到。

使用自定义CSS调整表单构建器

假设您想使用位于Your.Package/Resources/Public/FormBuilderAdjustments.css中的自定义CSS文件调整表单构建器。然后,您需要告诉表单构建器加载此附加样式表。您可以通过在包的Settings.yaml中添加一个条目来实现,如下所示

Neos:
  Form:
    YamlBuilder:
      stylesheets:
        customAdjustments:
          files: ['resource://Your.Package/Public/FormBuilderAdjustments.css']
          sorting: 200

最重要的是sorting属性,因为它定义了CSS文件的包含顺序。从100以下的排序已被表单构建器保留用于内部使用,因此除非您有充分的理由,否则您应该使用100以上的排序数字。

提示:将额外的JavaScript文件加载到表单构建器中的方法与此相同。

重写表单构建器Handlebars模板

假设我们想要调整表单构建器的标题,使其显示您的公司名称。为此,我们需要修改标题区域的默认handlebars模板

警告:如果修改handlebars模板,您可能需要在发布表单构建器的新版本后调整它们!修改handlebars模板对于未计划的扩展性很有用,但您应该将其作为最后的手段!

默认模板位于Neos.Form.YamlBuilder/Resources/Private/FormBuilderTemplates/Header.html中,如下所示

<h1>Form Builder - {{Neos.Form.YamlBuilder.Model.Form.formDefinition.label}}</h1>
{{#if Neos.Form.YamlBuilder.Model.Form.currentlyLoadingPreview}}
   <span id="neos-form-yamlbuilder-loading">Loading..</span>
{{/if}}

<ul id="neos-form-yamlbuilder-toolbar">
   <li class="neos-form-yamlbuilder-preset">
      {{view Neos.Form.YamlBuilder.View.Header.PresetSelector}}
   </li>
   <li class="neos-form-yamlbuilder-preview">
      {{#view Neos.Form.YamlBuilder.View.Header.PreviewButton class="neos-form-yamlbuilder-button icon"}}Preview{{/view}}
   </li>
   <li class="neos-form-yamlbuilder-save">
    {{#view Neos.Form.YamlBuilder.View.Header.SaveButton class="neos-form-yamlbuilder-button icon"}}Save{{/view}}
   </li>
</ul>

我们只需将其复制到Your.Package/Resources/Private/FormBuilderTemplates/Header.html中,并根据需要调整它,修改<h1>...</h1>内的部分

<h1>Your Company Form Builder - {{Neos.Form.YamlBuilder.Model.Form.formDefinition.label}}</h1>

然后,我们需要告诉表单构建器我们想要使用不同的handlebars模板来显示标题。为此,我们需要以下Settings.yaml

Neos:
  Form:
    YamlBuilder:
      handlebarsTemplates:
        Header: 'resource://Your.Package/Private/FormBuilderTemplates/Header.html'

警告:如果您想要覆盖此类设置,请确保您的包在Neos.Form.YamlBuilder包之后加载。

创建自定义编辑器

每个表单元素都在表单YAML构建器的右侧的元素选项面板中进行编辑。为了保持灵活性和可扩展性,元素选项面板是一个用于编辑器的容器,整个编辑器可以编辑表单元素。有大量预定义的编辑器,从简单的文本输入字段到用于编辑属性的网格小部件。

给定表单元素的所有编辑器都在formElementTypes定义中定义,如下所示

# we are now inside Neos:Form:presets:[presetName]:formElementTypes
'Neos.Form:TextMixin':
  formBuilder:
    editors:
      placeholder: # an arbitrary key for identifying the editor instance
        sorting: 200 # the sorting determines the ordering of the different editors inside the element options panel
        viewName: 'JavaScript.View.Class.Name' # the JavaScript view class name which should be used here
        # additionally, you can define view-specific options here
        # here, you can define some more editors.

现在我们将创建一个用于渲染选择框的自定义编辑器,并将其添加到文件上传表单元素中,以便用户可以选择允许的文件类型。完成后的编辑器是标准YamlBuilder分发的一部分,位于Neos.Form.YamlBuilder/Resources/Private/CoffeeScript/elementOptionsPanelEditors/basic.coffee

注意:如果您想要创建完全属于自己的编辑器,您需要包含额外的JavaScript文件。如何操作在上文中有详细说明

基本设置

注意:我们将使用CoffeeScript <https://coffeescript.node.org.cn>开发编辑器,但您当然也可以使用JavaScript。

我们将从Neos.Form.YamlBuilder.View.ElementOptionsPanel.Editor.AbstractPropertyEditor扩展我们的编辑器

Neos.Form.YamlBuilder.View.ElementOptionsPanel.Editor.SelectEditor = AbstractPropertyEditor.extend {
   templateName: 'ElementOptionsPanel-SelectEditor'
}

然后,我们将创建一个基本的handlebars模板,并将其注册到ElementOptionsPanel-SelectEditor下(如上所述)。我们将复制现有的编辑器模板并进行轻微调整

<div class="neos-form-yamlbuilder-controlGroup">
   <label>{{label}}:</label>
   <div class="neos-form-yamlbuilder-controls">
      [select should come here]
   </div>
</div>

注意:别忘了在您的Settings.yaml中注册handlebars模板ElementOptionsPanel-SelectEditor

现在我们已经准备好了所有部件,让我们在Neos.Form:FileUpload表单元素中使用编辑器

# we are now inside Neos:Form:presets:[presetName]:formElementTypes
'Neos.Form:FileUpload':
  formBuilder:
    editors:
      allowedExtensions:
        sorting: 200
        viewName: 'Neos.Form.YamlBuilder.View.ElementOptionsPanel.Editor.SelectEditor'

重新加载表单构建器后,您将在元素选项面板中看到文件上传字段有[选择应在这里显示]字段显示。

现在我们已经设置了基本结构,让我们通过实际实现来让编辑器充满活力。

实现编辑器

这里面的所有内容都是使用EmberJS进行JavaScript开发,使用绑定和计算属性。如果您对此感到困惑,请访问EmberJS <http://emberjs.com>_网站并阅读相关内容。

我们需要以某种方式配置编辑器中的可用选项,并以下列YAML配置文件类型

allowedExtensions:
  sorting: 200
  label: 'Allowed File Types'
  propertyPath: 'properties.allowedExtensions'
  viewName: 'Neos.Form.YamlBuilder.View.ElementOptionsPanel.Editor.SelectEditor'
  availableElements:
    0:
      value: ['doc', 'docx', 'odt', 'pdf']
      label: 'Documents (doc, docx, odt, pdf)'
    1:
      value: ['xls']
      label: 'Spreadsheet documents (xls)'

此外,上面的示例设置了元素编辑器的labelpropertyPath选项。label显示在元素前面,而propertyPath指向应使用此编辑器修改的表单元素选项。

此类编辑器定义的所有属性都可在编辑器对象内部使用,即SelectEditor现在神奇地拥有一个availableElements属性,我们可以在Handlebars模板中使用它来绑定选择框选项。因此,我们移除了[选择应出现在此处]并将其替换为Ember.Select

{{view Ember.Select contentBinding="availableElements" optionLabelPath="content.label"}}

现在,如果重新加载,我们将看到下拉列表中的选项列表。

保存选择

现在,我们只需要在模型中再次保存选择。为此,我们使用Ember.Select视图的selectionBinding将当前选择绑定到视图中的一个属性。

{{view Ember.Select contentBinding="availableElements" optionLabelPath="content.label" selectionBinding="selectedValue"}}

然后,在编辑器实现中创建一个计算属性 selectedValue,它更新value属性并触发更改通知回调@valueChanged()

SelectEditor = AbstractPropertyEditor.extend {
   templateName: 'ElementOptionsPanel-SelectEditor'
   # API: list of available elements to be shown in the select box; each element should have a "label" and a "value".
   availableElements: null

   selectedValue: ((k, v) ->
      if arguments.length >= 2
         # we need to set the value
         @set('value', v.value)
         @valueChanged()

      # get the current value
      for element in @get('availableElements')
         return element if element.value == @get('value')

      # fallback if value not found
      return null
   ).property('availableElements', 'value').cacheable()
}

就这样 :)

创建Finisher编辑器

假设我们实现了一个DatabaseFinisher,它有一些配置选项,如表名,并且您想在表单构建器中使这些配置选项可编辑。这可以通过使用自定义Handlebars模板和一些配置来完成。在许多情况下,您不需要为此编写任何JavaScript。

您需要做三件事

  1. 将finisher注册为Finisher Preset
  2. 为表单配置finisher编辑器,包括新创建的finisher作为可用finisher
  3. 创建并包含handlebars模板
Neos:
  Form:
    presets:
      yourPresetName: # fill in your preset name here, or "default"
        # 1. Register your finisher as finisher preset
        finisherPresets:
          'Your.Package:DatabaseFinisher':
             implementationClassName: 'Your\Package\Finishers\DatabaseFinisher'
        formElementTypes:
          'Neos.Form:Form':
            formBuilder:
              editors:
                finishers:
                  availableFinishers:
                    # Configure the finisher editor for the form to include
                    # the newly created finisher as available finisher
                    'Your.Package:DatabaseFinisher':
                      label: 'Database Persistence Finisher'
                      templateName: 'Finisher-YourPackage-DatabaseFinisher'
    YamlBuilder:
      handlebarsTemplates:
        # include the handlebars template
        Finisher-YourPackage-DatabaseFinisher: 'resource://Your.Package/Private/FormBuilderTemplates/DatabaseFinisher.html'

现在,您只需要包含适当的Handlebars模板,如下所示

<h4>
   {{label}}
   {{#view Ember.Button target="parentView" action="remove"
                        isVisibleBinding="notRequired"
                        class="neos-form-yamlbuilder-removeButton"}}Remove{{/view}}
</h4>

<div class="neos-form-yamlbuilder-controlGroup">
   <label>Database Table</label>
   <div class="neos-form-yamlbuilder-controls">
      {{view Ember.TextField valueBinding="currentCollectionElement.options.databaseTable"}}
   </div>
</div>

提示:创建自定义验证器编辑器的方式相同,只是它们必须注册在validatorPresets下,并且编辑器被调用为validators而不是finishers