使用Ajax提交文件上传的WordPress表单
问题描述:
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
(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:
1 2 3 4 5 6 7 8 9 10 11 |
<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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
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:
1 2 3 4 5 6 7 8 9 10 |
<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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
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:
- removed
(function($) {}
wrapper and instead usedjQuery(document).ready(function ($) {});
. This is just for note. There is no need to wrapp your jquery to have access to$
. -
We\'re getting file and name from inputs with lines below:
123var file = form_elm[0][1].files[0];var customer_field_text = form_elm[0][0].value; -
We\'re adding
action
for WordPress and form inputs with their values intoFormData
:1234form_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:12$_FILES[\'customer-field-upload\'] -
async : true
: this line we don\'t need. It\'s true by default.enctype: \'multipart/form-data\',
we don\'t need, too. -
data: form_data,
: we are sending everything only using oneform_data
variable(FormData
object ).
PHP file:
- I didn\'t use
add_action(\'wp_ajax_nopriv_form_submit1\', \'handle_form_submission\');
because there is nothing related tononce
in your provided code -
Your
$_POST
will contain:123456Array([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\']
. -
Your
$_FILES
will contain:12345678910111213Array([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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
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
1 2 3 4 5 6 7 8 9 10 |
jQuery.ajax({ type : \'POST\', enctype: \'multipart/form-data\', url : url, data : data, async : true, processData: false, contentType: false, }) |
###
Your Jquery is missing the
1 2 |
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
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); }); }); |
1. 带 [亲测] 说明源码已经被站长亲测过!
2. 下载后的源码请在24小时内删除,仅供学习用途!
3. 分享目的仅供大家学习和交流,请不要用于商业用途!
4. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
5. 本站所有资源来源于站长上传和网络,如有侵权请邮件联系站长!
6. 没带 [亲测] 代表站长时间紧促,站长会保持每天更新 [亲测] 源码 !
7. 盗版ripro用户购买ripro美化无担保,若设置不成功/不生效我们不支持退款!
8. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
9. 如果你也有好源码或者教程,可以到审核区发布,分享有金币奖励和额外收入!
10.如果您购买了某个产品,而我们还没来得及更新,请联系站长或留言催更,谢谢理解 !
GG资源网 » 使用Ajax提交文件上传的WordPress表单