Filter second dropdown (tax) based on first dropdown (cpt)

If you want an example of how to do the dropdown filtering using ajax, then if you factor out your taxonomy dropdown into your “functions.php”:

function my_dropdown_categories( $taxonomy, $current_selected = '', $include = null ) {
    // Get all terms of the chosen taxonomy
    $terms = get_terms($taxonomy, array('orderby' => 'name'));

    // our content variable
    $list_of_terms="<select id="location" class="selectboxSingle" name="location">";

    if ( ! is_wp_error( $terms ) ) foreach($terms as $term){

        // If include array set, exclude unless in array.
        if ( is_array( $include ) && ! in_array( $term->slug, $include ) ) continue;

        $select = ($current_selected == $term->slug) ? "selected" : ""; // Note: ==

        if ($term->parent == 0 ) {

            // get children of current parent.
            $tchildren = get_term_children($term->term_id, $taxonomy);

            $children = array();
            foreach ($tchildren as $child) {
                $cterm = get_term_by( 'id', $child, $taxonomy );
                // If include array set, exclude unless in array.
                if ( is_array( $include ) && ! in_array( $cterm->slug, $include ) ) continue;
                $children[$cterm->name] = $cterm;
            }
            ksort($children);

            // OPTGROUP FOR PARENTS
            if (count($children) > 0 ) {
                 $list_of_terms .= '<optgroup label="'. $term->name .'">';
                 if ($term->count > 0)
                     $list_of_terms .= '<option value="'.$term->slug.'" '.$select.'>All '. $term->name .' </option>';
            } else
                $list_of_terms .= '<option value="'.$term->slug.'" '.$select.'>'. $term->name .' </option>';
            //$i++;

            // now the CHILDREN.
            foreach($children as $child) {
                 $select = ($current_selected == $child->slug) ? "selected" : ""; // Note: child, not cterm
                 $list_of_terms .= '<option value="'.$child->slug.'" '.$select.'>'. $child->name.' </option>';

            } //end foreach

            if (count($children) > 0 ) {
                $list_of_terms .= "</optgroup>";
            }
        }
    }

    $list_of_terms .= '</select>';

    return $list_of_terms;
}

And also in your “functions.php”, you put in the ajax handling:

add_action( 'wp_ajax_wpse158929_get_terms_for_cpt', 'wpse158929_get_terms_for_cpt' );
add_action( 'wp_ajax_nopriv_wpse158929_get_terms_for_cpt', 'wpse158929_get_terms_for_cpt' );

function wpse158929_get_terms_for_cpt() {
    $ret = array( 'html' => '', 'error' => false );

    if ( ! check_ajax_referer( 'wpse158929_get_terms_for_cpt_submit_', 'nonce', false /*die*/ ) ) {
        $ret['error'] = __( 'Permission error', 'wpfm' );
    } else {
        $post_type = isset( $_REQUEST['post_type'] ) ? $_REQUEST['post_type'] : '';
        $taxonomy = isset( $_REQUEST['taxonomy'] ) ? $_REQUEST['taxonomy'] : '';
        $current_selected = isset( $_REQUEST['current_selected'] ) ? $_REQUEST['current_selected'] : '';

        if ( ! $post_type || ! $taxonomy ) {
            $ret['error'] = __( 'Params error', 'wpfm' );
        } else {
            global $wpdb;
            $sql = $wpdb->prepare( 'SELECT t.slug FROM ' . $wpdb->terms . ' t'
                . ' JOIN ' . $wpdb->term_taxonomy . ' AS tt ON tt.term_id = t.term_id'
                . ' JOIN ' . $wpdb->term_relationships . ' AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id'
                . ' JOIN ' . $wpdb->posts . ' AS p ON p.ID = tr.object_id'
                . ' WHERE tt.taxonomy = %s AND p.post_type = %s AND p.post_status = %s'
                . ' GROUP BY t.slug'
                , $taxonomy, $post_type, 'publish' );
            $include = $wpdb->get_col($sql);
            $ret['html'] = preg_replace( '/<\/?select[^>]*>/', '', my_dropdown_categories( $taxonomy, $current_selected, $include ) );
        }
    }

    wp_send_json( $ret );
}

Then append the jquery to your main code:

<form action="<?php bloginfo('url'); ?>" method="get">

<?php 

$args = array(
'public'   => true,
'_builtin' => false
);

$output="objects"; // names or objects, note names is the default
$operator="and"; // 'and' or 'or'

$post_types = get_post_types($args, $output, $operator);

echo '<select class="selectboxSingle" name="post_type">';

foreach ( $post_types  as $post_type ) {

$exclude = array('custom_type');

if(TRUE === in_array($post_type->name,$exclude))
continue;

   // Note: I think you need to use query_var here, rather than slug.
   echo '<option value="'.$post_type->query_var.'">' . ucfirst($post_type->name) . '</option>';
}

echo "</select>";
?>

<div class="inx">in</div>

<?php 

// Set your custom taxonomy
$taxonomy = "location";

// Factored out taxonomy dropdown into function my_dropdown_categories() in "functions.php".
echo my_dropdown_categories( $taxonomy );
?>

</div>
<div class="submit-button-blanket"><button class="submit-button" type="submit">Search</button></div>
</form>
</div>
<script type="text/javascript">
jQuery(document).ready(function() {
    (function ($) {
        $('select[name="post_type"]').change(function (event) {
            $.post( <?php echo json_encode( admin_url( 'admin-ajax.php' ) ); ?>, {
                    action: 'wpse158929_get_terms_for_cpt',
                    post_type: $(this).val(),
                    taxonomy: <?php echo json_encode( $taxonomy ); ?>,
                    current_selected: $('select[name="location"]').val(),
                    nonce: <?php echo json_encode( wp_create_nonce( 'wpse158929_get_terms_for_cpt_submit_' ) ); ?>
                }, function( response ) {
                    if ( response && !response.error ) {
                        $('select[name="location"]').html(response.html);
                    }
                }, 'json'
            );
        });
        // Remove if you don't want to call change immediately.
        $('select[name="post_type"]').change();
    })(jQuery);
});
</script>

you’ll get some way to what you want.