Support

Account

Home Forums Add-ons Repeater Field Dynamically generate subfield content when adding rows to a nested repeater

Solving

Dynamically generate subfield content when adding rows to a nested repeater

  • I’m starting this thread because my requirement is not covered by the “dynamically generate subfield content” thread.

    I need to set default values for a nested repeater field so that when I add a new row to the parent repeater, then the nested children are spawned with a number of default rows, each containing default values.

    So far, with the answer above what I have managed is for the child repeater to contain the desired rows and default values only when starting a new post; but when I add new rows to the parent repeater, their children repeaters are empty. So these are the ones I need to populate.

    So far, I have achieved this with the following code in my functions.php file:

    add_filter('acf/load_value/key=field_5fabd8c147569',  'acf_load_my_defaults', 10, 3);
    function acf_load_my_defaults($value, $post_id, $field) {
      if ($value === false) {
        $value = array();
        $value[] = array(
            'field_5fabd9c44756d' => array(
                array(
                'field_5fabd9ef4756e' => '20220501',
                'field_5fabda2c4756f' => '20220531',
                'field_5fabda4847570' => ''
                ),
                array(
                'field_5fabd9ef4756e' => '20220601',
                'field_5fabda2c4756f' => '20220630',
                'field_5fabda4847570' => ''
                ),
                array(
                'field_5fabd9ef4756e' => '20220701',
                'field_5fabda2c4756f' => '20220831',
                'field_5fabda4847570' => ''
                ),
                array(
                'field_5fabd9ef4756e' => '20220901',
                'field_5fabda2c4756f' => '20221031',
                'field_5fabda4847570' => ''
                ),
                array(
                'field_5fabd9ef4756e' => '20221101',
                'field_5fabda2c4756f' => '20221231',
                'field_5fabda4847570' => ''
                ),
                array(
                'field_5fabd9ef4756e' => '20230101',
                'field_5fabda2c4756f' => '20230228',
                'field_5fabda4847570' => ''
                ),
                array(
                'field_5fabd9ef4756e' => '20230301',
                'field_5fabda2c4756f' => '20230430',
                'field_5fabda4847570' => ''
                ),
                array(
                'field_5fabd9ef4756e' => '20230501',
                'field_5fabda2c4756f' => '20230531',
                'field_5fabda4847570' => ''
                ),
                array(
                'field_5fabd9ef4756e' => '20230601',
                'field_5fabda2c4756f' => '20230630',
                'field_5fabda4847570' => ''
                ),
                array(
                'field_5fabd9ef4756e' => '20230701',
                'field_5fabda2c4756f' => '20230831',
                'field_5fabda4847570' => ''
                ),
                array(
                'field_5fabd9ef4756e' => '20230901',
                'field_5fabda2c4756f' => '20231031',
                'field_5fabda4847570' => ''
                ),
                array(
                'field_5fabd9ef4756e' => '20231101',
                'field_5fabda2c4756f' => '20231231',
                'field_5fabda4847570' => ''
                ),
                array(
                'field_5fabd9ef4756e' => '20240101',
                'field_5fabda2c4756f' => '20240229',
                'field_5fabda4847570' => ''
                ),
                array(
                'field_5fabd9ef4756e' => '20240301',
                'field_5fabda2c4756f' => '20240430',
                'field_5fabda4847570' => ''
                ),
                array(
                'field_5fabd9ef4756e' => '20240501',
                'field_5fabda2c4756f' => '20240531',
                'field_5fabda4847570' => ''
                ),
                array(
                'field_5fabd9ef4756e' => '20240601',
                'field_5fabda2c4756f' => '20240630',
                'field_5fabda4847570' => ''
                ),
                array(
                'field_5fabd9ef4756e' => '20240701',
                'field_5fabda2c4756f' => '20240831',
                'field_5fabda4847570' => ''
                ),
                array(
                'field_5fabd9ef4756e' => '20240901',
                'field_5fabda2c4756f' => '20241031',
                'field_5fabda4847570' => ''
                ),
                array(
                'field_5fabd9ef4756e' => '20241101',
                'field_5fabda2c4756f' => '20241231',
                'field_5fabda4847570' => ''
                ),
            ),
        );
      }
      return $value;
    }

    The field field_5fabd8c147569 is called “Offers”, and the first child field_5fabd9c44756d is called “Prices”, which is another repeater containing three fields with a start_date, end_date and then a price, which is the only field I’m leaving blank so as to fill it in for every new offer I add. As you can see, I’m populating dates from May 2022 until the end of 2024, in the date(Ymd) format, which would be a pain to do by hand for every offer I add.

    So what do I need to change in my PHP code so that ALL new rows of field_5fabd9c44756d (Prices) inside my field_5fabd8c147569 (Offers) are populated the same as the one that currently appears when creating the new post?

    Many thanks in advance!

  • I’m guessing all I need to do is work out what I’m supposed to change on the conditional “if ($value === false)” which currently only checks if the field is empty when creating the new post, so that it checks if the nested repeater fields are empty upon creation of new child repeaters, and populates them with the default values. Perhaps this needs to be done more like with jQuery than with PHP alone.

  • You can only do this in PHP if all of the sub fields will have the same default value. You really don’t need to add anything if all of the sub fields will have the same value.

    You can only generate sub fields with different values in PHP if you create enough rows in the repeater to hold those values.

    If you want to generate different default values for each row of sub fields then the only way to do that would be to do that using JavaScript/jQuery/Ajax.

    There is not much in the way of examples for doing the last.

  • Hi John, thanks for your reply. Yes, I would like each batch of repeater children to have these exact 19 rows, including all the values as per above. So, basically I’d like that every time we add a new row to the Offers repeater, it automatically appears with the Prices repeater full with these 19 rows that already contain these exact values. How would I go about doing this then?

  • Suggestions and comments in code

    
    // change filter priority > 10
    add_filter('acf/load_value/key=field_5fabd8c147569',  'acf_load_my_defaults', 20, 3);
    
    function acf_load_my_defaults($value, $post_id, $field) {
      // I'm not sure that the value will === false, have you checked this?
      // you might try if(empty($value)) {
      if ($value === false) {
        $value = array();
        // array was nested too deep. You don't need the repeater, just the rows
        $value = array(
          array(
            'field_5fabd9ef4756e' => '20220501',
            'field_5fabda2c4756f' => '20220531',
            'field_5fabda4847570' => ''
          ),
          array(
            'field_5fabd9ef4756e' => '20220601',
            'field_5fabda2c4756f' => '20220630',
            'field_5fabda4847570' => ''
          ),
          array(
            'field_5fabd9ef4756e' => '20220701',
            'field_5fabda2c4756f' => '20220831',
            'field_5fabda4847570' => ''
          ),
          array(
            'field_5fabd9ef4756e' => '20220901',
            'field_5fabda2c4756f' => '20221031',
            'field_5fabda4847570' => ''
          ),
          array(
            'field_5fabd9ef4756e' => '20221101',
            'field_5fabda2c4756f' => '20221231',
            'field_5fabda4847570' => ''
          ),
          array(
            'field_5fabd9ef4756e' => '20230101',
            'field_5fabda2c4756f' => '20230228',
            'field_5fabda4847570' => ''
          ),
          array(
            'field_5fabd9ef4756e' => '20230301',
            'field_5fabda2c4756f' => '20230430',
            'field_5fabda4847570' => ''
          ),
          array(
            'field_5fabd9ef4756e' => '20230501',
            'field_5fabda2c4756f' => '20230531',
            'field_5fabda4847570' => ''
          ),
          array(
            'field_5fabd9ef4756e' => '20230601',
            'field_5fabda2c4756f' => '20230630',
            'field_5fabda4847570' => ''
          ),
          array(
            'field_5fabd9ef4756e' => '20230701',
            'field_5fabda2c4756f' => '20230831',
            'field_5fabda4847570' => ''
          ),
          array(
            'field_5fabd9ef4756e' => '20230901',
            'field_5fabda2c4756f' => '20231031',
            'field_5fabda4847570' => ''
          ),
          array(
            'field_5fabd9ef4756e' => '20231101',
            'field_5fabda2c4756f' => '20231231',
            'field_5fabda4847570' => ''
          ),
          array(
            'field_5fabd9ef4756e' => '20240101',
            'field_5fabda2c4756f' => '20240229',
            'field_5fabda4847570' => ''
          ),
          array(
            'field_5fabd9ef4756e' => '20240301',
            'field_5fabda2c4756f' => '20240430',
            'field_5fabda4847570' => ''
          ),
          array(
            'field_5fabd9ef4756e' => '20240501',
            'field_5fabda2c4756f' => '20240531',
            'field_5fabda4847570' => ''
          ),
          array(
            'field_5fabd9ef4756e' => '20240601',
            'field_5fabda2c4756f' => '20240630',
            'field_5fabda4847570' => ''
          ),
          array(
            'field_5fabd9ef4756e' => '20240701',
            'field_5fabda2c4756f' => '20240831',
            'field_5fabda4847570' => ''
          ),
          array(
            'field_5fabd9ef4756e' => '20240901',
            'field_5fabda2c4756f' => '20241031',
            'field_5fabda4847570' => ''
          ),
          array(
            'field_5fabd9ef4756e' => '20241101',
            'field_5fabda2c4756f' => '20241231',
            'field_5fabda4847570' => ''
          ),
        );
      }
      return $value;
    }
    
  • Hi John, thank you for your reply and for your suggestions. I had just written you an extensive reply and edited it because the images appeared as broken, and now it seems to have vanished, so I’m writing it again! 🙁

    I have changed the priority as advised, many thanks, however if I remove the extra depth in the nested repeaters, then my default Prices no longer appear. Instead, I get 19 Offers, all with empty Prices repeaters inside.

    If I start with my current code, including the extra array depth, then I get a sinlge Offer repeater, with it’s nested Prices repeater containing the desired 19 rows, all populated with the desired dates:

    Screen capture of the correct default values I'm getting inside the nested Prices repeater, which is inside the Offers repeater.

    This part works fine, so I understand that this part of the code is OK.

    My problem is that I want to be able to press the ADD (+) button on the parent Offers repeater, so that it adds a new row, when we will find that one of the contents of the row is the Prices repeater, which I was to appear populated by default with these same 19 rows and their contents.

    I’m guessing the only way to do this is going to be via jQuery, since I can’t alter the function of the ADD (+) button on the Offers repeater.

    Screen capture of the Alert I have managed to generate in jQuery, triggered by the correct Add Row Repeater button.

    I have managed to add a custom event to this exact button simply by locating it using jQuery and then I can make an Alert with an array of all the default values that I want to stick in the new Prices repeater, after it has added 19 rows to itself. I don’t even know if this is possible. I suspect it is, but very, very complicated. Any help is greatly appreciated!

  • You are attempting to update a nested repeater with update_field(), you can’t do this.

    I think you need to loop over the parent repeater and use update_row().

    Or possibly update then entire thing with all the rows of the parent repeater with all then nested repeaters.

    I’m not sure which way you need to go.

Viewing 7 posts - 1 through 7 (of 7 total)

You must be logged in to reply to this topic.