web-dev-qa-db-ja.com

混乱している AJAX ページテンプレートからフォームを送信する

私はAJAXを使ってWordPressのフォームをよりよく理解しようとしている間に、私はあまりにも多くのコードを見ていて自分自身を混乱させていると思います。私は今週、ページ用のフォームを作成し、それをAJAXを通して送信する方法を学ぶために始めました。

このページはテンプレートであり、処理の2つの解決策を調べたアクションです。次のようにPHPへのリダイレクトによるものです。

<form action="<?php echo get_template_directory_uri() . "/validation.php"; ?>" id="contactForm">
</form>

トピックに関するいくつかの投稿を読んだ後に、フォームの別々の検証がなされるべきであること。これは正しいですか、そしてそれはなぜですか?それから他の問題は私がテンプレートページでフォームを処理したいのであればフォームアクションは次のようになるべきです:

<form action="#" id="contactForm">
</form>

しかし私が見たWordPressの外では:

<form action="" id="contactForm">
</form>

どうしてこれなの? AJAX部分には、次の違いがあります。

jQuery.ajax({
    type :"post",
    url: ajaxurl,
    }
});

それから別のURL:

jQuery.ajax({
    type :"post",
    dataType:"json",
    url: MBAjax.admin_url,
    }
});

そして最後に:

jQuery.ajax({
    type :"post",
    dataType:"json",
    url: /wp-admin/admin-ajax.php?action=contactForm",
    }
});

それでは、WordPressでアクションを書くための適切な方法は何ですか:

  • フォームが同じページで処理されている場合
  • 別のPHPファイルがフォームを検証する場合

それでは、WordPressにおける適切なAJAX呼び出しは何ですか?

参照点:


編集する

さらに読んだ後、RESTfulな投稿に踏み込むことにしました。私は " REST Absolute初心者のためのAPI "を参照しましたが、望んでいるような結果が得られません。

HTML:

<form id="contactForm" action="" method="POST">
    <div class="form-group">
        <label for="form_email"><span class="asterisk">*</span>Email address:</label>
        <input type="email" class="form-control" id="form_email">
    </div>
    <div class="form-group">
        <button id="form_submit" class="supportbutton" type="submit">Submit</button>
    </div>
</form>
<div id="testForm"></div>

jQuery:

$(document).ready(function() {
    $('#contactForm').submit(function(e) {
        e.preventDefault(); 
        jQuery.ajax({
            url: '<?php echo home_url(); ?>/wp-json/darthvader/v1/contact',
            type: 'post',
            dataType: 'json',
            data: $('#contactForm').serialize(),
            success: function(data) {
                $("#testForm").html(data);
            },
             error: function() {
                alert("There was an issue");
             },
        });
    });
});

functions.php:

add_action('rest_api_init', function() {
    register_rest_route('darthvader/v1', '/contact/', array(
        'methods'   => 'POST',
        'callback'  => 'darth_contact_form'
    ));
});
function darth_contact_form(\WP_REST_Request $request) {
    $email = $request['form_email'];
    return "Your contact request had the title " . $email;
}

EメールではなくYour contact request had the titleのみが返品時に表示されるのはなぜですか?

<form action="<?php echo get_template_directory_uri() . "/validation.php"; ?>" id="contactForm">

????

それで私は基本的な基本を概説します、それであなたは前進するためのフレームワークを持っています

管理AJAXの修正

それが私の答えの核心ではないのでそれで私はこれを非常に簡単にカバーするつもりですが、役に立つでしょう:

  • URLに追加するのではなく、actionという名前の隠し入力フィールドを追加します。
  • validation.phpと他のどんなスタンドアロンファイルも千の日差しの火で燃えて、JSで、そして再びフォームハンドラでこの検証をするべきです。フォームの処理と検証は同じ手順ですが、それ以外の場合は検証をスキップして処理に直接進むことができます。

最後に、JSが使用されていない、または使用できない場合には標準のフォームハンドラを使用し、フォームに送信された場合にのみ発生するものを確認し、空のaction属性を指定して同じページに送信します。例えば:

if ( !empty( $_POST['form_page'] ) ) {
    $valid = false;

    // do validation
    // 
    if ( true === $valid ) {
        // yay do whatever submitting the form is meant to do
        // if it's a multipage form, handle that here
    } else {
        get_template_part( 'form' ); // show the form again, but with warnings for validation
    }
} else {
    get_template_part( 'form' );
}

RESTfulフォーム送信

フォーム送信jQueryをa REST endpointを使用するように変更し、これをdarthvader/v1/contactと呼びましょう。ここで stackoverflow回答からのコードを使用しました

jQuery('input#submitButton').click( function() {
    jQuery.ajax({
        url: '/wp-json/darthvader/v1/contact',
        type: 'post',
        dataType: 'json',
        data: jQuery('form#contactForm').serialize(),
        success: function(data) {
            //... do something with the data...
        }
    });
});

これはREST APIによるフォーム送信のほとんどすべてですが、そのエンドポイントが存在する必要があります。 '/ wp-json/darthvader/v1/form'を作成する必要があるので、tell WP POSTを受け付けるエンドポイントが必要です。

add_action( 'rest_api_init', function () {
        register_rest_route( 'darthvader/v1', '/contact/', array(
                'methods' => 'POST',
                'callback' => 'darth_contact_form'
        ) );
} );

それが呼ばれたときに何が起こるかを定義します。

function darth_contact_form( \WP_REST_Request $request ) {
    //
}

それが私達が私達のフォームを扱うところです、例えば:

function darth_contact_form( \WP_REST_Request $request ) {
    $title = $request['title'];
    $message = $request['message'];
    // send an email or create a post, or whatever
    // the contact form does when its submitted
    return "Your contact request had the title ".$title;
}

戻り値はJSONに変換されてブラウザに送り返されるので、この答えの前半で見たjavascriptのsuccess関数でそれを処理できます。他の応答も返すことができます。

return \WP_REST_Response( "Bad request, X Y and Z are empty", 400);

また、WP_Errorオブジェクトを返して、問題が発生したか正しくないかを示すことができます。

return new WP_Error( 'awesome_no_author', 'Invalid author', array( 'status' => 404 ) );

エンドポイント内で検証を行うことができますが、期待するフィールドとそれらを検証するための関数を指定することによってエンドポイントに検証を行わせることもできますが、これは練習用(または新しい質問)として残します。

3
Tom J Nowell

すべてのAJAXプロセスには、4つの基本ステップがあります。

  1. 非同期にサーバーに要求を送信する
  2. サーバーサイドタスクを処理する
  3. サーバーから応答を取得する
  4. サーバーの応答に基づいてクライアント側に変更を加える

サーバーへの要求を作成する

これを行うには多くの方法と方法があります。これはjQueryとJavaScriptの両方で行えます。しかし、jQueryを使うと簡単になるので、それを使用します。 jQueryは、同様の機能を持つ3つの異なる機能を提供します。これらの機能は次のとおりです。

  • $.ajax(); - POSTとGETメソッドの両方をサポート
  • $.get(); - 単純なGETメソッド
  • $.post(); - 単純なPOSTメソッド

どの方法を使用するのかわからないので、$.ajax();に進みます。サンプルコードをサーバーに送信してから、サーバーの応答に基づいてメッセージを表示します。送信を処理するjQuery関数を宣言しましょう。

この関数はサーバにユーザ名を送ります。

function sendMyForm( string ) {
    // Begin an Ajax request
    $.ajax({
        type: 'POST',                   // Submission method
        url: url_object.url_string + '/wp-json/darthvader/ajax_submission', // I will explain this later
        data: { username : string },        // Data to be sent to server
        dataType: 'json',               // You should set this to JSON if you are going to use the REST api
        beforeSend: function(){         // Let's show a message while the request is being processed
            $('#status').html('<span>Processing</span>');
        },
        success: function ( response ) {
            // The Ajax request is successful. This doesn't mean the
            // sever was able to do the task, it just means that the
            // server did send a response. So, let's check the response
            if( response.success == true ) {
                $('#status').html('<span>Success</span>');
                $('#message').html('<span>' + response.message + '</span>');
            } else {
                $('#status').html('<span>Failed</span>');
                $('#message').html('<span>' + response.message + '</span>');
            }
        },
        error: function(){              // The request wasn't successful for some reason
            $('#status').html('<span>Unknown error.</span>');
        }
    });
};

さて、今度はボタンにアクションをバインドする必要があります。これを行うには多くの方法があります。たとえば、フォームの送信、データのシリアル化などを防ぎます。私もフォームを作成するつもりはありません。

私たちがフォームさえ必要としないことを実証するためにカスタムHTML divを作成します。これがフォームのようなHTMLです。

<div>
    <p id="status"></p>
    <p id="message"></p>
    <input id="my-input" type="text"/>
    <span id="button">This is our button!</span>
</div>

それでは、実際にはボタンではありません。あなたをだました。

$('#button').on('click',function(){
    // Get the value of our input box
    var username = $('#my-input').val();
    // Call our Ajax function and pass the username to it
    sendMyForm( string );
});

さて、今すぐフォームはユーザーのクリックで送信されます。

リクエストを処理するためのルートの作成

データ型をJSONとして宣言したので、デフォルトでコンテンツをJSONとして出力するREST AP​​Iを使用します。

それが良い習慣であり、パフォーマンスに影響を与えたりセキュリティ上の問題を引き起こさない限り、あなたはあなたが望むものは何でも使うことができます。

とりあえずRESTルートを登録しましょう。

add_action( 'rest_api_init','my_rest_route' ); 
function my_rest_route() {
    register_rest_route( 
        'darthvader',   // Base path here
        '/ajax_submission/',    // Child path
        array(
            'methods' => 'POST',
            'callback' => 'darth_contact_form'
        ) 
    );
}

さあ、本当に楽しい時間です。受信したデータを処理しましょう。

function darth_contact_form( \WP_REST_Request $request ){
    // Get the data that was sent to server
    $data = $request['username'];
    // Check if it's empty and send the response
    if( !empty( $data ) ){
        // Remember these from our Ajax call? This is where we set them
        $response['status'] =  true;
        $response['message'] =  'You have entered a username!';
    } else{
        $response['status'] =  false;
        $response['message'] =  'Why didn\'t you enter a username?';
    }
    // Don't forget to return the data
    return $response;
}

最後の仕上げ

この行を覚えてる?

url: url_object.url_string

これがRESTルートへのパスです。ドメインが変わる可能性があるので、wp_localize_scriptを使ってこれを動的に形成するのが賢明です。これを行うには、すべてのスクリプトをscript.jsという名前のファイルに保存してから、エンキューしてローカライズします。

wp_enqueue_script( 'my-script', get_template_directory_uri().'/js/script.js', array( 'jquery' ), '', true );

$localized = array(
    'url_string' => site_url(), // This is where that url_string came from
);
wp_localize_script( 'my-script', 'url_object', $localized );

これで、スクリプト内でurl_object.url_stringを使用してsite_url();にアクセスできます。

それは今のところそれです。ボタンをクリックして楽しんでください。

2
Jack Johansson