这几天使用drupal的ajax form,因为第一次使用,本身对drupal也不熟,着实把我弄得够呛,摸索着总算搞定了,记录并分享一下使用心得,有错请指正!
1、表单按钮的处理,因为是ajax,那么自然不能使用type=‘submit’的按钮,我这里根据需求做了三个按钮,一个是span的,作为显示和用户点击的,第二个是button的,是触发ajax的,第三个是submit的,触发真正的表单提交。这里踩了两个坑,详见:https://editor.youkuaiyun.com/md/?articleId=121329201
2、这里有个 ‘#validate’ => [’::noValidate’],如果不想使用drupal自带的表单验证,就加这个,同样如果不想使用表单自带的提交,可以使用 ‘#submit’ => [’::noSubmit’], noValidate和noSubmit是对应的方法名,下面有代码:
$form['actions']['button'] = [
'#type' => 'button',
'#value' => t('Popup Submit'),
'#validate' => ['::noValidate'],
'#attributes' => ['class' => ['hide', 'button-popup']],
'#prefix' => '<span class="button button-show-popup">' . t('Submit') . '</span>',
'#ajax' => [
'callback' => [$this, 'requestFormPopupAjax'],
'event' => 'click',
],
];
public function noValidate(array &$form, FormStateInterface $form_state) {
// Clear all validation errors.
$form_state->clearErrors();
}
public function noSubmit(array &$form, FormStateInterface $form_state) {
// Do nothing.
}
3、使用ajax form的时候一定要在表单前面加下面这句,不然不会生效。
$form['#attached']['library'][] = 'core/drupal.dialog.ajax';
4、在回调中可以判断系统自带的validate是否有错误,根据错误自定义判断处理。
PS1:这里的 #weight 是表示错误消息显示的位置,数字越低就越往上。
PS2:
r
e
s
p
o
n
s
e
−
>
a
d
d
C
o
m
m
a
n
d
(
n
e
w
H
t
m
l
C
o
m
m
a
n
d
(
response->addCommand(new HtmlCommand(
response−>addCommand(newHtmlCommand(selector,
f
o
r
m
)
)
;
这
里
的
form)); 这里的
form));这里的selector是选择器,因为在一个表单有多处错误的时候他会全部显示出来,所以drupal的这个方法是替换整个表单,这里的
s
e
l
e
c
t
o
r
就
应
该
是
表
单
外
层
的
d
i
v
的
I
D
或
者
c
l
a
s
s
(
保
证
唯
一
)
,
当
然
这
里
的
selector就应该是表单外层的div的ID或者class(保证唯一),当然这里的
selector就应该是表单外层的div的ID或者class(保证唯一),当然这里的form也可以换成自定义的错误提示,纯文本或html代码都可以。另外HtmlCommand这里可以换成很多其他的Command类,比如替换,插入等等,网上搜一下很好查。
PS3:因为AJAX的返回是不需要刷新页面的,所以页面很长的时候,如果错误在最上面,页面是不会自己跳上去的,这里可以使用 KaTeX parse error: Expected 'EOF', got '#' at position 43: …directCommand(‘#̲xxx’));#表示ID选择器…form_state->setErrorByName()添加的错误消息不会再页面上显示
$errors = $form_state->getErrors();
if ($errors) {
$form['status_messages'] = [
'#type' => 'status_messages',
'#weight' => -10,
];
$response->addCommand(new HtmlCommand('#block-ixtend-content', $form));
}
5、Ajax可以做弹窗,$content一般是block
$content = \Drupal::service('plugin.manager.block')
->createInstance('register_password_popup_block', [
'data' => 'Thank you for your registration.'
])
->build();
$response->addCommand(new OpenModalDialogCommand(
'',
$content,
[
'width' => '700',
'dialogClass' => 'register-reset-password-popup',
'closeOnEscape' => FALSE,
]
));