Если попытаться в #ajax callback сгенерировать новую форму, то она подхватит данные из текущего запроса и скорей всего попытается снова засабмититься, уйдя в бесконечный цикл. Чтобы этого не происходило надо создать временный объект Request, поместить его в стэк, сгенерировать форму и удалить Request из стэка. В простейшем случае это выглядит так:
$fake_request = new \Symfony\Component\HttpFoundation\Request();
\Drupal::requestStack()->push($fake_request);
... generate form ...
\Drupal::requestStack()->pop();
Более сложный пример генерации формы добавления товара в корзину:
$request_stack = \Drupal::requestStack();
$product_id = 123;
// Create fake request object to product page
$url = Url::fromRoute('entity.commerce_product.canonical', ['commerce_product' => $product_id]);
$fake_request = Request::create($url->toString());
$fake_request->attributes->add([
RouteObjectInterface::ROUTE_NAME => $url->getRouteName(),
RouteObjectInterface::ROUTE_OBJECT => \Drupal::service('router.route_provider')->getRouteByName($url->getRouteName()),
'_raw_variables' => new ParameterBag(['commerce_product' => $product_id]),
'commerce_product' => Product::load($product_id),
]);
// Push fake request to requests stack
$request_stack->push($fake_request);
// Build "add to cart" form (form builder will use fake request from stack)
$form_build = \Drupal::service('commerce_product.lazy_builders')->addToCartForm($product_id, 'full', TRUE, 'ru');
// Remove fake request from requests stack
$request_stack->pop();
Способ с созданием собственного Request объекта и помещения его в стэк очень часто используется при написании тестов.
Написанное актуально для
Drupal 9+
Похожие записи
- AJAX в форме корзины Commerce 2
- AJAX добавление товара в корзину в Commerce 2
- Показать второй шаг многошаговой формы в модальном окне
- Навесить на элемент managed_file свой ajax callback (Как обновить всю форму при загрузки файла в managed_file)
- Восстанавливаем позицию текстового курсора при ajax обновлении формы
Добавить комментарий