网站优化

网站优化

Products

当前位置:首页 > 网站优化 >

使用Ajax提交文件上传的Wordpress表单

GG网络技术分享 2025-03-18 16:12 4


问题描述:

I am trying to create form and submitting this with ajax. So the page wont reload. I don\'t have a lot of experience with ajax and I am trying to find as much information as I can.

Right now in my code I can sbmit form without reloading. But I have a field for uploading files. I know It is a bit different to do this and I also found some examples but so far no luck. For example Ajax file upload in Wordpress - can\'t pass FormData

Right now I have My Ajax code like this:

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 );

My form:

 <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>

Right now this is how far I got. This is not my full form I have already added nonce and other required settings for sequrity. When I check input file It keep displaying error message that the field is empty.

My form handler

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\' );

So My question is What can I do or add in my ajax or form handler to get file upload submit with Ajax working. Any suggestion, advice or some existing example that are familiar will be appreciated. I am practicing with WordPress and Ajax that is how far I got.

I have tried to use FormData but still no luck so far.

网友观点:

Here is some tips to make work your provided form:

Form:

<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>

I removed placeholder=\\\"<?php echo $field->label ?>\\\" from your text input, because it\'s coming from custom code, which you didn\'t provide.

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);

});

});

});

NOTE: You\'re using var form_elm = jQuery(this);, which returns object of jquery with all Form content. That\'s why I used it for accessing input information. Instead you can access to form inputs with their name, class, id, placeholder and etc.

What changed:

  1. removed (function($) {} wrapper and instead used jQuery(document).ready(function ($) {});. This is just for note. There is no need to wrapp your jquery to have access to $.
  2. We\'re getting file and name from inputs with lines below:

    var file = form_elm[0][1].files[0];

    var customer_field_text = form_elm[0][0].value;

  3. We\'re adding action for WordPress and form inputs with their values into FormData:

    form_data.append(\'action\', action);

    form_data.append(\'customer-field-upload\', file);

    form_data.append(\'customer-field-name\', customer_field_text);

    Here you can change the name of array we\'re sending. For ex., we will recieve file in the array with key customer-field-upload and can use it such way:

    $_FILES[\'customer-field-upload\']

  4. async : true: this line we don\'t need. It\'s true by default. enctype: \'multipart/form-data\', we don\'t need, too.
  5. data: form_data,: we are sending everything only using one form_data variable( FormData object ).

PHP file:

  1. I didn\'t use add_action(\'wp_ajax_nopriv_form_submit1\', \'handle_form_submission\'); because there is nothing related to nonce in your provided code
  2. Your $_POST will contain:

    Array

    (

    [action] => form_submit1 //action, which we used to send and accept Ajax request

    [customer-field-name] => some input value in the name field

    )

    You can access to name input using $_POST[\'customer-field-name\'].

  3. Your $_FILES will contain:

    Array

    (

    [customer-field-upload] => Array

    (

    [name] => input file name

    [type] => input file type

    [tmp_name] => temp file

    [error] => 0

    [size] => some size

    )

    )

    You can work with input file using $_FILES[\'customer-field-upload\']


EDIT: Appended functional to add all inputs with several lines of code:

Form:

<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);

});

});

});

Here we used Jquery iterator to add several values from the loop into the FormData object. This is example and can be applied for checkboxes, textareas and etc.

###

You are missing enctype: \'multipart/form-data\' and contentType: false to prevent jQuery from setting it to string. If that doesn\'t work, see this example and follow the same method

   jQuery.ajax({

type : \'POST\',

enctype: \'multipart/form-data\',

url : url,

data : data,

async : true,

processData: false,

contentType: false,

})

###

Your Jquery is missing the

enctype: \'multipart/form-data\'

This is quite important when you are submitting the forms. This allows the form data to be sent without any conversions.

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);

});

});

标签:

提交需求或反馈

Demand feedback