Sort a Repeater Field

Last updated May 17, 2023

Overview

This article will cover how to sort a repeater field based on it’s sub field values using a function called array_multisort().

Getting started

The following examples assume a repeater field exists containing 2 sub field; ID (number field) and Name (text field). This repeater field is illustrated below. For the purpose of these examples, we will sort the repeater rows based on the ID, however, the same code could be used in a more ‘real’ situation such as order by name, age, etc.

In both examples, the before and after $value will look the same.

Examples

Basic

This example uses the get_field function to simply load an array of repeater field data, which is then sorted and looped through. Please note that the get_sub_field and the_sub_field functions will not work in this loop.

<?php 

// get repeater field data
$repeater = get_field('repeater');


// vars
$order = array();


// populate order
foreach( $repeater as $i => $row ) {
    
    $order[ $i ] = $row['id'];
    
}


/*

$order should look like this:

Array (
    [0] => 3
    [1] => 2
    [2] => 4
    [3] => 1
)
    
*/


// multisort
array_multisort( $order, SORT_DESC, $repeater );


// loop through repeater
if( $repeater ): ?>

    <ul>

    <?php foreach( $repeater as $i => $row ): ?>

        <li><?php echo $row['id']; ?>. <?php echo $row['name']; ?></li>

    <?php endforeach; ?>

    </ul>

<?php endif; ?>

Advanced

This example uses the acf/load_value filter to reorder the repeater field when it is loaded from the database. This allows the value to be modified for both the front and backend and also allows the get_sub_field and the_sub_field functions to work.

Please note that during this filter, the repeater field $value does not contain nice field names but instead uses the sub field’s key. This is visible when populating the $row variable.

functions.php

function my_acf_load_value( $value, $post_id, $field ) {
    
    // vars
    $order = array();
    
    
    // bail early if no value
    if( empty($value) ) {
        
        return $value;
        
    }
    
    
    // populate order
    foreach( $value as $i => $row ) {
        
        $order[ $i ] = $row['field_55121d86dd2f6'];
        
    }
    
    
    // multisort
    array_multisort( $order, SORT_DESC, $value );
    
    
    // return   
    return $value;
    
}

add_filter('acf/load_value/name=scores', 'my_acf_load_value', 10, 3);
<?php if( have_rows('repeater') ): ?>

    <ul>

    <?php while( have_rows('repeater') ): the_row(); ?>

        <li><?php the_sub_field('id'); ?>. <?php the_sub_field('name'); ?></li>

    <?php endwhile; ?>

    </ul>

<?php endif; ?>

How it works

The array_multisort function uses a “snapshot” array ($row in above examples) to compare and reorder the $value array. This function is not limited to 1 “snapshot” array. In fact, you can use multiple $column variables to sort the data.

Therefore, it is possible to order by one sub field and then by another (ID and Name).

There are a few options for the sorting direction, these are: SORT_ASC, SORT_DESC, SORT_REGULAR, SORT_NUMERIC, SORT_STRING.

Please read more about this function here: http://php.net/manual/en/function.array-multisort.php