WP_Query with Custom Field Parameter (checkbox)

I’m trying to set up a custom query that returns only posts that do not have a custom meta field checkbox is checked. The checkbox meta field id is position-filled.

Here is the code I have:

Read More
$args = array (
    'post_type' => 'jobs',
    'posts_per_page' => 4,
    'post__not_in' => array(get_the_id()),
    'meta_query' => array(
        array(
            'key' => 'position-filled',
            'value' => 'on', // also tried passing null and removing 'compare'
            'compare' => '!=' // also tried 'NOT LIKE'
        )
    ),
);
$customQuery = new WP_Query($args);

However, this returns no posts (I have made certain there are posts without the checkbox checked.

Any idea what I’m doing wrong?

Related posts

Leave a Reply

1 comment

  1. I’ve run into similar issues when adding custom fields to existing posts/pages where I needed to search on “unchecked” or “unselected” fields.

    It boils down to the fact that the query is actually saying, “Give me posts where the meta key (position-filled) is populated, but not populated with a value of ‘on'”.

    Does it work if you re-save your post with the checkbox being unchecked?

    If so, you might also try using the 'compare' value of 'NOT EXISTS'. Although I believe if you use NOT EXISTS and then someone saves an older post without the checkbox being checked, it will exist (with a blank value).

    [edit]

    I forgot to mention that you can build a query with either situation being true (the NOT EXISTS or it does exist but the value is blank/unchecked).

    $args = array(
        'post_type' => 'jobs',
        'posts_per_page' => 4,
        'post__not_in' => array(get_the_id()),
        'meta_query' => array(
            'relation' => 'OR',
            array(
                'key' => 'position-filled',
                'value' => 'on',
                'compare' => '!='
            ),
            array(
                'key' => 'position-filled',
                'value' => '',
                'compare' => 'NOT EXISTS'
            )
        )
    );
    

    You can chain multiple comparisons together and using the relation property of OR, either one should return true.