0

Source: https://bdwm.be/how-to-create-dynamically-populated-cascading-dropdown-lists-for-contact-form-7/

One cool guy shared his snipped that allows me to create dynamically populated cascading dropdown-lists based on data from .csv file. It works great but the issue is that it only reads first 3 columns (A,B,C)... I have no idea how to add another dropdown after 'years' that will read values from 4th column (D). I'm guessing that the key to resolve that solution is the line below:

$makes_models_years[$line[0]][$line[1]][] = $line[2];

Basically the source code is done only for reading three columns from CSV file. I want to extend it to 4 or even 5 columns. Example here: bdwm.be/wp-content/uploads/2017/12/make-model-year.png

contact form 7 fields

[select makes]
[select models]
[select years]

footer.php

<script>
    (function($) {

        // create references to the 3 dropdown fields for later use.

        var $makes_dd = $('[name="makes"]');
        var $models_dd = $('[name="models"]');
        var $years_dd = $('[name="years"]');


        // run the populate_fields function, and additionally run it every time a value changes

        populate_fields();
        $('select').change(function() {
            populate_fields();
        });

        function populate_fields() {

            var data = {

                // action needs to match the action hook part after wp_ajax_nopriv_ and wp_ajax_ in the server side script.

                'action' : 'cf7_populate_values', 

                // pass all the currently selected values to the server side script.

                'make' : $makes_dd.val(),
                'model' : $models_dd.val(),
                'year' : $years_dd.val()
            };

            // call the server side script, and on completion, update all dropdown lists with the received values.

            $.post('/wp-admin/admin-ajax.php', data, function(response) {
                all_values = response;

                $makes_dd.html('').append($('<option>').text(' -- choose make -- '));
                $models_dd.html('').append($('<option>').text(' -- choose model  -- '));
                $years_dd.html('').append($('<option>').text(' -- choose year -- '));

                $.each(all_values.makes, function() {
                    $option = $("<option>").text(this).val(this);
                    if (all_values.current_make == this) {
                        $option.attr('selected','selected');
                    }
                    $makes_dd.append($option);
                });
                $.each(all_values.models, function() {
                    $option = $("<option>").text(this).val(this);
                    if (all_values.current_model == this) {
                        $option.attr('selected','selected');
                    }
                    $models_dd.append($option);
                });
                $.each(all_values.years, function() {
                    $option = $("<option>").text(this).val(this);
                    if (all_values.current_year == this) {
                        $option.attr('selected','selected');
                    }
                    $years_dd.append($option);
                });
            },'json');
        }

    })( jQuery );
</script>

functions.php

  <?php
    function ajax_cf7_populate_values() {
    
            // read the CSV file in the $makes_models_years array
    
        $makes_models_years = array();
        $uploads_folder = wp_upload_dir()['basedir'];
        $file = fopen($uploads_folder.'\make_model_year.csv', 'r');
    
        $firstline = true;
        while (($line = fgetcsv($file)) !== FALSE) {
            if ($firstline) {
                $firstline = false;
                continue;
            }
            $makes_models_years[$line[0]][$line[1]][] = $line[2];
    
        }
        fclose($file);
    
            // setup the initial array that will be returned to the the client side script as a JSON object.
    
        $return_array = array(
                'makes' => array_keys($makes_models_years),
                'models' => array(),
                'years' => array(),
                'current_make' => false,
                'current_model' => false
            );
    
            // collect the posted values from the submitted form
    
        $make = key_exists('make', $_POST) ? $_POST['make'] : false;
        $model = key_exists('model', $_POST) ? $_POST['model'] : false;
        $year = key_exists('year', $_POST) ? $_POST['year'] : false;
    
            // populate the $return_array with the necessary values
    
        if ($make) {
            $return_array['current_make'] = $make;
            $return_array['models'] = array_keys($makes_models_years[$make]);
            if ($model) {
            $return_array['current_model'] = $model;
            $return_array['years'] = $makes_models_years[$make][$model];
            if ($year) {
                    $return_array['current_year'] = $year;
                }
                }
            }
    
            // encode the $return_array as a JSON object and echo it
            
            echo json_encode($return_array);
            wp_die();
    
    }
    
    // These action hooks are needed to tell WordPress that the cf7_populate_values() function needs to be called
    // if a script is POSTing the action : 'cf7_populate_values'
    
    add_action( 'wp_ajax_cf7_populate_values', 'ajax_cf7_populate_values' );
    add_action( 'wp_ajax_nopriv_cf7_populate_values', 'ajax_cf7_populate_values' );
?>
2
  • What is the 4th value you want to add? Where is it coming from?
    – Howard E
    Commented Jul 10, 2020 at 9:47
  • @HowardE From the .csv file - column "D", same as rest of fields ('makes' from A column, 'models' from B column and 'years' from C column). So I want to add 4th column (D) let's say called 'car_numbers' and I want to make it working same way like 'makes', 'models' and 'years'. Basically the source code is done only for reading three columns from CSV file. I want to extend it to 4 or even 5 columns. Example here: bdwm.be/wp-content/uploads/2017/12/make-model-year.png Commented Jul 10, 2020 at 12:32

1 Answer 1

0

I also had the same issue. I had a csv file of 4 columns. My new column name was 'school'

  1. Replace $makes_models_years[$line[0]][$line[1]][] = $line[2]; with

    $makes_models_years[$line[0]][$line[1]][$line[2]][] = $line[3];

  2. Change $file = fopen($uploads_folder.'\make_model_year.csv', 'r'); to $file = fopen($uploads_folder.'/make_model_year.csv', 'r'); (slash is different)

  3. Add the extra variables for the extra column wherever applicable in both functions.php and footer.php code.

  4. Replace the lower part of functions.php as follows(my new column name was

'school'), just above echo json_encode($return_array);:

$return_array['years'] = array_keys($makes_models_years[$make][$model]);
    if ($year) {
            $return_array['current_year'] = $year;
            $return_array['schools'] = $makes_models_years[$make][$model][$year];
            if($school)
            {
                $return_array['current_school'] = $school;
            }
        }
} }
  1. Add this snippet at the end of footer.php just below

$years_dd.append($option); });

$.each(all_values.schools, function() {
  $option = $("<option>").text(this).val(this);
  if (all_values.current_school == this) {
                    $option.attr('selected','selected');
                }
                $schools_dd.append($option);
            });

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