1

I have SQL table of cities and counties. I need to loop over them and create dropdown with labels. Cities should be an <option> elements and counties wrapper <optgroup>s.

enter image description here

function my_custom_shortcode() {
    global $wpdb;
    $results = $wpdb->get_results( "SELECT city, county FROM slovak_cities" );
    
    $select = '<select name="city_field">';
    
    foreach ( $results as $result ) {

        $city = $result->city;
        $county = $result->county;

        $select .= '<optgroup label="' . $county . '">';
        $select .= '<option value="' . $city . '">' . $city . '</option>';      
        $select .= '</optgroup>';
    }
    
    $select .= '</select>';
    
    return $select;
}
add_shortcode( 'my_shortcode', 'my_custom_shortcode' );

Counties are such groups of cities and should be displayed only one time without duplicating in every iteration. I get results like this:

enter image description here enter image description here

Counties are duplicated and created wrapper of every city every iteration. It should be one county <optgroup> wrapper for all cities associated with it.

So I tried to edit my code, but results are completely wrong:

    global $wpdb;
    $results = $wpdb->get_results( "SELECT DISTINCT city, county FROM slovakia_cities" );
    
    $select = '<select id="city_field" name="city_field" data-required="yes" data-type="select">';
    
    $no_duplicates = array();

    foreach ( $results as $result ) {

        $city = $result->city;
        $county = $result->county;
        
        if ( ! in_array( $county, $no_duplicates ) ) {
            
            $select .= '<optgroup label="' . $county . '">';
            $select .= '<option value="' . $city . '">' . $city . '</option>';      
            $select .= '</optgroup>';
            array_push( $no_duplicates, $county );
        }
    }
    
    $select .= '</select>';
1
  • I don't see where you're setting array_unique() anywhere. Try adding that after the array_push(). In your code you're just adding the county to the array for each iteration of the foreach(), but you're not doing anything to ensure it's not a duplicate. Commented Oct 19, 2022 at 14:11

1 Answer 1

0

This is more of a general PHP question than a Wordpress one.

Use an array with the county as a key to group up your results.

$groups = array();
foreach( $results as $result ) {
    $groups[$result->county][] = $result;
}

var_dump or print_r on $groups to see how this groups up your results.

You can then loop over $groups, if there's only one item in a group you output a single option, when there's more than one then you make an option group.

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.