2

Kentico 12 仅支持使用开箱即用的“表单”页面构建器小部件的表单。

谁能提供如何在 MVC _Layout.cshtml 或不使用页面构建器的页面中使用 BizForms 的示例?

验收标准:

  • 必须允许 CMS 用户编辑表单并将更改反映在网站上
  • 必须允许开发人员在保存到 Kentico 之前和发送通知/自动回复之前操作/转换提交的数据
  • 必须正确呈现表单构建器中使用的自定义 FormSections 和自定义 FormComponents
4

4 回答 4

1

表单小部件是使用以下视图结构和视图模型的组合呈现的FormWidgetViewModel

using (Ajax.Kentico().BeginForm( ... ))
{
    @Html.AntiForgeryToken()

    @Html.Kentico().FormFields(Model.FormComponents, Model.FormConfiguration, FormFieldRenderingConfiguration.Widget)

    // Render Model.SubmitButtonImage using @Html.Kentico().ImageInput( ... )
    // Or render a plain <input> using Model.SubmitButtonText
}

如果您有BizFormInfo表单的对象,则以下属性需要它:

new FormWidgetViewModel
{
    FormName = formInfo.FormName,
    FormConfiguration = IFormBuilderConfigurationRetriever.Retrieve(formInfo),
    FormComponents = IFormProvider.GetFormComponents(formInfo).GetDisplayedComponents( ... ),
    FormPrefix = // This may be optional outside of the Page Builder context,
    SubmitButtonText = formInfo.FormSubmitButtonText,
    SubmitButtonImage = formInfo.FormSubmitButtonImage
}

在里面Ajax.Kentico().BeginForm你可以传入控制器和处理表单的动作。

使用方法IFormProvider来更新或添加表单提交并发送电子邮件。

更新(见评论)

IFormBuilderConfigurationRetriever被标记internal,所以它不能直接访问。它的实现反过来用于IFormBuilderConfigurationSerializer反序列化formInfo.FormBuilderLayout. 那个接口也有标记internal。此外,该接口的实现使用internal FormBuilderTypesBinder.

这意味着没有可用于检索的 API Model.FormConfiguration。从 Kentico 12.0.16 开始,您需要重新创建内部功能。基本实现是这样的:

JsonConvert.DeserializeObject<FormBuilderConfiguration>(formInfo.FormBuilderLayout, new JsonSerializerSettings
    {
        ContractResolver = new CamelCasePropertyNamesContractResolver(),
        TypeNameHandling = TypeNameHandling.Auto,
        SerializationBinder = // Set to the internal FormBuilderTypesBinder, which validates only known form builder types
        StringEscapeHandling = StringEscapeHandling.EscapeHtml
    });

于 2019-03-29T15:26:15.127 回答
1

OP 发布了一篇关于如何完成这项工作的博客。

该解决方案需要使用 Kentico 的一些内部 API 来使用 Form Widgets 渲染 Form Builder,并将该代码放入 Controller 操作中。

var formInfo = BizFormInfoProvider
    .GetBizFormInfo(formName, SiteContext.CurrentSiteName);

string className = DataClassInfoProvider
    .GetClassName(formInfo.FormClassID);

var existingBizFormItem = className is null
    ? null
    : BizFormItemProvider
        .GetItems(className)?.GetExistingItemForContact(
           formInfo, contactContext.ContactGuid);

var formComponents = formProvider
    .GetFormComponents(formInfo)
    .GetDisplayedComponents(
      ContactManagementContext.CurrentContact, 
      formInfo, existingBizFormItem, visibilityEvaluator);

var settings = new JsonSerializerSettings
{
    ContractResolver = new CamelCasePropertyNamesContractResolver(),
    TypeNameHandling = TypeNameHandling.Auto,
    StringEscapeHandling = StringEscapeHandling.EscapeHtml
};

var formConfiguration = JsonConvert.DeserializeObject<FormBuilderConfiguration>(
    formInfo.FormBuilderLayout, settings);

return new FormWidgetViewModel
{
    DisplayValidationErrors = true,
    FormComponents = formComponents.ToList(),
    FormConfiguration = formConfiguration,
    FormName = formName,
    FormPrefix = Guid.NewGuid().ToString(),
    IsFormSubmittable = true,
    SiteForms = new List<SelectListItem>(),
    SubmitButtonImage = formInfo.FormSubmitButtonImage,
    SubmitButtonText = string.IsNullOrEmpty(formInfo.FormSubmitButtonText) 
      ? ResHelper.GetString("general.submit")
      : ResHelper.LocalizeString(formInfo.FormSubmitButtonText)
};

我接受了这个想法并写了一篇后续文章,Kentico EMS: MVC Widget Experiments Part 3 - Rendering Form Builder Forms without Widgets,这表明我们还可以使用 Kentico 的预构建 Form Widget 视图代码来获得预期的渲染和表单提交功能。

<!-- ~/Views/Form/Form.cshtml -->

@using Kentico.Forms.Web.Mvc;
@using Kentico.Forms.Web.Mvc.Widgets;
@using Kentico.Forms.Web.Mvc.Widgets.Internal

@model FormWidgetViewModel

@{
    var config = FormWidgetRenderingConfiguration.Default;

    // @Html.Kentico().FormSubmitButton(Model) requires 
    // this ViewData value to be populated. Normally it
    // executes as part of the Widget rendering, but since
    // we aren't rendering a Widget, we have to do it manually

    ViewData.AddFormWidgetRenderingConfiguration(config);
}

@using (Html.Kentico().BeginForm(Model))
{
    @Html.Kentico().FormFields(Model)

    @Html.Kentico().FormSubmitButton(Model)
}
于 2020-06-11T17:24:29.033 回答
0

Hades,您可以使用 Forms API ( https://docs.kentico.com/api12/content-management/form-data ) 来保存/访问表单数据并为其实现完全自定义的布局。希望有帮助!

于 2019-03-11T12:51:52.090 回答
0

您可以查看Kentico.Forms.Web.Mvc.WidgetsMVC 项目中的命名空间(默认情况下应该包含它)。

其中有一个KenticoFormWidgetController控制器类,它呈现表单部分并接受表单提交。您可以使用该控制器的 Index 路由来呈现表单的一部分,但是我不知道该路由的外观如何。

如果您可以访问 Kentico 的源代码,您可以自己检查它的内部结构。

于 2019-03-13T11:02:05.330 回答