Support

Account

Home Forums Front-end Issues Populate select list with values of custom field

Solved

Populate select list with values of custom field

  • I’ve got a CPT of Inventory and I’m trying to show a dropdown of all OEMs. I’ve got the form and pre_get_posts function so that when a user selects an OEM, the page refreshes and shows only the inventory with that OEM.

    THE PROBLEM: Once you select an OEM and the page refreshes, and only that OEM shows as an option! No matter what I try (I won’t post them all here because I have tried like 10 different loops) to build the select options, I can’t get it to show ALL OEMs, all the time.

    I’ve read through several dozen articles (literally) and cannot seem to find a solution that works.

    Here is what I have right now:
    In my functions.php

    function my_pre_get_posts( $query ) {
        // do not modify queries in the admin
        if( is_admin() ) {
            return $query;      
        }
    
        // only modify queries for 'inventory' post type
        if( isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'inventory' ) {
            
            // allow the url to alter the query
            if( isset($_GET['item_oem']) ) {
                $query->set('meta_key', 'item_oem');
                $query->set('meta_value', $_GET['item_oem']);
                $query->set( 'meta_compare', '=' );
            } 
        }
        // return
        return $query;
    }
    add_action('pre_get_posts', 'my_pre_get_posts');
    

    and my loop

    
            <?php // using get right now to see the query string and confirm functionality ?> 
            <form method="get" action="" onchange="submit();">
    
                <?php 
                    $posts = get_posts( array(
                    'post_type' => 'inventory',
                    'posts_per_page' => -1,
                    'orderby' => 'date',
                    'order' => 'DESC',
                ));
    
                if ( $posts ): ?>
    
                <select name="item_oem" id="select-oem">
                    <?php foreach( $posts as $post ): ?>
                        <option value="<?php the_field('item_oem'); ?>"> <?php the_field('item_oem'); ?> </option>
                    <?php endforeach; ?>
                </select>
            <?php endif; ?>
            <?php wp_reset_postdata(); ?>
    
            </form>
    

    How can I retrieve ALL values of the item_oem custom field, regardless of what post is being displayed? I’ve tried resetting the query, the post data, etc without luck.

  • What kind of a field is this field?

  • It’s a text field, added to each inventory post.

  • The purpose of the dropdown is to provide a way to filter the posts on the archive page, by OEM (the custom field value).

  • There are some ways to get a list of all of the values of this field.

    The first is what you are doing, which is time consuming. Get all of the posts and loop through them all and build a list of values.

    
    $values = array();
    if ($posts) {
      foreach ($posts as $post) {
        $value = get_field('item_oem', $post->ID);
        if (!in_array($value, $values)) {
          $values[] = $value;
        }
      }
    }
    

    then you loop over the array that was built do show the options. I would not do this. Querying all of the posts to get the values is a bad idea for performance.

    The second way would be to query the DB directly

    
    // see wpdb for more information. This is dirty for an example
    global $wpdb;
    $query = 'SELECT DISTINCT meta_value
              FROM '.$wpdb->postmeta.' pm, '.$wpdb->posts.' p
              WHERE pm.meta_key = "item_oem"
                AND pm.post_id = p.ID
                AND p.post_type = "inventory"
                AND p.post_status = "publish"
              ORDER BY pm.meta_value';
    $values = $wpdb->get_results($query, 'ARRAY_A');
    

    Then you can loop over these results. This will be faster but can get the job done.

    If it is not too late I would make this oem field a custom taxonomy because taxonomies are built to do and are capable of doing what you want a lot easier and faster.

  • I’ve been tinkering and finally found something that works:

    
    		<form method="get" action="" onchange="submit();">
    			<div class="input-group">
    				<?php
    				global $wpdb;
    				$meta_key = 'item_oem';
    				$data = $wpdb->get_results($wpdb->prepare( "SELECT DISTINCT meta_value FROM $wpdb->postmeta WHERE meta_key = %s", $meta_key) , ARRAY_N  ); ?>
    				<select class="custom-select" id="oems" aria-label="oems" name="item_oem" >
    					<option selected>Search By OEM</option>
    					<?php foreach( $data as $value ): ?>
    						<option value="<?php echo $value[0]; ?>"><?php echo $value[0]; ?> </option>
    					<?php endforeach; ?>
    			  </select>
    			  <div class="input-group-append">
    			    <a href="/inventory" class="btn btn-secondary" type="button">Clear Filter</a>
    			  </div>
    			</div>
    		</form>
    
    

    I’ll definitely look through your suggestions as well, and see which one works the best.. I don’t want to take a hit on performance just for a filter 🙂

    Thank you!

Viewing 6 posts - 1 through 6 (of 6 total)

You must be logged in to reply to this topic.