6

I'd like to display all posts within a given price range. For example: When a user inputs 100 and 1000 (in two separate form fields) - my site will display all posts that have a custom field called price that has a numeric value between 100 and 1000.

Found this under the documentation for WP Query; however, I'm unsure as to how I create a query based on input from a form on my WordPress site.

$args = array(
'post_type' => 'product',
'meta_query' => array(
    array(
        'key' => 'color',
        'value' => 'blue',
        'compare' => 'NOT LIKE'
    ),
    array(
        'key' => 'price',
        'value' => array( 20, 100 ),
        'type' => 'numeric',
        'compare' => 'BETWEEN'
    )
)
);
$query = new WP_Query( $args );

Thank you for your time.

2
  • 2
    have a look at the examples for WP_Query Custom Field Parameters.
    – Milo
    Mar 18, 2013 at 20:30
  • Maybe I need to clarify my question. I'm stuck as to how I connect this query with a form on the front end of my website. Mar 19, 2013 at 3:12

3 Answers 3

6

Use the pre_get_posts action to detect some filter vars in the URL and filter the query accordingly.

For example, say your form sets price_low and price_high GET vars, so the URL looks like:

domain.com/?price_low=100&price_high=1000

Then your filter function checks for the presence of those vars and creates the meta_query. This example is checking if it's the main query on the home page, see the Conditional Tags page for how to check if other types of queries are happening, like a category or tag, etc..

function wpa_filter_home_query( $query ){
    if( $query->is_home()
    && $query->is_main_query()
    && isset( $_GET['price_low'] )
    && isset( $_GET['price_high'] ) ) {
        $meta_query = array(
            array(
                'key' => 'price',
                'value' => array( $_GET['price_low'], $_GET['price_high'] ),
                'type' => 'numeric',
                'compare' => 'BETWEEN'
            )
        );
        $query->set( 'meta_query', $meta_query );
    }
}
add_action( 'pre_get_posts', 'wpa_filter_home_query' );

EDIT- example of a simple form to submit values. Omitting the action attribute will submit the form to the current page.

<form method="GET">
    <input type="text" name="price_low">
    <input type="text" name="price_high">
    <input type="submit">
</form>
5
  • Thanks Milo! The problem I'm having is with setting 'price_low' and 'price_high' GET vars through a form. Can you provide an example of this? Mar 19, 2013 at 11:38
  • see edit above.
    – Milo
    Mar 19, 2013 at 14:47
  • EDIT: just going to ask another question (don't want to get off topic). Mar 21, 2013 at 1:40
  • Totally got this working. Wish I could up-vote you again Milo! Thanks a million. Mar 21, 2013 at 13:06
  • Trying to combine this query with the Multiple Category Selection widget - any ideas as to how I can make it all happen in one query? Right now the user has to submit 2 queries. I've posted another question here: (wordpress.stackexchange.com/questions/91701/…) thank you for your time! Mar 21, 2013 at 13:18
0

I had luck with the Custom Query Fields plugin for this exact issue before.

I'm not 100% sure it will work as it hasn't been updated for a year but it may be worth a go.

1
  • I've used that plugin, and it provides me with the URL that I need. For example, if I use: register_custom_queryable_field("price", array("dataType"=>"numeric")); and then a link like this: http://www.yoursite.com/?price_min=200&price_max=800&order_by=price it will do what I want. The problem I'm having is connecting a web form with this process (I don't want a user to type in a url, or click a link for a pre-determined range. They should be able to set their own numeric values with a form. Make sense? Mar 19, 2013 at 11:32
-1

Thank you Milo some edit in your code

function wpa_filter_home_query( $query ){
    if( $query->is_home()
    && $query->is_main_query()
    && isset( $_GET['price_low'] )
    && isset( $_GET['price_high'] ) ) {
        $meta_query = array(
            array(
                'key' => 'price',
                'value' => $_GET['price_low'],
                'type' => 'numeric',
                'compare' => '>='
            )
        );
        $query->set( 'meta_query', $meta_query );
        $meta_query = array(
            array(
                'key' => 'price',
                'value' => $_GET['price_high'],
                'type' => 'numeric',
                'compare' => '<='
            )
        );
        $query->set( 'meta_query', $meta_query );
    }
}
add_action( 'pre_get_posts', 'wpa_filter_home_query' );
1
  • This is the same anser Milo gave but instead of a BETWEEN statement you use two compare statements. Jun 21, 2013 at 9:45

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.