1

I have read about more than 10 answers that recommends using action in data and adding echo and die at the end of function. But still I am getting error of bad request. If I directly open the URL "http://localhost/wpdemo/wp-admin/admin-ajax.php" in browser it returns 0.

Here is my ajax code:

jQuery(document).ready(function($) {
    $('#submit').on('click', function(e){
        e.preventDefault();
        let title = $('#title').val();
        let content = $('#content').val();
        var formData = new FormData();
        var formData = {
            image: document.getElementById('image-input').files[0],
            var1: title,
            var2: content
        };

        $.ajax({
            url: "/wpdemo/wp-admin/admin-ajax.php",
            type: 'POST',
            data: { action : 'my_ajax_handler', chosen : formData },
            processData: false,
            contentType: false,
            success: function(response) {
                console.log(response);
            }
          });
    })
});

I have added a php file to handle ajax request. Here is my PHP code.

<?php

function my_ajax_handler() {
    if (isset($_FILES['image'])){

        $post_title = $_POST['var1'];
        $image = $_FILES['image'];
        $post_content = $_POST['var2'];
    
        $new_post = array(
        'post_title' => $post_title,
        'post_content' => $post_content,
        'post_status' => 'publish',
        'post_name' => 'pending',
        );
    
        $pid = wp_insert_post($new_post);
        add_post_meta($pid, 'meta_key', true);
    
        if (!function_exists('wp_generate_attachment_metadata'))
        {
        require_once(ABSPATH . "wp-admin" . '/includes/image.php');
        require_once(ABSPATH . "wp-admin" . '/includes/file.php');
        require_once(ABSPATH . "wp-admin" . '/includes/media.php');
        }
        if ($_FILES)
        {
        foreach ($_FILES as $file => $array)
        {
            if ($_FILES[$file]['error'] !== UPLOAD_ERR_OK)
            {
            return "upload error : " . $_FILES[$file]['error'];
            }
            $attach_id = media_handle_upload( $file, $pid );
        }
        }
        if ($attach_id > 0)
        {
        //and if you want to set that image as Post then use:
        update_post_meta($pid, '_thumbnail_id', $attach_id);
        }
    }
    echo json_encode('success');
    die();
  }
  add_action("wp_ajax_my_ajax_handler", "my_ajax_handler");
  add_action("wp_ajax_nopriv_my_ajax_handler", "my_ajax_handler");
?>

My form comes from a short code I am creating in my main plugin file. My plugin file code is here.

<?php
/*
Plugin Name:  Notification Plugin Beta Version
Plugin URI:   https://www.amirsandila.com/ 
Description:  My first ever plugin n history of technology. You will love this plugin. 
Version:      1.0
Author:       Amir Sandila  
Author URI:   https://www.amirsandila.com
License:      GPL2
License URI:  https://www.gnu.org/licenses/gpl-2.0.html
Text Domain:  amirsandila
Domain Path:  /languages
*/

define("version", strtotime(date("Ymd")));

function my_theme_enqueue_scripts() {
  wp_enqueue_script( 'custom-jquery', 'https://code.jquery.com/jquery-3.5.1.min.js', array(), version, true );
  wp_enqueue_script('ajax-script', '/wp-content/plugins/wp-plugin-demo/js/script.js',array(), version, true );
  wp_localize_script( 'ajax-script','ajaxurl', admin_url( 'admin-ajax.php' ) ) ;
}
add_action( 'wp_enqueue_scripts', 'my_theme_enqueue_scripts' );



function form_shortcode_func() {
    $output = '<style>
                .form-container {
                    width: 70%;
                    margin: 0 auto;
                    border: 1px solid #ccc;
                    padding: 20px;
                }
                .form-container input[type="text"], .form-container textarea {
                    width: 100%;
                    border: 1px solid #ccc;
                    padding: 10px;
                    margin-bottom: 10px;
                }
                .form-container input[type="submit"] {
                    background-color: #333;
                    color: #fff;
                    border: 0;
                    padding: 10px 20px;
                    cursor: pointer;
                }
                </style>
                <h2> Sumit Your Article! </h2>
                <div class="form-container">
                <form method="POST" enctype="multipart/form-data">
                    <input type="text" id="title" name="title" placeholder="Post Title">
                    <textarea name="message" id="content" rows="20" cols="30" placeholder="Post Body"></textarea>
                    <input type="file" id="image-input" name="image">
                    <button id="submit"> submit </button>
                </form>
                </div>';
    return $output;
}

add_shortcode('form', 'form_shortcode_func');
3
  • Where did you place the my_ajax_handler() function code. Commented Dec 27, 2022 at 7:16
  • my_ajax_handler() function is in a separate php file. Commented Dec 27, 2022 at 7:22
  • A separate file that is included or required by your plugin? Shouldn’t the URL you’re testing have ?action=my_ajax_handler ?
    – Rup
    Commented Dec 27, 2022 at 10:59

1 Answer 1

0

Avoid using ajax URLs like this when working with ajax calls. Using wp_localize_script is a good way to accomplish this.

Let's assume your js code is in the script.js file. You need to localize that file.

function my_theme_enqueue_scripts() {
    wp_enqueue_script( 'custom-jquery', 'https://code.jquery.com/jquery-3.5.1.min.js', array(), '1.0', true );
    wp_enqueue_script( 'ajax-script', plugin_dir_url( __FILE__ ) . 'js/script.js', array( 'jquery' ), '1.0', true );
    wp_localize_script( 'ajax-script', 'Obj', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
}
add_action( 'wp_enqueue_scripts', 'my_theme_enqueue_scripts' );

JS file:

jQuery(document).ready(function ($) {
  $("#submit").on("click", function (e) {
    e.preventDefault();
    let ajax_url = Obj.ajax_url;        //Ajax url
    let title = $("#title").val();
    let content = $("#content").val();
    var data = new FormData($('#postform')[0]);
    data.append( "image", $('#input-image')[0].files[0]);
    data.append( "action", 'my_ajax_handler');
    data.append( "title", $('#title').val());
    data.append( "content", $('#content').val());;

    $.ajax({
      url: ajax_url,
      type: "POST",
      data: data,
      success: function (response) {
        console.log(response);
      },
    });
  });
});

Ajax callback function:

function my_ajax_handler() {
    if ( isset( $_FILES['image'] ) ) {

        $post_title   = $_POST['title'];
        $image        = $_FILES['image'];
        $post_content = $_POST['content'];
        
        $new_post = array(
            'post_title'   => $post_title,
            'post_content' => $post_content,
            'post_status'  => 'publish',
            'post_name'    => 'pending',
        );

        $pid = wp_insert_post( $new_post );
        add_post_meta( $pid, 'meta_key', true );

        if ( ! function_exists( 'wp_generate_attachment_metadata' ) ) {
            require_once ABSPATH . 'wp-admin' . '/includes/image.php';
            require_once ABSPATH . 'wp-admin' . '/includes/file.php';
            require_once ABSPATH . 'wp-admin' . '/includes/media.php';
        }
        if ( $_FILES ) {
            foreach ( $_FILES as $file => $array ) {
                if ( $_FILES[ $file ]['error'] !== UPLOAD_ERR_OK ) {
                    return 'upload error : ' . $_FILES[ $file ]['error'];
                }
                $attach_id = media_handle_upload( $file, $pid );
            }
        }
        if ( $attach_id > 0 ) {
            // and if you want to set that image as Post then use:
            update_post_meta( $pid, '_thumbnail_id', $attach_id );
        }
    }
    echo json_encode( 'success' );
    die();
}
add_action( 'wp_ajax_my_ajax_handler', 'my_ajax_handler' );
add_action( 'wp_ajax_nopriv_my_ajax_handler', 'my_ajax_handler' );

It is working for me. I would like to know if it works for you, and make sure you have included PHP file of ajax request in your main plugin file where you have enqueued JS file.

1
  • I edited the answer and it works perfectly. Please explain about constructor of FormData object. How it works? Commented Dec 28, 2022 at 6:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.