使用Ajax

时间:2018-04-10 22:02:35

标签: php jquery ajax wordpress

我正在尝试创建表单并使用ajax提交。所以页面不会重新加载。我没有很多关于ajax的经验,我试图找到尽可能多的信息。

现在在我的代码中,我可以在不重新加载的情况下使用表单。但我有一个上传文件的字段。我知道这样做有点不同,我也找到了一些例子,但到目前为止还没有运气。例如Ajax file upload in Wordpress - can't pass FormData

现在我有这样的My Ajax代码:

的Ajax

(function($) {

jQuery(document).ready(function() {

    // when user submits the form
    jQuery(document).on('submit', '.form-assignment', function(event) {

        var error_elm = jQuery('.ajax-error');
        var response_elm = jQuery('.ajax-response')
       // var widgetId = grecaptcha.reset(container);
        error_elm.html('');
        response_elm.html('');

        // prevent form submission
        event.preventDefault();

        var form_elm = jQuery(this);

        var url = form_elm.data('url');
        var action = form_elm.data('action');
        var form_data = new FormData();

        var data = {
            action: action,
            form_data : form_data
        };

        // add loading message
        response_elm.html('Loading...');

        jQuery.ajax({
            type : 'POST',
            url : url,
            data : data,
            processData: false,
            contentType: false,
            enctype: 'multipart/form-data',
            dataType : 'json',
            async : true
        }).success(function(response) {

            error_elm.html('');
            response_elm.html('');

            if(response.status !== 'success') {
                // something went wrong
                if(response.message) {
                    error_elm.html(response.message);
                    return;
                }

                // don't know ?
            }

            // success!!

            // log data
            console.log(response);

            // display data
            response_elm.html(response.message);
            $("#form-assignment").trigger("reset");
            grecaptcha.reset();
        }).error(function(response) {
            error_elm.html('');
            response_elm.html('');

            error_elm.html(response.statusText);
        });
    });

});



})( jQuery );

我的表单:

 <div class="ajax-error" style="color: red;"></div>
    <form class="form-assignment" name="form_assignment" id="form-assignment"
          method="post" enctype="multipart/form-data"
          data-url="<?php echo esc_url( admin_url( 'admin-ajax.php' ) ) ?>" data-action="form_submit1">
          <label>name:</label>
          <input type="text" name="customer-field-text"pattern="[a-zA-Z0-9 ]+" placeholder="<?php echo $field->label ?>" size="40"/>
          <label>file upload</label>
           <input type="file"  name="customer-field-upload" id="customer-field-upload"
                           multiple="false"/>
    </form>

现在这是我得到了多远。这不是我的完整形式我已经为sequrity添加了nonce和其他必需的设置。当我检查输入文件时它会一直显示该字段为空的错误消息。

我的表单处理程序

function handle_form_submission (){
global $wpdb;
$response = array(
    'status' => 'error',
    'message' => '',
);


parse_str($_POST['form_data'], $form_data);

//global $error;
$error = new WP_Error();

    if (empty($_POST['customer-field-name'])  ) {
    $error->add('empty','Name is required.');
}

    if (empty($_POST['customer-field-upload']) && empty($_FILES["customer-field-upload"]["name"])) {
    $error->add('empty','select an file.');
}

if ( !empty( $error->get_error_codes() ) ) {
    $error_messages = $error->get_error_messages();

    $error = '';
    foreach($error_messages as $error_message) {
        $error .= '<p>'.$error_message.'</p>';
    }

    $response['message'] = $error;

    wp_send_json( $response );
    wp_die();
}
$name                 = sanitize_text_field( $form_data["customer-field-name"] );
$upload                 = sanitize_text_field( $form_data["customer-field-upload"] );


require_once( ABSPATH . 'wp-admin/includes/image.php' );
require_once( ABSPATH . 'wp-admin/includes/file.php' );
require_once( ABSPATH . 'wp-admin/includes/media.php' );

 media_handle_upload( 'customer_field_upload', $form_data['post_id'] );

}

    add_action( 'wp_ajax_form_submit1', 'handle_form_submission' );

    // ajax hook for non-logged-in users: wp_ajax_nopriv_{action}
    add_action( 'wp_ajax_nopriv_form_submit1', 'handle_form_submission' );

所以我的问题是我可以做什么或添加到我的ajax或表单处理程序中以通过Ajax工作来提交文件上传。任何建议,建议或一些熟悉的现有例子将不胜感激。我正在练习使用WordPress和Ajax,这是我有多远。

我曾尝试使用FormData但到目前为止仍然没有运气。

3 个答案:

答案 0 :(得分:3)

以下是使用您提供的表单进行工作的一些提示:

<强>表格

<div class="ajax-error" style="color: red;"></div>
<form class="form-assignment" name="form_assignment" id="form-assignment" method="post" enctype="multipart/form-data"
      data-url="<?php echo esc_url(admin_url('admin-ajax.php')) ?>" data-action="form_submit1">
    <label>name:</label>
    <input type="text" name="customer-field-text" pattern="[a-zA-Z0-9 ]+" size="40"/>
    <label>file upload</label>
    <input type="file" name="customer-field-upload" id="customer-field-upload" multiple="false"/>
    <input type="submit" value="Submit" name="submit">
</form>

我从placeholder="<?php echo $field->label ?>"输入中删除了text,因为它来自您未提供的自定义代码。

<强> Ajax.js

jQuery(document).ready(function ($) {
    // when user submits the form
    jQuery(document).on('submit', '.form-assignment', function (event) {

        var error_elm = jQuery('.ajax-error');
        var response_elm = jQuery('.ajax-response');
        error_elm.html('');
        response_elm.html('');

        event.preventDefault();

        var form_elm = jQuery(this);

        var url = form_elm.data('url');
        var action = form_elm.data('action');
        var file = form_elm[0][1].files[0];
        var customer_field_text = form_elm[0][0].value;
        var form_data = new FormData();
        form_data.append('action', action);
        form_data.append('customer-field-upload', file);
        form_data.append('customer-field-name', customer_field_text);

        response_elm.html('Loading...');

        jQuery.ajax({
            type: 'POST',
            url: url,
            data: form_data,
            processData: false,
            contentType: false,
            cache: false
        }).success(function (response) {

            error_elm.html('');
            response_elm.html('');

            if (response.status !== 'success') {
                // something went wrong
                if (response.message) {
                    error_elm.html(response.message);
                    return;
                }

                // don't know ?
            }

            response_elm.html(response.message);
            $("#form-assignment").trigger("reset");

        }).error(function (response) {
            error_elm.html('');
            response_elm.html('');

            error_elm.html(response.statusText);
        });
    });

});

注意:您正在使用var form_elm = jQuery(this);,它返回包含所有表单内容的jquery对象。这就是我用它来访问输入信息的原因。相反,您可以使用其名称,类,ID,占位符等访问表单输入。

改变了什么

  1. 已移除(function($) {}包装,而是使用jQuery(document).ready(function ($) {});。这只是为了注意。无需使用jquery来访问$
  2. 我们从以下行的输入中获取文件和名称:

    var file = form_elm[0][1].files[0];
    var customer_field_text = form_elm[0][0].value;
    
  3. 我们正在为WordPress添加action,并将输入及其值输入FormData

    form_data.append('action', action);
    form_data.append('customer-field-upload', file);
    form_data.append('customer-field-name', customer_field_text);
    

    在这里,您可以更改我们发送的数组的名称。例如,我们将使用键customer-field-upload接收数组中的文件,并可以这样使用它:

    $_FILES['customer-field-upload']
    
  4. async : true:这条线我们不需要。这是true by defaultenctype: 'multipart/form-data',我们也不需要。
  5. data: form_data,我们只使用一个form_data变量(FormData对象)发送所有内容
  6. PHP 文件:

    1. 我没有使用add_action('wp_ajax_nopriv_form_submit1', 'handle_form_submission');,因为您提供的代码中没有与nonce相关的内容
    2. 您的$_POST将包含:

      Array
      (
         [action] => form_submit1 //action, which we used to send and accept Ajax request
         [customer-field-name] => some input value in the name field
      )
      

      您可以使用$_POST['customer-field-name']访问姓名输入。

    3. 您的$_FILES将包含:

      Array
      (
          [customer-field-upload] => Array
              (
                  [name] => input file name
                  [type] => input file type
                  [tmp_name] => temp file
                  [error] => 0 
                  [size] => some size
              )
      
      )
      

      您可以使用$_FILES['customer-field-upload']

    4. 处理输入文件

      编辑附加功能,可以使用多行代码添加所有输入:

      <强>表格

      <div class="ajax-error" style="color: red;"></div>
      <form class="form-assignment" name="form_assignment" id="form-assignment" method="post" enctype="multipart/form-data"
            data-url="<?php echo esc_url(admin_url('admin-ajax.php')) ?>" data-action="form_submit1">
          <label for="customer-field-text">name:</label>
          <input type="text" name="customer-field-text" id="customer-field-text" pattern="[a-zA-Z0-9 ]+" size="40"/>
          <label>file upload</label>
          <input type="file" name="customer-field-upload" id="customer-field-upload" multiple="false"/>
          <label for="select">select:</label>
          <select name="carlist" id="select">
              <option value="1">1</option>
              <option value="2">2</option>
              <option value="3">3</option>
              <option value="4">4</option>
          </select>
          <label for="email">email: </label>
          <input type="text" name="email" id="email">
          <input type="submit" value="Submit" name="submit">
      </form>
      

      <强> Ajax.js:

      jQuery(document).ready(function ($) {
          // when user submits the form
          jQuery(document).on('submit', '.form-assignment', function (event) {
      
              var error_elm = jQuery('.ajax-error');
              var response_elm = jQuery('.ajax-response');
              error_elm.html('');
              response_elm.html('');
      
              event.preventDefault();
      
              var form_elm = jQuery(this);
      
              var url = form_elm.data('url');
              var action = form_elm.data('action');
              var file_input_name = jQuery('#form-assignment').find('input[type=file]').attr('id');
              var form_data = new FormData();
      
              form_data.append('action', action);
      
              jQuery.each(jQuery(':input:not([type=submit]):not([type=file])', '#form-assignment' ), function(i, fileds){
                  form_data.append(jQuery(fileds).attr('name'), jQuery(fileds).val());
              });
              jQuery.each(jQuery(':input:not([type=submit]):not([type=text]):not([type=select])', '#form-assignment' )[0].files, function(i, file){
                  form_data.append(file_input_name, file);
              });
      
              response_elm.html('Loading...');
      
              jQuery.ajax({
                  type: 'POST',
                  url: url,
                  data: form_data,
                  processData: false,
                  contentType: false,
                  cache: false
              }).success(function (response) {
      
                  error_elm.html('');
                  response_elm.html('');
      
                  if (response.status !== 'success') {
                      // something went wrong
                      if (response.message) {
                          error_elm.html(response.message);
                          return;
                      }
      
                      // don't know ?
                  }
      
                  response_elm.html(response.message);
                  $("#form-assignment").trigger("reset");
      
              }).error(function (response) {
                  error_elm.html('');
                  response_elm.html('');
      
                  error_elm.html(response.statusText);
              });
          });
      
      });
      

      在这里,我们使用Jquery iterator将循环中的多个值添加到FormData对象中。这是示例,可以应用于复选框,textareas等。

答案 1 :(得分:0)

您缺少enctype: 'multipart/form-data'contentType: false以阻止jQuery将其设置为字符串。如果这不起作用,请参阅此example并按照相同的方法

   jQuery.ajax({
        type : 'POST',
        enctype: 'multipart/form-data',
        url : url,
        data : data,
        async : true,
        processData: false,
        contentType: false,
    })

答案 2 :(得分:0)

您的Jquery缺少

enctype: 'multipart/form-data'

当您提交表单时,这非常重要。这样就可以在不进行任何转换的情况下发送表单数据。

jQuery.ajax({
            type : 'POST',
            url : url,
            data : data,
            enctype: 'multipart/form-data',
            dataType : 'json',
            async : true
        }).success(function(response) {

            error_elm.html('');
            response_elm.html('');

            if(response.status !== 'success') {
                // something went wrong
                if(response.message) {
                    error_elm.html(response.message);
                    return;
                }

                // don't know ?
            }

            // success!!

            // log data
            console.log(response);

            // display data
            response_elm.html(response.message);
        }).error(function(response) {
            error_elm.html('');
            response_elm.html('');

            error_elm.html(response.statusText);
        });
    });