web-dev-qa-db-fra.com

Formulaire Wordpress personnalisé + PHP + MYSQL + AJAX, événement de soumission non capturé par Javascript, mais POST données vers la base de données

Je construis un petit formulaire pour permettre aux utilisateurs de mettre à jour leurs informations de contact en dehors des systèmes de gestion d’utilisateurs Vanilla Wordpress. Je prévois d’utiliser une configuration simple CRUD et de jeter un peu d’assainissement. J'ai la fonction initiale d'insertion/création construite à l'aide des fonctions $ wpdb et le formulaire écrit correctement dans la base de données. Cependant, mon code Javascript ne s'appelle pas lorsque je soumets mon formulaire. Le fichier Javascript ne capture pas l'événement submit et le formulaire ne fait que soumettre les données directement au fichier de processeur PHP. Je me gratte la tête ici.

Résumé du problème, play-by-play: 1. Le formulaire est envoyé, mais l'utilisateur est redirigé vers une page contenant les données codées JSON dans un tableau. 2. Le fichier Javascript contenant le traitement de mes erreurs et les appels Ajax n'est jamais touché. 3. Le fichier Javascript ne capture pas l'événement submit. 4. Le formulaire est toujours écrit dans la base de données, je suppose, car la méthode POST est appelée sur le fichier PHP dans l'action de formulaire.

NOTE: J'inclus le fichier .js à l'aide de wp_enqueue_script dans mon fichier de fonctions, mais le modifierai probablement pour ne l'inclure que lorsque la page contenant ce formulaire est chargée, afin de réduire les temps de chargement. Je ne pense pas que le chargement du fichier javascript de cette façon puisse changer quoi que ce soit.

Traitement PHP:

<?php
# DB CRUD commands for updating the table for alumni contact info
/* wordpress db globals, require wp-load to bring in useful functions */
$parse_uri = explode( 'wp-content', $_SERVER['SCRIPT_FILENAME'] );
require_once( $parse_uri[0] . 'wp-load.php' );
global $wpdb;

$errors         = array();      // array to hold validation errors
$data           = array();      // array to pass back data

/*Ensure no fields are empty, and if they are, return $errors array encoded in JSON */
    if (empty($_POST['first_name']))
        $errors['first_name'] = 'First name is required.';

        if (empty($_POST['last_name']))
        $errors['last_name'] = 'Last name is required.';

    if (empty($_POST['email']))
        $errors['email'] = 'Email is required.';

    if (empty($_POST['phone']))
        $errors['phone'] = 'A phone number is required.';

    if (empty($_POST['address']))
        $errors['address'] = 'A mailing address is required.';

    if (empty($_POST['city']))
        $errors['city'] = 'Please enter the city for your mailing address.';

    if (empty($_POST['Zip']))
        $errors['Zip'] = 'Your Zip code is required.';  

    if (empty($_POST['state']))
        $errors['state'] = 'Please select your state.';

// return a response ===========================================================

    // if there are any errors in our errors array, return a success boolean of false
    if ( ! empty($errors)) {

        // if there are items in our errors array, return those errors
        $data['success'] = false;
        $data['errors']  = $errors;
    } else {

        // if there are no errors process our form, then return a message

            /* Set the proper table name to a variable */
                        $table_name = "wp_alumni"; 
                        /* Use insert function to write the data to the table 
                        * Called on form submit when the user adds their contact info
                        * to the Alumni database using the on-page form.
                        * button name = submit is used to check 'if isset' 
                        * and then perform the update function
                        */
                        if (isset($_POST['create'])) {
                                $wpdb->insert(
                                    $table_name, array(
                                        'first_name'    => $_POST['first_name'],
                                        'last_name' => $_POST['last_name'],
                                        'address'   => $_POST['address'],
                                        'address2' => $_POST['address2'],
                                        'city'  => $_POST['city'],
                                        'state' => $_POST['state'],
                                        'Zip'   => $_POST['Zip'],
                                        'phone' => $_POST['phone'],
                                        'email' => $_POST['email'],
                                        'time' => current_time('mysql', 1)
                                        )
                                    );
                            }

        // show a message of success and provide a true success variable
        $data['success'] = true;
        $data['message'] = 'Success!';
    }

    // return all our data to an AJAX call
    echo json_encode($data);
?>

Le formulaire/HTML:

<form method="POST" action="<?php echo plugins_url( 'alumni/alumni_update.php' ); ?>" name="alumni-update" id="alumni-update">
    <div id="alumni-form-column">
        <li>
        <span class="alumni-span">First Name</span><br />
            <input id="first_name" type="text" name="first_name" class="alumni-input" />
        </li>
        <li>
        <span class="alumni-span"> Last Name</span><br />
            <input id="last_name" type="text" name="last_name" class="alumni-input" />
        </li>
        <li>
        <span class="alumni-span">Street Address</span><br />
            <input id="address" type="text" name="address" class="alumni-input" />
        </li>
            <li>
        <span class="alumni-span">Apt, Unit, Ste #, etc</span><br />
            <input id="address2" type="text" name="address2" class="alumni-address-2" cols="1" />
        </li>
    </div>
    <div id="alumni-form-column">
        <li>
        <span class="alumni-span">City</span><br />
            <input id="city" type="text" name="city" class="alumni-input" />
        </li>
        <li>
        <span class="alumni-span">State</span><br />
                <select id="state" type="text" name="state" class="alumni-input">
                    <option value="AL">Alabama</option>
                    <option value="AK">Alaska</option>
                    <option value="AZ">Arizona</option>
                    <option value="AR">Arkansas</option>
                    <option value="CA">California</option>
                    <option value="CO">Colorado</option>
                    <option value="CT">Connecticut</option>
                    <option value="DE">Delaware</option>
                    <option value="DC">District Of Columbia</option>
                    <option value="FL">Florida</option>
                    <option value="GA">Georgia</option>
                    <option value="HI">Hawaii</option>
                    <option value="ID">Idaho</option>
                    <option value="IL">Illinois</option>
                    <option value="IN">Indiana</option>
                    <option value="IA">Iowa</option>
                    <option value="KS">Kansas</option>
                    <option value="KY">Kentucky</option>
                    <option value="LA">Louisiana</option>
                    <option value="ME">Maine</option>
                    <option value="MD">Maryland</option>
                    <option value="MA">Massachusetts</option>
                    <option value="MI">Michigan</option>
                    <option value="MN">Minnesota</option>
                    <option value="MS">Mississippi</option>
                    <option value="MO">Missouri</option>
                    <option value="MT">Montana</option>
                    <option value="NE">Nebraska</option>
                    <option value="NV">Nevada</option>
                    <option value="NH">New Hampshire</option>
                    <option value="NJ">New Jersey</option>
                    <option value="NM">New Mexico</option>
                    <option value="NY">New York</option>
                    <option value="NC">North Carolina</option>
                    <option value="ND">North Dakota</option>
                    <option value="OH">Ohio</option>
                    <option value="OK">Oklahoma</option>
                    <option value="OR">Oregon</option>
                    <option value="PA">Pennsylvania</option>
                    <option value="RI">Rhode Island</option>
                    <option value="SC">South Carolina</option>
                    <option value="SD">South Dakota</option>
                    <option value="TN">Tennessee</option>
                    <option value="TX">Texas</option>
                    <option value="UT">Utah</option>
                    <option value="VT">Vermont</option>
                    <option value="VA">Virginia</option>
                    <option value="WA">Washington</option>
                    <option value="WV">West Virginia</option>
                    <option value="WI">Wisconsin</option>
                    <option value="WY">Wyoming</option>
                </select>   
        </li>
        <li>
        <span class="alumni-span">Zip</span><br />
            <input id="Zip" type="text" name="Zip" class="alumni-input" maxlength="5" />
        </li>
        <li>
        <span class="alumni-span">Phone</span><br />
            <input id="phone" type="text" name="phone" class="alumni-input" maxlength="10" onfocus="if (this.value == 'Hint text..') this.value=''" value="Hint text.." onblur="if (this.value == '') this.value='Digits only: 5458881234'"/>
        </li>
        <li>
        <span class="alumni-span">Email</span><br />
            <input id="email" type="text" name="email" class="alumni-input" />
        </li>
    <li>    
        <button class="alumni-button" type="submit" name="create">Submit</button>
    </li>
        </div>
</form>

Javascript

// .js document to capture the Submit event from the form and send back errors asychronously
$(document).ready(function() {
    // process the form
    $('form').submit(function(event) {
            event.preventDefault();
            $('.form-group').removeClass('has-error'); // remove the error class
            $('.help-block').remove(); // remove the error text
        // get the form data
        // there are many ways to get this data using jQuery (you can use the class or id also)
        var formData = {
            'email'             : $('input[name=email]').val(),
            'address'              : $('input[name=address]').val(),
            'phone'             : $('input[name=phone]').val(),
            'city'              : $('input[name=city]').val(),
            'state'             : $('input[name=state]').val(),
            'first_name'              : $('input[name=first_name]').val(),
            'last_name'             : $('input[name=last_name').val(),
            'Zip'              : $('input[name=Zip]').val()         
        };

        // process the form
        $.ajax({
            type        : 'POST', // define the type of HTTP verb we want to use (POST for our form)
            url         : 'http://localhost/wordpress/wp-content/plugins/alumni/alumni_update.php', // the url where we want to POST
            data        : formData, // our data object
            dataType    : 'json', // what type of data do we expect back from the server
            encode          : true
        })
            // using the done promise callback
            .done(function(data) {

                // log data to the console so we can see
                console.log(data); 

                // here we will handle errors and validation messages
                if ( ! data.success) {

            // handle errors for fist name ---------------
            if (data.errors.first_name) {
                $('#first_name').addClass('has-error'); // add the error class to show red input
                $('#first_name').append('<div class="help-block">' + data.errors.first_name + '</div>'); // add the actual error message under our input
            }

            // handle errors for last name ---------------
            if (data.errors.last_name) {
                $('#last_name').addClass('has-error'); // add the error class to show red input
                $('#last_name').append('<div class="help-block">' + data.errors.last_name + '</div>'); // add the actual error message under our input
            }

            // handle errors for city---------------
            if (data.errors.city) {
                $('#city').addClass('has-error'); // add the error class to show red input
                $('#city').append('<div class="help-block">' + data.errors.city + '</div>'); // add the actual error message under our input
            }

            // handle errors for last name ---------------
            if (data.errors.state) {
                $('#state').addClass('has-error'); // add the error class to show red input
                $('#state').append('<div class="help-block">' + data.errors.state + '</div>'); // add the actual error message under our input
            }

            // handle errors for phone ---------------
            if (data.errors.phone) {
                $('#phone').addClass('has-error'); // add the error class to show red input
                $('#phone').append('<div class="help-block">' + data.errors.phone + '</div>'); // add the actual error message under our input
            }

            // handle errors for address ---------------
            if (data.errors.address) {
                $('#address').addClass('has-error'); // add the error class to show red input
                $('#address').append('<div class="help-block">' + data.errors.address + '</div>'); // add the actual error message under our input
            }

            // handle errors for Zip ---------------
            if (data.errors.Zip) {
                $('#Zip').addClass('has-error'); // add the error class to show red input
                $('#Zip').append('<div class="help-block">' + data.errors.Zip + '</div>'); // add the actual error message under our input
            }

            // handle errors for email ---------------
            if (data.errors.email) {
                $('#email').addClass('has-error'); // add the error class to show red input
                $('#email').append('<div class="help-block">' + data.errors.email + '</div>'); // add the actual error message under our input
            }

        } else {

            // ALL GOOD! just show the success message!
            $('form').append('<div class="alert alert-success">' + data.message + '</div>');

            // usually after form submission, you'll want to redirect
            // window.location = '/thank-you'; // redirect a user to another page
            alert('success'); // for now we'll just alert the user

        }
    });

        // stop the form from submitting the normal way and refreshing the page
        event.preventDefault();
    });

});
2
Jordan J.

Si vous publiez ceci en tant que plugin, vous devez absolument utiliser utiliser l'API AJAX. C'est super facile:

/**
 * Handle the request and return the result.
 */
function alumni_process_request() {
    global $wpdb;

    // All your processing code from your original question, except for loading WordPress!

    return $data;
}

/**
 * AJAX handler for the "alumni" action.
 */
function alumni_ajax_handler() {
    global $wpdb;

    $data = alumni_process_request();

    header( 'Content-Type: application/json; charset=' . get_bloginfo( 'charset' ) );
    echo json_encode( $data );
    exit;
}

add_action( 'wp_ajax_nopriv_alumni', 'alumni_ajax_handler' );
add_action( 'wp_ajax_alumni',        'alumni_ajax_handler' );

C'est la base. Maintenant, nous devons nous assurer que nous chargeons correctement notre code JavaScript, que jQuery est chargé et qu'une variable JavaScript globale contient l'URL du gestionnaire WordPress AJAX:

function alumni_enqueue_script() {
    wp_enqueue_script(
        'alumni',
        plugins_url( 'path/to/script.js', __FILE__ ), // URL path relative to the folder of the PHP script this code is placed in 
        array( 'jquery' ) // Requires jQuery, make sure it's loaded first
    );

    wp_localize_script(
        'alumni', // Name of script, from above
        'alumni', // Name of JavaScript variable
        array(
            'ajaxUrl' => admin_url( 'admin-ajax.php' ),
        )
    );
}

add_action( 'wp_enqueue_scripts', 'alumni_enqueue_script' );

Et maintenant pour le JavaScript:

!function( $ ) { // Self-executing function closure, will ensure $ is jQuery - might be running in noConflict mode

    $( document ).ready(
        function() {
            $( "#alumni-update" ).submit( // Don't bind to all forms, just ours
                function ( event ) {
                    event.preventDefault();

                    $('.form-group').removeClass('has-error'); // remove the error class
                    $('.help-block').remove(); // remove the error text

                    var data = $( this ).serializeArray(); // Will automatically grab all form fields and data

                    data.Push({
                        name : "create",
                        value: "1"                      
                    });

                    data.Push({
                        name : "action",
                        value: "alumni" // This parameter needs to match the wp_ajax_* hook.                        
                    });

                    $.post(
                        alumni.ajaxUrl, // Use our JavaScript variable "alumni" we defined in wp_localize_script()
                        data, // POST data
                        function ( data ) {
                            // Your form handling
                        }                   
                    );

                }
            )
        }
    );

}( jQuery );

Ce qui précède suppose une structure de plugin semblable à celle-ci:

plugin-folder/plugin.php
 - PHP code
plugin-folder/path/to/script.js
 - JavaScript
2
TheDeadMedic