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.

2
  • 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? Mar 23, 2017 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, 2017 at 21:44

2 Answers 2

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?

1
  • 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. Mar 26, 2017 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()

1
  • 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. Mar 26, 2017 at 23:40

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.