web-dev-qa-db-ja.com

AJAXビューで有効にするとフォームAPIが壊れますAJAXボタン(Drupal 8)

製品ノードには、フォームAPI(ajax)で実装される「カートに追加」ボタンのあるフォームがあります。

$form['add_to_cart'] = array(
  '#type' => 'button',
  '#value' => $this->t('Add to cart'),
  '#ajax' => array(
    'callback' => 'Drupal\custom_cart\Form\AddToCartForm::addProductToCart',
    'event' => 'click',
    'effect' => 'fade',
    'wrapper' => '#custom-cart', 
    'progress' => array(
      'type' => 'throbber',
    ),
  )
);

...

public function addProductToCart(array &$form, FormStateInterface $form_state) {
if ($parent_node_id = $form_state->getStorage()['parent_node_id']) {
  if ($product_node = Node::load($parent_node_id)) {
    $pid = $product_node->get('field_product_bid')->value;
    $price = $product_node->get('field_product_price')->value;
    $renderer = \Drupal::service('renderer');
    $response = new AjaxResponse();
    Cart::addLineItem($pid, $form_state->getValue('amount'), $price);
    $cart = Cart::getThemedCart();
    $elem = ['#markup' =>  $cart];
    $response->addCommand(new ReplaceCommand('.cart-nav', $renderer->render($elem)));
    return $response;
  }
 }
}

これは期待どおりに機能します。

製品概要ページでは、ビュー(ノードティーザー)で製品ノードをレンダリングし、ビューにはいくつかの公開されたフィルターが含まれています。ビューがajax対応の場合、「カートに追加」ボタンからのajaxコールバック(ブレーク)で404エラーが返されます。

リクエストURL: http://foobar.lo/views/ajax?_wrapper_format = drupal_ajax リクエストメソッド:POSTステータスコード:404見つかりません

誰かがこれを修正する方法を知っていますか(コアパッチはどこにありますか?)またはあなたが知っている回避策はありますか?

アドバイスをありがとう

1
lenni

問題はこの RenderElement :: preRenderAjaxForm の行にあります:

$settings['url'] = Url::fromRoute('<current>');

「カートに追加」ボタンが付いたフォームがビューのajaxリクエスト内でレンダリングされると、URLが誤ったエンドポイントに設定されます/views/ajax

回避策は、動的に設定されないように、フォーム要素のajax設定に静的URLを追加することです。

use Drupal\Core\Form\FormBuilderInterface;

  '#ajax' => [
    'callback' => '::add',
    'wrapper' => $wrapper,
    'url' => Url::fromRoute('<front>'),   // set this to the route of the view page
    'options' => ['query' => \Drupal::request()->query->all() + [FormBuilderInterface::AJAX_FORM_REQUEST => TRUE]],
  ]

複数のページでフォームを使用する場合、フォームがこのビューでレンダリングされるときにのみURLを設定するようにコードを調整する必要があります。

3
4k4