17

Question: How do you simply count the rows in the output of an ACF repeater field?

Goal: to make the output look different with a css class when there's only one row, vs. more than one row.

My code:

if( have_rows('testimonials')) {
    $counter = 0;
    $numtestimonials = '';

    //loop thru the rows
    while ( have_rows('testimonials') ){
        the_row();
        $counter++;
            if ($counter < 2) {                         
                $numtestimonials = 'onlyone';               
            }
        echo '<div class="testimonial ' . $numtestimonials . '">';
           // bunch of output here
        echo '</div>';                          
    }
}

Obviously, The way I do it here will not work as the count is < 2 the first time thru the row, so it returns true even if more rows are counted after.

Thank you!

Robert
  • 744
  • 1
  • 5
  • 15

8 Answers8

42

OK, I finally found the answer to this.

The way to count total rows in an ACF repeater is:

$numrows = count( get_sub_field( 'field_name' ) );
Robert
  • 744
  • 1
  • 5
  • 15
  • 8
    Thanks. If the repeater is not a sub-field (typical case) then it is just `count( get_field( 'field_name' ) );`. – Space Nov 21 '17 at 16:48
  • Ben (above) is correct also. His comment helped me out. – dustincaruso Mar 18 '18 at 20:31
  • 4
    This still didn't work for me. I have a Repeater within a Flexible Content Layout. The `have_rows`/`the_row` while loop works fine to print the contents of the repeater, but neither `get_sub_field` or `get_field` called on the Repeater name return anything. If I `error_log` the output of `get_sub_field` or `get_field`, I can see both return nothing, which is why I can't get the count. My temporary fix was just to repeat the `have_rows`/`the_row` while loop before the main one just to count all the rows in the Repeater :/ I hate this solution. – mike Feb 27 '19 at 11:54
  • Did you have a fix for this ridiculous unnecessary loop before the content loop? – Mike Wells Oct 09 '20 at 16:27
  • 2
    I have 5 sub fields, yet I get 24, so this no longer seems to work. – Tim Hallman May 06 '21 at 14:28
  • @mike I also have flexible contents, so here is MY solution. I put `$counter = 0;`inside the `while` loop then put **$counter++** in an array `$counters[] = $counter++`, then count the array `count($counters)` and display the number where I want to, THEN, AFTER closing the `endwhile` loop make sure to **RESET** the array `unset($counters);` – maiakd Dec 21 '22 at 10:54
5

It's work for me, count must be placed before if(have_rows('repeater_field') :

Ternary operator to avoid warning errors if repeater is empty

If you place the count after "if(have_rows('repeater_field')) :", count returns FALSE

$repeater_field = get_sub_field('repeater_field');
// OR if repeater isn't a sub_field
// $repeater_field = get_field('repeater_field');

// ternary operator to avoid warning errors if no result
$count =  $repeater_field ? count($repeater_field) : FALSE;

if(have_rows('repeater_field')) : // OR if($count) :

    echo 'Number of posts:' . $count . '<br>';

    while(have_rows('repeater_field')) : the_row();
        echo get_sub_field('field_name') . '<br>';
    endwhile;
endif;
Otis Feru
  • 111
  • 1
  • 4
3

You can get the row count like this:

$count = get_post_meta(get_the_ID(), 'testimonials', true);

Obviously this uses get_the_ID() to retrieve the current post ID - you may need to amend this.

ACF stores the repeater count value against the repeater field name as the meta_key in the postmeta table.

ACF uses the count to retrieve the correct repeater subfield values, which are stored as values against meta_keys with the format $repeaterFieldname . '_' . $index . '_' . $subfieldName.

Hope this helps...

csknk
  • 1,899
  • 1
  • 16
  • 27
  • Thanks David, that is indeed helpful to know how ACF handles it. I'd like to get in the total # of rows though, not just the current row ID. I'm not sure how to pull that off. – Robert May 04 '17 at 17:41
  • 3
    Hi Robert, I think it does exactly what you need. For example, if you have added 4 repeater entries for the 'testimonials' repeater, `get_post_meta(get_the_ID(), 'testimonials', true)` will return '4', not the row ID. – csknk May 04 '17 at 19:20
  • 1
    This comment is underrated - perfectly worked for getting the number of rows my repeater has. – terryeah Jan 23 '21 at 10:39
1

You may wanted to try this..

<?php 
$row = get_field('repeater', $post->ID);
if($row < 1) {
 $rows = 0;
} else {
 $rows = count($row);
} ?>
<p>Number of Row is (<?php echo $rows ; ?>)</p>
1

Advanced Custom Fields has a built in function to count the rows added in version 5.3.4.

Official Documenation: ACF | get_row_index()

You can use get_row_index(); inside the loop.

<?php if( have_rows('slides') ): ?>
    <?php while( have_rows('slides') ): the_row(); ?>
        <div class="accordion" id="accordion-<?php echo get_row_index(); ?>">
            <h3><?php the_sub_field('title'); ?></h3>
            <?php the_sub_field('text'); ?>
        </div>
    <?php endwhile; ?>
<?php endif; ?>

The index returned from this function begins at 1. This means a Repeater field with 3 rows of data will produce indexes of 1, 2 and 3.

Jake
  • 370
  • 4
  • 15
0

Looks like you would want to reset the value in $numtestimonials.

So, effectively, the code with a fix would be:

$output = "";
$numtestimonials = "";

while ( have_rows('testimonials') ){
    the_row();
    $counter++;
    $output .= "<span>" .$some_data. "</span>"; // bunch of output;
}

if($counter < 2){
    $numtestimonials = "onlyone";
}
$output = "<div class='testimonail ".$numtestimonials." '>"
              .$output
         ."</div>";
echo $output;
Dhruv Saxena
  • 1,336
  • 2
  • 12
  • 29
  • Hello, The problem with this solution is that the first row gets the "onlyone" class even if there are more than one total rows. – Robert May 04 '17 at 17:39
  • Hi @Robert. Please see the edited code. It should take care of the situation you describe - just in case there's still something you'd want to do along these lines. Although glad to see that you've yourself found a way get to the row count in advance! – Dhruv Saxena May 04 '17 at 19:25
-1

You can try this code its working fine :

<?php if( have_rows('repeater_name') ):
$my_fields = get_field_object('repeater_name');
$count = (count($my_fields));
echo $count;
endif;?>
-1

ACF Repeater Field uses array to store the rows The simplest way to get the numuber of field rows is

$count = sizeof(get_sub_field('field_name'));
  • 1
    Hi and welcome to SO ! While your answer might be correct, there is already an accepted answer which is almost identical to yours. Try not to post duplicate answers. If the accepted answer is wrong or you have improvements to it, please include more details in your answer. – turbopasi Jan 25 '21 at 09:18
  • when i used count(); php showed warning on the other hand sizeof() of worked without warning. – Majid Shah Jan 25 '21 at 12:40
  • Please include this information in your answer so others might see it better. Also include the warning you get. This would highly improve your answer ! – turbopasi Jan 25 '21 at 12:44