翻译者:长风Drupal开发:Drupal8 AJAX Forms
原文链接:https://www.drupal.org/docs/8/api/menu-api/providing-module-defined-contextual-links
Drupal开发中,添加ajax到表单中可以允许Drupal开发者动态的更新表单的表单字段和标记。
ajax的回调函数可以做以下事:
更新已经存在的字段或者添加新的标段字段。
执行各种预定义的ajax命令。(https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Ajax%21CommandInterface.php/interface/implements/CommandInterface/8.3.x)
粘贴ajax回调到一个字段
内容:
1、创建一个表单
2、ajax渲染元素
3、ajax的回调函数:渲染数组、html标签、ajax命令
4、在ajax的回调函数中自定义javascription
5、debugging ajax回调函数
6、更多的渲染
1、创建一个表单
$form['container']['output'] = [
'#type' => 'textfield',
'#size' => '60',
'#disabled' => TRUE,
'#value' => 'Hello, World!',
'#attributes' => [
'id' => ['edit-output'],
],
];
drupal将自动为所有的表单元素生成一个Id,你可以查看已经渲染的结果来找到Drupal已经生成的ID;尽管如此,无论什么原因,你修改这个ID将导致回调不能生效;
2、Ajax 渲染元素
在一个Drupal8表单元素中,渲染数组使用'ajax'标记,下面是一个Drupal8中使用Ajax的例子
$form['input'] = [
'#type' => 'textfield',
'#title' => 'A Textfield',
'#description' => 'Enter a number to be validated via ajax.',
'#size' => '60',
'#maxlength' => '10',
'#required' => TRUE,
'#ajax' => [
'callback' => 'sayHello',
'event' => 'keyup',
'wrapper' => 'edit-output',
'progress' => [
'type' => 'throbber',
'message' => t('Verifying entry...'),
],
],
];
上面的Drupal8代码将创建一个Ajax 请求,当用户敲击键盘的时候这个请求将触发一个sayhello()的函数。
上面的ajax用到的属性如下 :
callback:通过ajax求情将触发的函数
event:触发请求的事件,蔽日click、keyup、change等
wrapper:这个元素的ID;也可以把这个ID包裹这元素的外面。
progress:当请求正在进行时用来为用户展示的信息,以便用户知道请求正在进行。
3、ajax回调函数
这里有不同的方法来相应Ajax请求。你既可以使用ajaxresponse对象并执行一个ajax命令,也可以使用html标签,来替换wrapper元素。
use Drupal\Core\Form\FormStateInterface;
public function sayHello(array &$form, FormStateInterface $form_state) : array {
$elem = [
'#type' => 'textfield',
'#size' => '60',
'#disabled' => TRUE,
'#value' => 'Hello, ' . $form_state->getValue('input') . '!',
'#attributes' => [
'id' => ['edit-output'],
],
];
return $elem;
}
4、在ajax回调中执行自断一的javascription
你可以写自定义的ajax命令。但是你只能于宁很少的Javascription,并且没有过多。AJAX InvokeCommand将被用来调用jquery的方法
你的ajax调用
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\InvokeCommand;
public function sayHello(array &$form, FormStateInterface $form_state) : AjaxResponse {
$response = new AjaxResponse();
$response->addCommand(new InvokeCommand(NULL, 'myAjaxCallback', ['My arguments']));
return $response;
}
你的jquery方法
(function($)
{
//argument passed from InvokeCommand
$.fn.myAjaxCallback = function(argument)
{
console.log('myAjaxCallback is called.');
//set some input field's value to 'My arguments'
$('#some-wrapper input').attr('value', argument);
};
})(jQuery);
5、Debugging AJAX 回调函数
kint可以用来在ajax回调中记录,非常简单的在你的回调函数中调用kint($form_state),来记录ajax错误或者WSOD,你可以使用ajaxresponse来显示kint()的结果,
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;
//implements HOOK_form_alter. add debug output container and ajax callback
function YOUR_MODULE_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
if($form_id == 'your_form_id') {
//add empty container to the form. it gets filled with
//the kint output from our ajax event callback.
$form['debug'] = [
'#type' => 'container',
'#attributes' => [
'id' => ['debug-out'],
],
];
}
//here follows the code where you add the #ajax callback
//to some field of this form. lets say a taxonomy reference select box
$form['field_yourtaxonomy']['widget']['#ajax'] = array(
'event' => 'change',
'callback' => 'sayHello',
);
}
//the callback function, triggered by changing selection of our taxonomy select box
public function sayHello(array &$form, FormStateInterface $form_state) : AjaxResponse {
$response = new AjaxResponse();
$debugOut = @Kint::dump($form_state);
$response->addCommand(new ReplaceCommand('#debug-out', $debugOut ));
return $response;
}