1

I'm inexperienced with ajax. I'm building a form that will allow the user to grab a custom post type from the first field that will return the value of the post ID. Then, I'd like ajax to take that post ID and build a second dropdown based on some custom fields for that post.

Here's what I have so far, which was adapted from the first answer on this question: Filter a second dropdown list when a value is chosen in the first one

In functions.php:

if ( is_admin() ) {
    add_action( 'wp_ajax_dynamic_dropdown', 'dynamic_dropdown_func' );
    add_action( 'wp_ajax_nopriv_dynamic_dropdown', 'dynamic_dropdown_func' );
}
function dynamic_dropdown_func () {
    global $wpdb;
    if (isset($_POST['event'])) {
        $event_id = $_POST['event'];
        $first = get_field('first_day',$event_id);
        $last = get_field('last_day',$event_id);
        $event_dates = '<option value="" disabled selected>Choose Date</option>';
        $event_dates .= '<option value="'.$first.'">'.$first.'</option>';
        while($first<$last) :
            $first = $first + 1;
            $event_dates .= '<option value="'.$first.'">'.$first.'</option>';
        endwhile;
    }
ob_clean();
return $event_dates;
wp_die();
}

(I'm aware the code to build the dates still needs some work to display proper dates.)

And then, in the page template:

<?php function date_chooser () {
    $ajax_url = admin_url( 'admin-ajax.php' );
    $grabDates = "
        <script>
            var ajaxUrl = '{$ajax_url}',
            dropdownEvent = jQuery('#chooseEvent'),
            dropdownDate  = jQuery('#chooseDate');
            dropdownEvent.on('change', function (e) {
                var value = e.target.selectedOptions[0].value,
                success,
                data;
                if (!!value) {
                    data = {
                        'event' : value,
                        'action' : 'dynamic_dropdown'
                    };
                    success = function ( response ) {
                        dropdownDate.html( response );
                    };
                    jQuery.post( ajaxUrl, data, success );
                }
            });
        </script>";
    return $grabDates;
}
echo date_chooser(); ?>

This code is getting me part of the way. Once the #chooseEvent dropdown has a selection, it is capture the proper post ID, and then the #chooseDate dropdown just empties itself from my placeholder but never loads anything else.

I've tried just having the dynamic_dropdown_func() just return a "Hello world!" and it doesn't do that either, so somehow I think I'm not triggering and returning the ajax function properly.

  • in your JS you've got if (!!value) { (i.e., double !). Is that just a typo when you entered your question, or is that actually in your real code? – Paul 'Sparrow Hawk' Biron Mar 23 '17 at 21:20
  • @Paul'SparrowHawk'Biron I think it's an intentional boolean coercion. I don't think it's necessary here, as (to the best of my knowledge) a <option>'s value is always a string, even when missing the value attribute and inner text - so if(value) should be sufficient. But the coercion won't hurt anything, and might catch some strange edge-case. – bosco Mar 23 '17 at 21:44
2
+50

In dynamic_dropdown_func(), at the end try echo $event_dates; instead of return $event_dates;.

Also, I'm wondering why you declare global $wpdb; when you don't seem to use it?

  • Scott -- that did it. Thanks! That global $wpdb was just leftover from the code I based it on above. Hadn't even occurred to me that I wouldn't need to to just use the get_field queries. – John Chandler Mar 26 '17 at 23:38
0

I prefer to use jQuery.ajax() over jQuery.post(), as I seem to have more control over error processing.

In your page template, do the following:

function
date_chooser ()
{
    $ajax_url = admin_url( 'admin-ajax.php' );
    $grabDates = "
    <script>
        var ajaxUrl = '{$ajax_url}',
        dropdownEvent = jQuery('#chooseEvent'),
        dropdownDate  = jQuery('#chooseDate');
        dropdownEvent.on('change', function (e) {
            var value = e.target.selectedOptions[0].value,
                success,
                data;
            if (!!value) {
                var data = {
                    action: 'dynamic_dropdown',
                    event: value
                    } ;

                jQuery.ajax ({
                    type: 'POST',
                    async: true,
                    url: ajaxUrl,
                    data: data,
                    dataType: 'JSON',
                    success: function (response) {
                        // handle ajax success
                        if (response.success) {
                            // handle success, returned with wp_send_json_success ()
                            dropdownDate.html (response.data) ;
                            }
                        else {
                            // handle errors, returned with wp_send_json_error ()
                            }
                        },
                    error: function (xhr, ajaxOptions, thrownError) {
                        // handle ajax errors
                        }
                    }) ;
                }
            });
        </script>";
    echo $grabDates;
}

In your functions.php, do the following:

add_action( 'wp_ajax_dynamic_dropdown', array ($this, 'dynamic_dropdown_func' ));
add_action( 'wp_ajax_nopriv_dynamic_dropdown', array ($this, 'dynamic_dropdown_func' ));

function
dynamic_dropdown_func ()
{
    if (!isset($_POST['event'])) {
        wp_send_json_error ('event not set') ;
        }

    $event_id = $_POST['event'];
    $first = get_field('first_day',$event_id);
    $last = get_field('last_day',$event_id);
    $event_dates = '<option value="" disabled selected>Choose Date</option>';
    $event_dates .= '<option value="'.$first.'">'.$first.'</option>';
    while($first<$last) :
        $first = $first + 1;
        $event_dates .= '<option value="'.$first.'">'.$first.'</option>';
    endwhile;

    ob_clean () ;

    wp_send_json_success ($event_dates) ;
}

Note the use of wp_send_json_success() and wp_send_json_error()

  • Tried this one. It ended up not triggering any changes to the Choose Date fields at all -- not even wiping out what I previously had in there. The response above worked, however, so I'm good to go. – John Chandler Mar 26 '17 at 23:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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