提问人:Juju 提问时间:8/22/2022 最后编辑:Juju 更新时间:8/27/2022 访问量:1247
Drupal 9 - Ajax 回调只工作一次
Drupal 9 - Ajax callback working only once
问:
我正在 Drupal 9.4 上构建站点,我在用户表单 alter 的 .module 文件中的 Ajax 回调遇到了一些问题。
功能不是很复杂,我在一个字段中显示之前上传的图像(在多个图像字段中),并附带一个删除按钮。
另一个字段显示仍然可以上传的图像数量。 在每个删除按钮上调用回调以执行 2 项操作:
1-删除照片字段中对图像的引用。
2- 将可上传的图像数量增加 1。
在我的回调中,如果我只做 1,一切正常。但是,如果我将 ajax 响应与字段更新一起添加以增加数字,则第一次删除有效并且字段增加 1。
但是,如果我尝试删除第二个回调,则会出现一个错误,指出找不到回调。 Symfony\Component\HttpKernel\Exception\HttpException:指定的 #ajax 回调为空或不可调用。
这是我的代码:
function main_form_alter(&$form, $form_state, $form_id) {
if ($form_id === 'user_form') {
/** @var \Drupal\user\Entity\User $user */
$user = $form_state->getFormObject()->getEntity();
$already_uploaded_files = getUserPictureFiles($user);
$nbre_file = count($already_uploaded_files);
$callback = 'remove_user_picture_callback';
if ($nbre_file < 10) {
$form['field_photos'] = [
'#title' => t('Vos photos'),
'#type' => 'dropzonejs',
'#max_files' => (10 - $nbre_file),
'#dropzone_description' => t('Déposez les fichiers ici pour les télécharger'),
'#attributes' => [
'id' => 'field-photos',
],
];
$form['photos_left'] = [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => t(10 - $nbre_file . " photo(s) restante(s)"),
'#prefix' => '<div id="field-photos-left">',
'#suffix' => '</div>',
];
}
if ($nbre_file === 10) {
$form['field_photos'] = [
'#title' => t('Vos photos'),
'#type' => 'markup',
'#markup' => t("Nombre maximum de photos atteint."),
];
}
if ($already_uploaded_files) {
$form['saved_uploaded_files'] = [
'#type' => 'value',
'#value' => $already_uploaded_files,
'#attributes' => ['id' => 'save-uploaded-files'],
];
$form['user_pictures_container'] = [
'#type' => 'container',
'#attributes' => [
'class' => ['user-photos-container'],
'id' => ['user-photos-container'],
],
];
foreach ($already_uploaded_files as $key => $file) {
$form['user_pictures_container']['picture_container_' . $key] = [
'#type' => 'container',
'#attributes' => [
'class' => ['image-square-container'],
'id' => ['image-square-container-' . $file->id()],
],
];
$form['user_pictures_container']['picture_container_' . $key]['user_uploaded_picture_' . $key] = [
'#type' => 'html_tag',
'#tag' => 'img',
'#attributes' => [
'src' => $file->createFileUrl(),
],
];
$form['user_pictures_container']['picture_container_' . $key]['remove_picture_' . $key] = [
'#type' => 'button',
'#name' => 'remove-button-' . $file->id(),
'#attributes' => [
'class' => ['user-picture-delete-icon-field'],
'data-name' => 'remove-button-' . $file->id(),
],
'#ajax' => [
'callback' => $callback,
'wrapper' => 'field-photos-left',
'effect' => 'fade',
'event' => 'click',
'prevent' => 'submit',
'progress' => [
'type' => 'throbber',
'message' => t('Suppression de la photo...'),
],
],
];
}
}
以及内部调用函数的回调
function remove_user_picture_callback($form, FormStateInterface $form_state): AjaxResponse {
// Get user Entity.
$user = getUserEntity($form_state);
// Get trigger fid.
$fid = getFid($form_state);
// Delete picture reference from user field_photos,
deletePictureReference($user, $fid);
return updateNbrePhotoUploaded($form, $form_state);
}
function updateNbrePhotoUploaded($form, FormStateInterface $form_state): AjaxResponse {
$user = getUserEntity($form_state);
$already_uploaded_files = getUserPictureFiles($user);
$nbre_file = count($already_uploaded_files);
$elem['photos_left'] = [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => t(10 - $nbre_file . " photo(s) restante(s)"),
'#prefix' => '<div id="field-photos-left">',
'#suffix' => '</div>',
];
$response = new AjaxResponse();
$response->addCommand(new ReplaceCommand('#field-photos-left', $elem));
return $response;
}
/**
* @param \Drupal\Core\Form\FormStateInterface $form_state
*
* @return string
*/
function getFid(FormStateInterface $form_state): string {
$element = $form_state->getTriggeringElement()['#name'];
return substr($element, strpos($element, '-') + 8);
}
/**
* @param \Drupal\Core\Form\FormStateInterface $form_state
*
* @return \Drupal\user\Entity\User
*/
function getUserEntity(FormStateInterface $form_state): User {
$form_state_user = $form_state->getFormObject()->getEntity();
return User::load($form_state_user->id());
}
/**
* @param \Drupal\user\Entity\User $user
* @param string $fid
*
* @return void
* @throws \Drupal\Core\Entity\EntityStorageException
*/
function deletePictureReference(User $user, string $fid): void {
$field_photos = $user->get('field_photos');
$field_photos_values = $field_photos->getValue();
// Get the index to remove
$index_to_remove = array_search($fid, array_column($field_photos_values, 'target_id'));
$field_photos->removeItem($index_to_remove);
$user->save();
}
/**
* Return array of user picture Files entity.
*
* @param $user
*
* @return array
*/
function getUserPictureFiles($user): array {
$user_pictures = $user->get('field_photos')->getValue();
$files = [];
if ($user_pictures) {
foreach ($user_pictures as $user_picture) {
if (array_key_exists('target_id', $user_picture)) {
/** @var File $file */
$file = File::load($user_picture['target_id']);
$files[] = $file;
}
}
}
return $files;
}
在这种情况下,我到处搜索相同的错误,但是...... 如果有人能帮忙! 谢谢
答: 暂无答案
评论