如何实施AJAX表单提交?


14

我的任务是通过AJAX提交联系表单,然后显示“谢谢您的提交!” 消息,将其加载到表单所在的位置。因此,我需要取消现有的联系表。

我找到了一些示例,这些示例如何在D8中使用AJAX 验证表单字段,但是找不到任何示例来实现Ajax表单提交并随后通过AJAX加载某些内容。

如何执行任务?我应该如何更改联系方式以添加所需的功能?


对于那些遇到通用表单问题的用户:Webform模块允许您根据需要创建表单,并通过ajax提交结果。
弗洛里安·穆勒

Answers:


26

在表单中使用ajax时,必须记住以下几点:

  • 知道您是要重建整个表单还是仅重建其中的一部分,并用具有ID属性的div元素相应地包装表单,该元素将在触发元素的#ajax定义中用作“包装器”。对this()使用#prefix和#suffix属性。还请记住,如果您的表单具有自定义模板,则在这种情况下()不会呈现前缀和后缀,否则它们将被呈现两次-通过模板以及表单主题包装器。您无法通过将#theme_wrappers设置为空数组来防止这种情况,因为表单模板包含实际的表单html元素。$form['#prefix'] = '<div id="myform-ajax-wrapper">'; $form['#suffix'] = '</div>';{{ form|without('#prefix', '#suffix') }}

  • 在你的Ajax提交处理程序,返回整个窗体或你已经包裹并要重建(它的一部分return $formreturn $form['myelement'])。您还可以使用ajax命令,而不只是返回表单结构,但这是更高级的内容。

  • 将每个值存储在表单状态的存储中,直到提交表单为止。在提交处理程序($form_state->set('somevalue', $form_state->getValue('somevalue')))中执行此操作,$form_state->setRebuild()如果您未进行最终表单提交,则始终调用。我更喜欢使用自定义提交处理程序,但是在主提交处理程序中具有更多逻辑也是完全可以的。

  • 始终#name在执行提交的按钮上使用属性,如果您只有单个表单提交处理程序,则使用该属性$for_state->getTriggeringElement()['#name']来检测哪个元素已提交了表单。

  • 如果在#ajax定义中使用'trigger_as',例如,如果要提交带有select元素的表单,请始终使用与在按钮上相同的#ajax定义。以我的经验,这是必需的-尽管未在文档中说明。

  • 使用#limit_validation_errors有时可能会变得非常棘手,弄清楚为什么表单无法正常工作可能需要花费一些时间,因此请谨慎使用(这对于仅在实际重建的元素上隔离表单错误是很有用的,这样您的代码就可以了)不会影响表格的其他部分)。

  • 始终使用按钮提交表单,如果您想花哨的东西(例如选择作为触发元素),请使用#ajax配置的'trigger_as'选项,并使用'js-hide'类隐藏真正的按钮以获得良好的UI。

  • 在表单定义中,从表单状态的存储中获取默认值(如果存在),否则将其分配到存储中。否则,该表格将无法正常工作。

  • 不要使用$ this或您无法从外部访问的其他任何东西,否则它将破坏ajax。始终使用静态ajax处理程序。

  • 最终提交表单时,根据您(没有)为ajax提供自定义表单提交处理程序的事实,请通过调用来禁用表单重建$form_state->setRebuild(FALSE)

  • 您可以在ajax提交元素($element['#ajax']['callback'] = '::ajaxFormRebuild';$element['#submit'] = [['::ajaxFormSubmitHandler'];)中使用::简写调用。

  • ajax回调纯粹是返回重建的表单或ajax命令。切勿返回更改后的表单(即,不要在此回调中更改表单数组)。


很棒的检查清单,如果您在drupal 8中遇到有关ajax的问题​​!(我不明白第一点,为什么不渲染ajax wrap div?)
4k4'1

我不记得确切,但我认为它可能与#theme,#theme_wrappers以及渲染器中#prefix和#suffix属性的处理有关。我认为您最终将在<form>元素内部使用包装器。当然,这仅适用于您重建整个表单而不仅仅是某些元素的情况。

谢谢,但是在哪里可以找到任何简单的AJAX提交示例?
谢尔盖·克拉夫琴科


@IvanJaros,谢谢。您知道在提交Ajax后如何清除表单值吗?
milkovsky '16

1

要添加到此清单,如果要在模式窗口中显示表单,则可能不会显示错误消息。正如Ivan Jaros所说,您必须确保表格具有包装器:

$form['#prefix'] = '<div id="my-form-wrapper-id">';
$form['#suffix'] = '</div>';

您还需要将以下内容添加到提交表单的元素中。在大多数情况下,这将是您的提交按钮:

$form['submit'] = [
    '#type' => 'submit',
    '#value' => $this->t('Save Changes'),
    '#attributes' => [
        'class' => [
            'btn',
            'btn-md',
            'btn-primary',
            'use-ajax-submit'
        ]
    ],
    '#ajax' => [
        'wrapper' => 'my-form-wrapper-id',
    ]
];

1

我使用Contact ajax模块。有关它的更多详细信息(从其项目页面):

Contact Ajax在Drupal 8中实现了针对Contact表单的Ajax提交。

怎么运行的

启用该模块后,每个联系表单将显示一个复选框“ Use ajax”。启用此复选框后,联系表单将为您显示另一个选项“确认类型”,其中包含以下选项:

  • 加载表单:将发送表单而不重新加载页面。
  • 从自定义消息加载:加载自定义文本。
  • 从节点加载:提交表单后加载节点。

如果出现以下情况,此模块可以为您提供帮助:

  • 您需要自定义确认消息
  • 您需要提交联系表单而无需重新加载页面。
  • 您要在提交表单后加载自定义文本或其他节点。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.