Support

Account

Home Forums Backend Issues (wp-admin) Repeater to manage a custom post type

Solving

Repeater to manage a custom post type

  • Hello
    I use a repeater in a “master” post (cpt) to manage (create, update, delete) a child post (cpt).

    If a new entry is created in the repeater and the master is saved, I use “acf/save_post” to loop over the rows and create the child(s). Then I update the field “kurs_id” in the repeater of the master with ID of the created child:


    $id = Id of the new created child post.
    $loop_nr = the number of the repeater row.
    $this->parent_post_id = "master" id (post with the repeater).

    private function ckc_update_parent_post( $id, $loop_nr ) {
    $kurse_repeater = get_field( 'kurse_repeater', $this->parent_post_id );
    for ( $i = 0; $i < count( $kurse_repeater ); $i++ ) {
    if ( $i === $loop_nr ) {
    $kurse_repeater[ $i ]['kurs_id'] = $id;
    }
    }
    update_field( 'kurse_repeater', $kurse_repeater, $this->parent_post_id );
    acf_flush_value_cache( $this->parent_post_id, 'kurse_repeater' );
    }

    Creating and updating works. But when deleting I have a problem with the field kurs_id in the repeater.

    If I delete a child in the repeater, e.g. row 3 of 4, all content of row 4 moves to row 3 but not the value of the kurs_id field.
    For example, row 3 has the kurs_id 33 and row 4 has the kurs_id 44. If I delete row 3 and row 4 becomes row 3, the kurs_id field still shows the value 33 (all other fields have the content of the original row 4).

    Am I making a mistake when I update the kurs_id field or why is only the value of the course_id field not transferred?

    I am grateful for any idea that helps me to fix this problem. Thank you for your help!

  • is kurs_id a sub field of the repeater that was created using ACF?

  • Hi
    Yes, it is a repeater subfield created with ACF (screenshot of the acf reapaeter). My setup is: WordPress 6.2 with roots/sage9, PHP 8.0.28 and the Plugin ACF Pro 6.1.5.

  • Is the field hidden using ACF’s conditional logic?

  • No, first it was set to read-only using ‘acf/load_field/name=kurs_id’ hook and $field['disabled'] = 1;. But this code is currently commented.

  • When editing an ACF repeater in the admin the only reason that ACF would not move a field is if for some resewn the value(s) of a sub field is not submitted when the post is updated. This usually happens when a field is hidden by conditional logic or if a field is disabled.

    Another reason this could be happening could be the priority of your acf/save+post action. Is it > or < 10? Actually I don’t see this as the cause, but sometime strange things happen.

  • I tested with priority 5 and 20 and it made no difference.

    I used the hook acf/validate_save_post to output $_POST in the console. Then I saved a the master again with a new child. But I can’t see a kurs_id field in the output.
    Then I did the same but gave the kurs_id field a default value of 0. Now I can see a the field in the $_POST with the default value. But in the end, this did not solve the problem either.

  • I don’t think I understand the complete process well enough to be able to help more at the moment. Maybe if I have more details, but I don’t know enough to know what to ask for.

  • I understand that well. It is certainly very difficult to understand my approach and the chosen process with my description. I will rethink everything and try again.

    Thank you for your time and advice.

  • I do, in a way, understand what you are doing. I have a setup where I have a repeater field that lets the client add child posts in the same post type. My setup is different.

    On save I have an acf/save_post action that looks at the repeater and compares it with the posts to child posts to see
    1) What has been added
    2) What has been deleted
    and then I add or delete child posts as needed.

    In my case I do not have an ID. the child posts are based on start and end date. If any start/end date combination is new I create a new post and for every existing child post if the start/end date combination does not exist then I delete that post.

    In my case I store all the needed information in the child posts and not in the repeater.

    Have you thought about having a post object field in the child post that points back to the parent instead of a value in the parent that is pointing to the child.

  • Hello John
    Thank you very much for the advice. The setting described is really very similar and the procedure described has brought me further.

    After thinking about it for a while over the weekend, I decided to stick with the ID field. I restarted from scratch and I could fix the problem when deleting a Row and passing the ID field (the ReadOnly code was not commented everywhere…).

    Now I stumble upon another problem. When a Row is duplicated, all values are duplicated (including the ID). So in the repeater loop an ID can appear multiple times and that makes checking what is new/edited/remained the same complicated.

    I thought that the ID field can be defined as unique according to your post (https://tinyurl.com/2dqajbcf). Or is there a way to give the Duplicate button a custom JS function to empty the input field?

    Thanks for the help.

  • The problem is that you are using a repeater, so you need to find out if there are duplicate rows.

    I have an old example of doing this here https://github.com/Hube2/acf-filters-and-functions/blob/master/unique-repeater-sub-field.php

    But, if this is a readonly field then you will need to generate the unique ID in JavaScript. This depends on how you are generating the unique ID to begin with.

  • Thank you for the pointers. I will take a close look at the function on github.

    At the moment I have added another field to the field group. This field is assigned a default value and is set to read-only.
    When saving duplicated rows, the default value of the field is passed on and I can check this in the loop. It’s not a very nice solution but it seems to work.

    Before that I used your function add_filter('acf/validate_value/name='.$field_name,... to declare a field as unique. So there will always be one field unique that can be checked in the loop.

    Maybe there is a more elegant solution?

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

You must be logged in to reply to this topic.