Support

Account

Home Forums Add-ons Repeater Field Avoid duplicate content on repeater field Reply To: Avoid duplicate content on repeater field

  • I’ve recently had to do this myself, otherwise I could not give you an answer. This probably took me a few hours to work out.

    This function will validate any repeater sub field to make sure it’s unique across all rows. Please note that this code is a little obtuse and not easy to follow. It would probably take me several pages to explain what it’s doing, but I hope it helps.

    In this case you need to use the field key version of the acf/validate_value filter https://www.advancedcustomfields.com/resources/acf-validate_value/

    
    add_filter('acf/validate_value/key='.$field_key, 'unique_repeater_sub_field', 20, 4);
    

    Here is the function

    
    function unique_repeater_sub_field($valid, $value, $field, $input) {
      if (!$valid) {
        return $valid;
      }
      
      // get list of array indexes from $input
      // [ <= this fixes my IDE, it has problems with unmatched brackets
      preg_match_all('/\[([^\]]+)\]/', $input, $matches);
      if (!count($matches[1])) {
        // this should actually never happen
        return $valid;
      }
      $matches = $matches[1];
      
      // walk the acf input to find the repeater and current row      
      $array = $_POST['acf'];
      
      $repeater_key = false;
      $repeater_value = false;
      $row_key = false;
      $row_value = false;
      $field_key = false;
      $field_value = false;
      
      for ($i=0; $i<count($matches); $i++) {
        if (isset($array[$matches[$i]])) {
          $repeater_key = $row_key;
          $repeater_value = $row_value;
          $row_key = $field_key;
          $row_value = $field_value;
          $field_key = $matches[$i];
          $field_value = $array[$matches[$i]];
          if ($field_key == $field['key']) {
            break;
          }
          $array = $array[$matches[$i]];
        }
      }
      
      if (!$repeater_key) {
        // this should not happen, but better safe than sorry
        return $valid;
      }
      
      // look for duplicate values in the repeater
      foreach ($repeater_value as $index => $row) {
        if ($index != $row_key && $row[$field_key] == $value) {
          // this is a different row with the same value
          $valid = 'this value is not unique';
          break;
        }
      }
      
      return $valid;
    }