0

I have 4 custom taxonomies that are associated with a custom post type "procedure": "vehicle_year", "make", "model", "axel_type". I've built a dropdown that is dynamically populated based on the selection in the select field above it. The goal is that as you select a term for each subsequent taxonomy, the form will redirect to an archive page only showing posts that have each selected term.

My vehicle selection form For example, if I make the selections below, I should only see listings for a 1998 Acura CL FWD.

vehicle_year: 1998

make: Acura

model: CL

axel_type: FWD

What I have below allows this kind of functionality, but it only pulls terms based on the previous selection. Choosing a year works in that it only shows makes associated to posts with the selected year. Choosing a make then creates problems as the models that are displayed are from all posts with the selected make regardless of year.

For example, here is my data set:

vehicle_years: 1998, 1999, 2000 make: Acura model: CL, CSX, EL axel_type: FWD, AWD

If I choose 1998, Acura shows up. Perfect! If I select Acura, then "CL" and "EL" should pop up in the next field, but instead "CL", "EL", and "CSX" appear - there is no 1998 Acura CSX in my database.

The same obviously applies to the axel_type field.

This is the specific code I most want help with, but all of it is below...

$query = "
    SELECT DISTINCT $wpdb->terms.name, $wpdb->terms.slug
    FROM $wpdb->terms
    INNER JOIN $wpdb->term_taxonomy ON $wpdb->terms.term_id=$wpdb->term_taxonomy.term_id
    INNER JOIN $wpdb->term_relationships ON $wpdb->term_relationships.term_taxonomy_id=$wpdb->term_taxonomy.term_taxonomy_id
    LEFT JOIN $wpdb->posts ON $wpdb->posts.ID=$wpdb->term_relationships.object_id
    WHERE $wpdb->term_taxonomy.taxonomy='make' AND $wpdb->posts.ID IN (
    SELECT $wpdb->posts.ID
    FROM $wpdb->terms
    INNER JOIN $wpdb->term_taxonomy ON $wpdb->terms.term_id=$wpdb->term_taxonomy.term_id
    INNER JOIN $wpdb->term_relationships ON $wpdb->term_relationships.term_taxonomy_id=$wpdb->term_taxonomy.term_taxonomy_id
    LEFT JOIN $wpdb->posts ON $wpdb->posts.ID=$wpdb->term_relationships.object_id
    WHERE $wpdb->term_taxonomy.taxonomy='vehicle_year' AND $wpdb->terms.slug='$veh_year_term')";

Here's my full code (much of which is pulled from "Dropdown: Display terms from B only if has relationship with a term A selected").

WHAT AM I DOING WRONG? :(

Here's my original function to build the form.

<form action="/search" role="search" method="get" id="mysearchul" onsubmit="searchFormSubmit(); return false;">
    <?php // YEAR dropdown
        $term_selected_veh_year = get_terms('vehicle_year');
        echo '<label for="veh_year" class="required">Year</label>';
        echo '<select id="veh_year" name="veh_year" required>';
        echo '<option disabled="disabled" selected="selected">Please select a year...</option>';
        foreach ($term_selected_veh_year as $term) {
            echo '<option id=' . $term->term_id . ' value=' . $term->slug . '>' . $term->name . '</option>';
        }
        echo '</select>';

    ?>

    <!-- MAKE Dropdown -->
    <label for='veh_make' class="required">Make</label>
    <select name="veh_make" id="veh_make" disabled required>
        <option> </option>
    </select>

    <!-- MODEL Dropdown -->
    <label for='veh_model' class="required">Model</label>
    <select name="veh_model" id="veh_model" disabled required>
        <option> </option>
    </select>

    <!-- AXEL TYPE Dropdown -->
    <label for='veh_axel_type'>Drive Train</label>
    <select name="veh_axel_type" id="veh_axel_type" disabled>
        <option> </option>
    </select>

    <input type="submit" value="Search" id="searchsubmit" disabled />

    <span class="fa-stack fa-2x searchsubmit-success m-page scene_element scene_element--fadeinup">
        <i class="fa fa-circle-o-notch fa-spin fa-stack-2x" style="color: #114d82"></i>
        <i class="fab fa-check"></i>
    </span>
</form>

Here my javascript to dynamically build and populate the form.

jQuery('#veh_year').change(function(){
    jQuery('#veh_make').css('background', '#ddd url("/wp-content/themes/memberlite-child/ajax-loader.gif") no-repeat center center');
    var veh_year=jQuery('#veh_year').val();
    jQuery.ajax({
        url:"/wp-admin/admin-ajax.php",
        type:'POST',
        data:'action=year_select_action&name=' + veh_year,
        success:function(results){
            jQuery("#veh_make").html(results);
        },
        complete: function(results) {
            jQuery('#veh_make').removeAttr('disabled');
            jQuery('#veh_make').css('background', '#ddd');
            jQuery('#veh_model').html('<option value=""></option>').attr('disabled', 'disabled');
            jQuery('#veh_model').css("background", "#f9f9f9");
            jQuery('#veh_axel_type').html('<option value=""></option>').attr('disabled', 'disabled');
            jQuery('#veh_axel_type').css("background", "#f9f9f9");
        }
     });
});
jQuery('#veh_make').change(function(){
    jQuery('#veh_model').css('background', '#ddd url("/wp-content/themes/memberlite-child/ajax-loader.gif") no-repeat center center');
    var veh_make=jQuery('#veh_make').val();
    jQuery.ajax({
        url:"/wp-admin/admin-ajax.php",
        type:'POST',
        data:'action=make_select_action&name=' + veh_make,
        success:function(results){
            jQuery("#veh_model").html(results);
        },
        complete: function(results) {
            jQuery('#veh_model').removeAttr('disabled');
            jQuery('#veh_model').css('background', '#ddd');
            jQuery('#veh_axel_type').html('<option value=""></option>').attr('disabled', 'disabled');
            jQuery('#veh_axel_type').css("background", "#f9f9f9");
        }
     });
});
jQuery('#veh_model').change(function(){
    jQuery('#veh_axel_type').css('background', '#ddd url("/wp-content/themes/memberlite-child/ajax-loader.gif") no-repeat center center');
    var veh_model=jQuery('#veh_model').val();
    jQuery.ajax({
        url:"/wp-admin/admin-ajax.php",
        type:'POST',
        data:'action=model_select_action&name=' + veh_model,
        success:function(results){
            jQuery("#veh_axel_type").html(results);
        },
        complete: function(results) {
            jQuery('#veh_axel_type').removeAttr('disabled');
            jQuery('#searchsubmit').removeAttr('disabled');
            jQuery('#veh_axel_type').css('background', '#ddd');
        }
     });
});

Here's my functions.php file with ajax functions.

function implement_year_ajax() {
    // Populates the second dropdown with cuisine terms
    global $wpdb;
    $veh_year_term = $_POST['name'];
    $query = "
        SELECT DISTINCT $wpdb->terms.name, $wpdb->terms.slug
        FROM $wpdb->terms
        INNER JOIN $wpdb->term_taxonomy ON $wpdb->terms.term_id=$wpdb->term_taxonomy.term_id
        INNER JOIN $wpdb->term_relationships ON $wpdb->term_relationships.term_taxonomy_id=$wpdb->term_taxonomy.term_taxonomy_id
        LEFT JOIN $wpdb->posts ON $wpdb->posts.ID=$wpdb->term_relationships.object_id
        WHERE $wpdb->term_taxonomy.taxonomy='make' AND $wpdb->posts.ID IN (
        SELECT $wpdb->posts.ID
        FROM $wpdb->terms
        INNER JOIN $wpdb->term_taxonomy ON $wpdb->terms.term_id=$wpdb->term_taxonomy.term_id
        INNER JOIN $wpdb->term_relationships ON $wpdb->term_relationships.term_taxonomy_id=$wpdb->term_taxonomy.term_taxonomy_id
        LEFT JOIN $wpdb->posts ON $wpdb->posts.ID=$wpdb->term_relationships.object_id
        WHERE $wpdb->term_taxonomy.taxonomy='vehicle_year' AND $wpdb->terms.slug='$veh_year_term')";

    $object = $wpdb->get_results($query);
    $cuisine_terms = array();
    for ($i = 0; $i < count($object); $i++) {
        $cuisine_terms[] = get_object_vars($object[$i]);
    }

    echo '<select id="veh_make">' . '<option disabled="disabled" selected="selected">Please choose a make...</option>';
    foreach ($cuisine_terms as $term) {
        echo '<option value=' . $term['slug'] . '>' . $term['name'] . '</option>';
    }
    echo '</select>';
}

add_action('wp_ajax_year_select_action', 'implement_year_ajax');
add_action('wp_ajax_nopriv_year_select_action', 'implement_year_ajax');

function implement_make_ajax() {
    // Populates the second dropdown with cuisine terms
    global $wpdb;
    $veh_make_term = $_POST['name'];
    $query = "
        SELECT DISTINCT $wpdb->terms.name, $wpdb->terms.slug
        FROM $wpdb->terms
        INNER JOIN $wpdb->term_taxonomy ON $wpdb->terms.term_id=$wpdb->term_taxonomy.term_id
        INNER JOIN $wpdb->term_relationships ON $wpdb->term_relationships.term_taxonomy_id=$wpdb->term_taxonomy.term_taxonomy_id
        LEFT JOIN $wpdb->posts ON $wpdb->posts.ID=$wpdb->term_relationships.object_id
        WHERE $wpdb->term_taxonomy.taxonomy='model' AND $wpdb->posts.ID IN (
        SELECT $wpdb->posts.ID
        FROM $wpdb->terms
        INNER JOIN $wpdb->term_taxonomy ON $wpdb->terms.term_id=$wpdb->term_taxonomy.term_id
        INNER JOIN $wpdb->term_relationships ON $wpdb->term_relationships.term_taxonomy_id=$wpdb->term_taxonomy.term_taxonomy_id
        LEFT JOIN $wpdb->posts ON $wpdb->posts.ID=$wpdb->term_relationships.object_id
        WHERE $wpdb->term_taxonomy.taxonomy='make' AND $wpdb->terms.slug='$veh_make_term' AND $wpdb->term_taxonomy.taxonomy='vehicle_year' AND $wpdb->terms.slug='1998')";

    $object = $wpdb->get_results($query);
    $cuisine_terms = array();
    for ($i = 0; $i < count($object); $i++) {
        $cuisine_terms[] = get_object_vars($object[$i]);
    }

    echo '<select id="veh_model">' . '<option disabled="disabled" selected="selected">Please choose a model...</option>';
    foreach ($cuisine_terms as $term) {
        echo '<option value=' . $term['slug'] . '>' . $term['name'] . '</option>';
    }
    echo '</select>';
}

add_action('wp_ajax_make_select_action', 'implement_make_ajax');
add_action('wp_ajax_nopriv_make_select_action', 'implement_make_ajax');

function implement_model_ajax() {
    // Populates the second dropdown with cuisine terms
    global $wpdb;
    $veh_model_term = $_POST['name'];
    $query = "
        SELECT DISTINCT $wpdb->terms.name, $wpdb->terms.slug
        FROM $wpdb->terms
        INNER JOIN $wpdb->term_taxonomy ON $wpdb->terms.term_id=$wpdb->term_taxonomy.term_id
        INNER JOIN $wpdb->term_relationships ON $wpdb->term_relationships.term_taxonomy_id=$wpdb->term_taxonomy.term_taxonomy_id
        LEFT JOIN $wpdb->posts ON $wpdb->posts.ID=$wpdb->term_relationships.object_id
        WHERE $wpdb->term_taxonomy.taxonomy='axel_type' AND $wpdb->posts.ID IN (
        SELECT $wpdb->posts.ID
        FROM $wpdb->terms
        INNER JOIN $wpdb->term_taxonomy ON $wpdb->terms.term_id=$wpdb->term_taxonomy.term_id
        INNER JOIN $wpdb->term_relationships ON $wpdb->term_relationships.term_taxonomy_id=$wpdb->term_taxonomy.term_taxonomy_id
        LEFT JOIN $wpdb->posts ON $wpdb->posts.ID=$wpdb->term_relationships.object_id
        WHERE $wpdb->term_taxonomy.taxonomy='model' AND $wpdb->terms.slug='$veh_model_term')";

    $object = $wpdb->get_results($query);
    $cuisine_terms = array();
    for ($i = 0; $i < count($object); $i++) {
        $cuisine_terms[] = get_object_vars($object[$i]);
    }

    echo '<select id="veh_axel_type">' . '<option disabled="disabled" selected="selected">Please choose an axel type...</option>';
    foreach ($cuisine_terms as $term) {
        echo '<option value=' . $term['slug'] . '>' . $term['name'] . '</option>';
    }
    echo '</select>';
}

add_action('wp_ajax_model_select_action', 'implement_model_ajax');
add_action('wp_ajax_nopriv_model_select_action', 'implement_model_ajax');
  • OK, so you have a little problem... Such query will be very inefficient. But, there is a simple solution, because you've made an error earlier on. Yesr, made and model are not three taxonomies. They are different levels of the same taxonomy... You can't have Acura 911, right? ;) – Krzysiek Dróżdż Jul 2 '18 at 21:13
  • @Krzysiek Dróżdż Lol! So, I tried that approach to begin with, but it seemed really inefficient to me. I ended up with some 15,000 terms under the "vehicle" taxonomy and terms were repeated 100's of times: "Acura" was a unique entry under every year, "FWD" is repeated 1000's of times, plus the ajax calls felt like they took longer than they should. This also created issues in that I wanted formatted URLs and the duplicate entries made that really difficult/ugly: /2012/Acura-2/CL-4/FWD-8912. – Zack Jul 3 '18 at 12:43
  • And why do you do that this way? I mean why the first choice is the year? Most of the times it’s make, I guess... And that’s like that because of your current problem ;) – Krzysiek Dróżdż Jul 3 '18 at 13:09
  • :) @Krzysiek Dróżdż, I need it this way because our data is such that in certain years there are no models to be listed under a particular make, so that make should not appear. For example, we have no Aston Martins for the year 2011, so to avoid frustration we need them to tell us year first so we can show them what's available. – Zack Jul 3 '18 at 13:47

Your Answer

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

Browse other questions tagged or ask your own question.