Question: ACF filter custom posts by subfield of repeater field


ACF filter custom posts by subfield of repeater field

Answers 1
Added at 2016-12-26 08:12

I'm following the official guide in ACF documentation but hasn't been able to get it right. I'm using Advanced custom fields and Custom post type UI plugins.

I have a custom post type named materials, each material has a files repeater field, one of the subfield is title. I want to query the posts based on the title and put the results onto the page using ajax.

Here's my functions.php:

function materialsSearchAjax() {

  $html = "";
  $keyword = $_POST['keyword'];
  // args
  $args = array(
    'numberposts'   => -1,
    'posts_per_page' => -1,
    'post_type'     => 'materials',
    'meta_key'    => 'type',
    'meta_value'    => 'students',
    'meta_query'    =>
            'key'       => 'files_%_title',
            'compare'   => 'LIKE',
            'value'     => $keyword,

  $query = new WP_Query( $args );
  $posts = array();
  $html .= '<div class="Materials-students">';

  while( $query->have_posts() ) : $query->the_post();
    $html .= '<div class="Files-list u-padding-left--12">';
      if( have_rows('files') ){
        while ( have_rows('files') ) : the_row();
          $html .= '<div class="Files-item u-margin-right--30 u-margin-bottom--18">';
          $html .= '<div class="Files-itemImage"></div>';
          $html .= '<a href="' . the_sub_field("document") . '" target="_blank" class="Files-itemLink">';
          $html .= the_sub_field('title');
          $html .= '</a>';
          $html .= '</div>';
    $html .= '</div>';

  $html .= '</div>';

  return $html;

// filter
function materials_where( $where ) {

    $where = str_replace("meta_key = 'files_%", "meta_key LIKE 'files_%", $where);

    return $where;

function igs_scripts_styles() {
  wp_enqueue_script( 'ajaxMaterialsSearch', get_template_directory_uri() . '/assets/scripts/ajaxMaterialsSearch.js', array(), false, true );
  wp_localize_script( 'ajaxMaterialsSearch', 'ajax_data_object', array( 'url' => admin_url( 'admin-ajax.php' )) );

add_action('wp_ajax_nopriv_materialsSearchAjax', 'materialsSearchAjax');
add_action('wp_ajax_materialsSearchAjax', 'materialsSearchAjax');
add_filter('posts_where', 'materials_where');
add_action('wp_enqueue_scripts', 'igs_scripts_styles');

Here's my ajax:

(function($) {
  // Trigger submit
  $('.Search-magnifier').on('click', function(){
    var $form = $(this).parent();

  $('.Search-form').on('submit', function(event){
    var $form = $(this);
    var searchKeyword = $($form).find('input[type="search"]').val();
    console.log('keyword: ' + searchKeyword);
      type: 'POST',
      url: ajax_data_object.url,
      data: {action: 'materialsSearchAjax', keyword: searchKeyword},
      success: function(textStatus) {
        // update the content
      error: function(XMLHttpRequest, textStatus, errorThrown) {

The ajax and query work fine if I query all the materials post without filtering the title so the only think that's wrong is the query itself. I followed the guide but been stuck for hours.

nr: #1 dodano: 2016-12-28 17:12

I guess your only mistake is within the meta_query itself. Besides the (optional) first-level relation, a meta_query has to be an array of array(s). Try:

$args = array(
    'posts_per_page' => -1,
    'post_type'      => 'materials',
    'meta_key'       => 'type',
    'meta_value'     => 'students',
    'meta_query'     => array(
            'key'     => 'files_%_title',
            'compare' => 'LIKE',
            'value'   => $keyword,

From WP Codex:

meta_query (array) - Contains one or more arrays with the following keys: […]

I replicated your case (except for the Ajax) and the query worked fine, so I guess this should also work over Ajax calls.

Source Show
◀ Wstecz