0

I've tried and tried and tried, I've searched and searched... I can't figure out why this isn't working. One huge problem is I can't seem to figure out how to get any good debug info about why this is failing.

Anyway, I have a search field to lookup libraries from CDNJS.com (which works). Upon selection of a result, I am wanting to add that library data to a custom Wordpress table. That process is failing, no matter what I try.

Here's the code:

<?php

    function cdnjs_add_library_callback() {
        // Get the library data from the POST request
        $library = json_decode(file_get_contents('php://input'), true);

        // Insert the library into the "cdnjs_libraries" table
        global $wpdb;
        $table_name = $wpdb->prefix . 'cdnjs_libraries';
        $wpdb->insert(
            $table_name,
            array(
                'description' => $library['description'],
                'homepage' => $library['homepage'],
                'latest' => $library['latest'],
                'license' => $library['license'],
                'name' => $library['name'],
                'version' => $library['version']
            )
        );

        // Check for errors
        if ($wpdb->last_error) {
            die("Error inserting library: " . $wpdb->last_error);
        }

        // Return a success message
        echo "Library added successfully";

        wp_die(); // this is required to terminate immediately and return a proper response
    }
    add_action( 'wp_ajax_cdnjs_add_library', 'cdnjs_add_library_callback' );

?>

    <div class="wrap">
        <h1>CDNJS Library Manager</h1>
        <p>&nbsp;</p>
        <div id="search-form">
            <form onsubmit="return false;">
                <h2><label for="library-search">Search CDNJS</label></h2>
                <input type="text" id="library-search" name="library-search" placeholder="Type to start searching..." size=30>
            </form>
        </div>
        <p>&nbsp;</p>
        <h2>Managed Libraries</h2>
        <table id="managed-libraries" class="wp-list-table widefat fixed striped">
            <thead>
                <tr>
                    <th>Action</th>
                    <th>Filename</th>
                    <th>Description</th>
                    <th>Version</th>
                    <th>License</th>
                    <th>Homepage</th>
                    <th>Delete</th>
                </tr>
            </thead>
            <tbody>
                <?php echo generate_table_rows($managed_libraries); ?>
            </tbody>
        </table>
    </div>

    <script>
    jQuery(document).ready(function($) {

        // Set up the search field as an autocomplete field
        $("#library-search").autocomplete({
            // Set the source of the autocomplete options to the CDNJS API
            source: function(request, response) {
                $.ajax({
                    data: {
                        search: request.term,
                        fields: "name,description,version,license,homepage"
                    },
                    success: function(results) {
                        console.log(results);
                        // Extract the list of library names, descriptions, and URLs from 
                        // the results and pass them to the response callback
                        var libraries = results.results.map(function(library) {
                            return {
                                label: "<b>"+library.name+"</b><br><i>"+library.description+"</i>",
                                value: library
                            };
                        });
                        response(libraries);
                    },
                    url: "https://api.cdnjs.com/libraries"
                });
            },
            minLength: 3,
            select: function(event, ui) {
                // When a library is selected from the autocomplete list,
                // add that library to the "cdnjs_libraries" table by 
                // making an AJAX POST call to the "cdnjs_add_library" PHP action

                // Get the selected library object
                var library = ui.item.value;

                // Make an AJAX call to the "cdnjs_add_library" action
                $.ajax({
                    url: ajaxurl,
                    type: 'POST',
                    dataType: 'json',
                    contentType: 'application/json; charset=utf-8',
                    data: JSON.stringify({
                        action: 'cdnjs_add_library',
                        library: library
                    }),
                    success: function(response) {
                        console.log(response);
                        // Add the library to the table of managed libraries
                        $("#managed-libraries tbody").append(generateTableRow(library));
                    },
                    error: function(error) {
                        console.log(error);
                    }
                });
            }
        }).autocomplete( "instance" )._renderItem = function( ul, library ) {
            // Customize the display of the autocomplete options
            // Create a new list item for the library
            var listItem = $("<li>");
            // Create a link for the library
            var libraryLink = $("<a>", {
                href: library.url,
                target: "_blank",
                html: library.label
            });
            // Append the link to the list item
            listItem.append(libraryLink);
            // Return the list item
            return listItem.appendTo(ul);
        };


    });
    </script>
4
  • Your AJAX request is posting data as JSON. That’s not supported. No WordPress AJAX tutorials or documentation will show admin-ajax.php being used with JSON like this. Commented Jan 8, 2023 at 7:47
  • All I'm trying to do I push a JS array into a custom Wordpress table (in a WP Admin-side plug-in). I've found a bunch of info on pushing JSON data to admin-ajax.php... it's just that it doesn't seem to work (maybe that should be obvious, based on your comment). So, should I be able to do what I'm wanting to do with my posted code... by setting the dataType & contentType parameters to a different value? I thought admin-ajax.php was just the mechanism to expose custom PHP actions, at which point I could send whatever type of data to be further processed/handled on the PHP/server side.
    – Dustin
    Commented Jan 8, 2023 at 18:27
  • Is this tutorial not using jquery.ajax to send json data via the admin-ajax.php file… with the action parameter being the name of a custom Wordpress function? wpmudev.com/blog/using-ajax-with-wordpress
    – Dustin
    Commented Jan 9, 2023 at 4:18
  • It is, but you’re not. Because you’ve used JSON.stringify you’re not sending an action parameter, you’re sending a JSON string with an action property in it. WordPress checks $_REQUEST['action'] to run the correct PHP but this is not populated by JSON. Commented Jan 9, 2023 at 4:24

1 Answer 1

0

To elaborate on my comments, your issue is here:

contentType: 'application/json; charset=utf-8',
data: JSON.stringify({
    action: 'cdnjs_add_library',
    library: library
}),

When sending data to admin-ajax.php you need to set the action property of data to the action name, eg. cdnjs_add_library. That's not what you're doing here. data is not an object with an action property, as is expected, it's a string containing JSON that happens to include an action property. These are not the same thing.

In the source of admin-ajax.php you'll see this:

$action = $_REQUEST['action'];

If you post JSON to admin-ajax.php $_REQUEST will not have an action property, for reasons I explain here. This means that your action will not be fired and your PHP code will not run.

The solution is to remove contentType and pass the data like so:

data: {
    action: 'cdnjs_add_library',
    library: library
},

Your cdnjs_add_library_callback() function will then need to set $libary like this:

$library = $_POST['library'];
1
  • I was able to figure out the changes needed based on your earlier brief comments... as it was also pretty much how I had it coded before making 100 changes while troubleshooting. I then spent then next 5 hours trying to figure out why it still wasn't working... until I finally figured out that my hooks weren't available. :( Certainly would have been nice to have an error say "hey, man... your action 'cdnjs_add_library', hasn't been added correctly'
    – Dustin
    Commented Jan 9, 2023 at 18:08

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.