web-dev-qa-db-ja.com

フォーム自体がajaxで返されたときにフォームで#ajaxを再度呼び出す方法はありますか?

コメントの削除リンクを変更して、Ajaxで削除確認が返され、Ajaxで削除確認が実行されるようにしたい。

/ comment /%cid/deleteで削除を確認するようにフォームを修正したので、送信アクションはajaxで実行されます。

これを実現するために使用したコードは次のとおりです。

function awesomesite_comments_form_comment_confirm_delete_alter(&$form, &$form_state, $form_id) {

  // Add the Ajax Submit Function
  $form['actions']['submit']['#ajax'] = array(
    'callback' => 'awesomesite_comments_ajax_delete',
    'progress' => false,
  );

}

function awesomesite_comments_ajax_delete($form, $form_state) {

  // Get rid of all of the messages that have been set
  drupal_get_messages();

  // Get the comment & node objects
  $comment = $form_state['comment'];

  // Put all of the Ajax Commands into an array
  $commands = array();

  // Place the comment above the form
  $commands[] = ajax_command_remove('#comment-'.$comment->cid.', comment-'.$comment->cid.' + .comment');

  // Return the Ajax Commands Array
  return array('#type' => 'ajax', '#commands' => $commands);

 }

これは削除確認ページでは完全に機能しますが、Ajaxでフォームを返すと、送信はAjaxで処理されなくなり、標準のページ更新が行われます。

Ajaxを介して確認フォームを配信するために必要なPHPコードは次のとおりです。

function awesomesite_comments_menu_alter(&$items) {
  $items['comment/%/delete/ajax'] = $items['comment/%/delete'];
  $items['comment/%/delete/ajax']['delivery callback'] = 'ajax_deliver';
  $items['comment/%/delete/ajax']['page callback'] = 'awesomesite_comments_ajax_confirm_delete_page';
}

function awesomesite_comments_ajax_confirm_delete_page($cid) {

  // Get the HTML of the detele page.
  $data = drupal_render(comment_confirm_delete_page($cid));

  // Put all of the Ajax Commands into an array
  $commands = array();

  // Replace the HTML
  $commands[] = ajax_command_html('#comment-'.$cid.' + .comment', $data, array('effect' => 'fade'));

  return array('#type' => 'ajax', '#commands' => $commands);

}

そして、これはコメントの「削除」リンクを取り、フォームを返すための(上記のコールバックから)JavaScriptです。

jQuery('a.ajax-link:not(.ajax-processed)').addClass('ajax-processed').each(function() {

        // Cret the element settings object
        var element_settings = {};

        // Get rid of the progress
        element_settings.progress = { 'type' : 'none' };

        // setup the click elements and add the href
        if (jQuery(this).attr('href')) {
            element_settings.url = jQuery(this).attr('href');
            element_settings.event = 'click';
        }

        element_settings.effect = 'fade';

        // Get the base
        var base = jQuery(this).attr('id');

        // Register the Ajax Request with Drupal
        Drupal.ajax[base] = new Drupal.ajax(base, this, element_settings);

    });

Drupalは、ページが読み込まれたときに#ajaxのページ上のすべてのフォームを処理していると思いますが、AJAXを介してフォームが読み込まれるため、#は設定されていません。 ajax情報(確認できます)。 Ajaxリクエストの後で、どのようにしてDrupalに新しいフォームをチェックさせることができますか?それとも何か不足していますか?

どんな助けでも大歓迎です!

2
David Barratt

答えを見つけた!

私は単に間違った質問をしていた。私がする必要があったのは、Drupal.attachBehaviors()でdrupalビヘイビアーを再アタッチすることです。

このコードをJavaScriptコードに追加しました。

jQuery('.ajax-processed').once().ajaxSuccess(function() {
    Drupal.attachBehaviors();
});

ほら!すべてが正常に機能します。

5
David Barratt

少しわかりやすくするために、私のような初心者にとっては、次のように使用します。

(function($)  {

    $(document).ready(function(){

        ..the JS code here..

    });

jQuery('.ajax-processed').once().ajaxSuccess(function() {
    Drupal.attachBehaviors();
});

})(jQuery);

クライヴとデビッド、ありがとうSO

0
Maarten Hartman

このような問題に遭遇する前にいくつかのajaxフォームを作成しましたが、一部のajaxが機能し、他のパーツが機能しないのは奇妙でした。

Ajax.jsとajax呼び出しによって返されるデータ構造を詳しく調べたところ、私が発見した答えは、ajax.jsが2つの条件のいずれかに依存しているように見えることでした。 fapi ['#ajax']が有効な要素に「id」情報がないか、またはfapi ['#id']とfapi ['#attributes'] ['id']の両方を提供する必要があります。

うまくいけば、この種の問題に遭遇している人のために、これをチェックリストに追加して確認することができます。