困惑AJAX通过页面模板提交表单

时间:2017-08-15 作者:DᴀʀᴛʜVᴀᴅᴇʀ

我想我已经看了太多的代码,在试图更好地理解WordPress和AJAX中的表单时把自己弄糊涂了。本周我开始学习如何为页面创建表单并通过AJAX提交表单。

该页面是一个模板,我已经研究了两种处理方法。一种是通过重定向到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中编写动作的正确方法是什么呢

是否在同一页上处理表单

Reference points:


编辑:

进一步阅读后,决定进入RESTful提交。我引用了“REST APIs for Absolute Beginners“但我没有得到我所希望的回报:

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;
}
为什么我只能Your contact request had the title 在回信上,而不是在电子邮件上?

2 个回复
最合适的回答,由SO网友:Tom J Nowell 整理而成

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

因此,我将概述基本原理,这样您就有了一个可以向前推进的框架

修复管理AJAX,因此我将非常简要地介绍这一点,因为这不是我回答的关键,但会很有用:

添加一个名为action 而不是将其添加到URLvalidation.php 任何其他独立的文件都应该燃烧千个太阳,在JS中进行验证,然后在表单处理程序中再次进行验证。处理表单和验证表单是同一个步骤,其他人可以跳过验证直接进行处理。最后,使用标准表单处理程序来处理不使用/不可能使用JS的情况,检查表单中是否存在仅在提交时才会发生的内容,并通过具有空操作属性将表单提交到同一页面,例如:

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更改为使用REST端点,让我们调用darthvader/v1/contact, 我使用了来自stackoverflow answer here:

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”需要创建,所以让我们告诉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中的成功函数中处理它。您还可以返回其他响应,例如:

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 ) );
您可以在端点内进行验证,但也可以通过指定期望的字段和验证它们的函数,让端点为您进行验证,但我将此作为练习(或新问题)留给您

SO网友:Johansson

每个AJAX流程都有4个基本步骤:

异步向服务器发送请求处理服务器端任务从服务器检索响应根据服务器的响应更改客户端创建对服务器的请求有多种方法。这可以通过jQuery和JavaScript来完成。然而,由于jQuery使它变得更容易,我将使用它。jQuery提供了3种不同的功能,具有类似的功能。这些功能包括:

  • $.ajax(); - 支持POST和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,所以我将使用REST API,默认情况下将内容输出为JSON。

    您可以使用任何您想要的东西,例如管理Ajax,只要这是一种良好的做法,并且不会影响性能或导致安全问题。

    现在让我们注册一个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
    
    这是我们休息的路线。由于域可能会更改,因此明智的做法是使用wp_localize_script. 为此,我们将所有脚本保存到一个名为script.js 然后排队(&N);本地化它。

    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 );
    
    现在我们可以访问site_url(); 通过使用url_object.url_string 在我们的剧本中!

    现在就这样了。点击按钮,享受乐趣。

结束

相关推荐

如何从REST API访问和AJAX响应的标头

如何访问rest API的标头和ajax响应?我需要总页数(X-WP-TotalPages)这里是我的代码:$(document).ready(function () { var pageCounter = 1; var ourHTMLString = \'\'; ///////////////////////////////////// // Ajax function starts // ///////