0

I have a table with two dropdown lists. The first one is the brand which is a WordPress custom post type. The second is the flavors which is also a custom post type. Brand is the parent of the flavors. When I choose a brand I need to update the second dropdown list with the flavors of this brand (the children).

I created shortcodes for my lists and they are correctly filled. But I don't know how to filter the second dropdown list when the first one changes.

Here is my table :

 <table id="fla_inf" width="100%">
<tbody>
<tr>
<th class="tab_header" colspan="6">Flavors and Additives</th>
</tr>
<tr>
<th class="tab_header_nam">Flavor Brand</th>
<th class="tab_header_nam">Flavor Name</th>
<th class="tab_header_nam">Dropper type</th>
<th class="tab_header_nam">Quantity Unit</th>
<th class="tab_header_nam">Quantity</th>
<th class="tab_header_nam">Add/Remove row</th>
</tr>
<tr class="flavors">
<td>[brand_list]</td>
<td>[flavor_list]</td>
<td><select id="dropper0" class="dropper">
<option selected="selected" value="type1">type 1</option>
<option value="type2">type 2-3</option>
</select></td>
<td><select id="qtyunit0" class="qtyunit">
<option value="ml">ml</option>
<option value="drops">drops</option>
<option selected="selected" value="perc">%</option>
</select></td>
<td><input id="quantity0" class="quantity" type="number" /></td>
<td><input class="addline" src="http://spitilab.com/wp-content/uploads/2015/01/add.png" type="image" /><input class="remline" src="http://spitilab.com/wp-content/uploads/2015/01/delete.png" type="image" /></td>
</tr>
</tbody>
</table>

here are my shortcodes :

function GetBrandList() {

    $brands = wp_dropdown_pages(array('id'=>'marque0','post_type' => 'marque-type','echo'=>0));
    return $brands;
} 

function GetFlavorList() {

   $flavors = wp_dropdown_pages(array('id'=>'arome0','post_type'=>'aromes-type','echo'=>0));
   return $flavors;
}   

add_shortcode('brand_list', 'GetBrandList');
add_shortcode('flavor_list', 'GetFlavorList');

Here is my update :

I added the following to my functions.php

 add_action( 'wp_ajax_brand_children', 'GetBrandChildren');
add_action( 'wp_ajax_nopriv_brand_children', 'GetBrandChildren');

function GetBrandChildren($parent_id,$id) {
   $children = wp_dropdown_pages(array('id'=>'arome$id','post_type'=>'aromes-type','child_of'=>$parent_id,'echo'=>0));
   return $children;
}

and here is my jquery :

    //On selected brand, update flavors list
$(document).on('change', "select[id^='marque']", function() {

        var $brandid =  $(this).val();
        var $brand_dd_id = $(this).attr('id');
        var $flav_dd_id = $brand_dd_id.substr($brand_dd_id.length-1);
        $("#arome"+$flav_dd_id).empty();

        //Make AJAX request, using the selected value as the GET
        $.ajax({data: '{"parent_id":"' + $brandid + '","id":"'+ $flav_dd_id +'","action":"brand_children"}',
                success: function(output) {
                    alert(output);
                    $("#arome"+$flav_dd_id).html(output);
                }
         });

});

However, my dropdown list of flavor remains empty. In the output showed in the alert, the complete html page seems to be returned.

UPDATE :

add_action( 'wp_ajax_brand_children', 'GetBrandChildren');
add_action( 'wp_ajax_nopriv_brand_children', 'GetBrandChildren');

function GetBrandChildren() {
   $parent_id = $_POST['brandid'];
   $id = $_POST['flav_dd_id'];
   echo wp_dropdown_pages(array("id"=>"arome$id",'post_type'=>'aromes-type','child_of'=>$parent_id,'echo'=>0));
  //ob_clean();
  //echo "working";
  wp_die();
}

// need these two lines to be ale to locate the admin-ajax.php inside jquery
wp_enqueue_script( 'my-ajax-request', get_template_directory_uri() . '/js/ajax.js', array( 'jquery' ) );
wp_localize_script( 'my-ajax-request', 'MyAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );

the JQuery :

//On selected brand, update flavors list
$(document).on('change', "select[id^='marque']", function() {

        var $brandid =  $(this).val();
        var $brand_dd_id = $(this).attr('id');
        var $flav_dd_id = $brand_dd_id.substr($brand_dd_id.length-1);
        $("#arome"+$flav_dd_id).empty();

        //Make AJAX request, using the selected value as the GET
        //var ajax_url = admin_url('admin-ajax.php');
        $.ajax({
                url: MyAjax.ajaxurl,
                data: {
                        'parent_id': $brandid,
                        'id': $flav_dd_id,
                        'action': 'brand_children'
                      },
                success: function(output) {
                    console.log(output);
                    $("#arome"+$flav_dd_id).html(output);
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    alert(xhr.status + " "+ thrownError);
        }});

});

now my second dropdown list is updated.

0

You are going to want to use Ajax to do this to get the second drop-down to load after the first has been selected. I'm not sure about a couple things that you have going on up there, so I'm just going to code this out for you, you may have to change something here or there, I will complete it as well as possible. So the first thing to do is set up an ajax action. This should be setup within a plugin ideally. The is_admin() is used because when the Ajax request is sent from the page with your drop-down list, it will be running under admin. If it feels like we're working backwards, it's just a chicken egg thing. Which came first, the request or the handler... the handler of coarse, which is why I'm starting here.

<?php
if ( is_admin() ) {
    // We add 2 actions, the first is for logged in users, the second for guests.
    add_action( 'wp_ajax_dynamic_dropdown', 'dynamic_dropdown_func' );
    add_action( 'wp_ajax_nopriv_dynamic_dropdown', 'dynamic_dropdown_func' );
}

// This is the function that will handle your Ajax Request/Response
function dynamic_dropdown_func () {
    global $wpdb;
    if (isset($_POST['value'])) {
        $selected_option = $_POST['value'];
        // This will be your second dropdown here, this will be returned in an Ajax request
        $args = array(
            'show_option_none' => __( 'Pick Another One' ),
            'class' => 'dropper',
            'id' => 'dropper0',
            'orderby' => 'ID',
            'order' => 'ASC',
            'hide_empty' => 0,
            'hierarchical' => 1,
            'depth' => 1,
            // This is what will get us the children of first selected option
            'child_of' => (int)$selected_option,
            'echo' => 0,
            // Make sure you switch out this const for your tax
            'taxonomy' => MY_CUSTOM_TAX,
        );

        $my_second_dropdown = wp_dropdown_categories( $args );
        // If you want to do any preg_replace or str_replace, do it here before we do the ob_clean() below         
    }
    //ob_clean is to prevent errors, echos, anything that has outputted to this point in the Ajax WP instance that could ruin your return.
    ob_clean();
    return $my_second_dropdown;
    wp_die();
}

Ok, so now we are going to do the front end part of the code. This is the part that the user will see. When they trigger the Ajax Request, upon response the second dropdown should load. Normally, you would localize a JavaScript file with the variable for the ajax_url and any other PHP values that we need to use in our JS to send Ajax requests to WP. We are going to cheat a little and just print our script out to the page and we will get the same result. Just make sure that you print this script out at the end of the body ideally, or else you will have to add in a document ready function, it wouldn't hurt anyways.

function my_frontend_javascript () {
    $ajax_url = admin_url( 'admin-ajax.php' );
    $javascript = "
        <script>
            var ajaxUrl = {$ajax_url},
            // Now lets grab our dropdowns
                dropdownArome   = jQuery('#arome0'),
                dropdownDropper = jQuery('#dropper0');

            if (dropdownArome.length && dropdownDropper.length) {
                // Good, our elements exist
                dropdownArome.on('change', function (e) {
                    var value = e.target.selectedOptions[0].value,
                        success,
                        data;
                    if (!!value) {
                        // Alright, lets send that value to our Ajax Script, note that the action is the same as the Ajax action hook we used earlier
                        data = {
                            'my_value' : value,
                            'action'   : 'dynamic_dropdown'
                        };
                        success = function ( response ) {
                            // This response will hold our <option>'s
                            dropdownDropper.html( response );
                        };
                        jQuery.post( ajaxUrl, data, success );
                    }
                });
            }
        </script>";
    return $javascript;
}

/** This is where we build our site/form/dropdowns */

$args = array(
    'show_option_none' => __( 'Pick One' ),
    'class' => 'arome',
    'id' => 'arome0"',
    'orderby' => 'ID',
    'order' => 'ASC',
    'hide_empty' => 0,
    'hierarchical' => 1,
    'depth' => 1,
    'echo' => 0,
    // Make sure you switch out this const
    'taxonomy' => MY_CUSTOM_TAX,
);

$my_first_dropdown = wp_dropdown_categories( $args );

// Alright, so now we print out the 2 dropdowns, then the JavaScript from function we wrote above
echo $my_first_dropdown;
echo '<br /><div id="dropper0-container"></div><br />';
echo my_frontend_javascript();

/** That Should be it! Like I said, you will have to tweak some options to fit your site and your implementation. */

So that is how you would do what you are trying to do in what I guess could be one of the simplest ways. I say simplest because we really did no validation, nonce, we pretty much assumed that everything went well. I would suggest reading up on Ajax in WP, even if you know some, it can never hurt to know more. I hope this code works well for you with some tweaking.

http://codex.wordpress.org/AJAX_in_Plugins

http://www.smashingmagazine.com/2011/10/18/how-to-use-ajax-in-wordpress/

  • Hi oneThingSimple, I didn't expect an answer as complete as yours, thank your very for taking time to explain to me. I'm very new to ajax, this is actually the first time I need to use it. I'll try to adapt your answer to what I need, it really helps. Thanks again. Cyrille – user3515709 Feb 5 '15 at 15:10
  • @user3515709 Alright, no problem. Ajax can be a little tricky to work with at first. It would be good for you to be familiar with how the jQuery Ajax Object works. That is the object we mainly use in WP to send out asynchronous requests. As a developer I would say jQuery is worth it's weight alone for the Ajax Object. If you need help, you can contact me, I will try to make it less painful on you as it will be complex until you get your head wrapped around the whole process, then it will become like anything else. So if you get frustrated let me know. – OnethingSimple Feb 5 '15 at 16:36
  • upadted my code, I have a problem with the output. Probably something I got bad. – user3515709 Feb 5 '15 at 16:45
  • @user3515709 I will be done with work in 4 hours. Then if you want me to look at the code I can do that with you. Try to help you to get it working. Either in the chat room here on stackexchange or mail mike@stayshine.com and we can discuss it off of the forum. Good luck. – OnethingSimple Feb 5 '15 at 17:36
  • Still no luck with this. I think there is a problem with my cod but also with my wp_dropdown_pages function because I created a shortcode to display the children of a pecific parent and the dropdown shows : "Main Page (no parent)" – user3515709 Feb 5 '15 at 23:18

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.