Support

Account

Home Forums Add-ons Repeater Field Bidirectional with repeater issue

Solving

Bidirectional with repeater issue

  • hello

    i have many custom post type
    1- people
    2- events
    3- locations

    and i use repeater field on events like this
    ROW contain :
    – User (post object from people post type)
    – location ( repeater ((nested))
    — location (post object from locations post type)
    — user nickname (text)
    – status (text)

    i try to use (Bidirectional) plugin from ACF extend with this code (https://alf-drollinger.com/bidirectional-relationships-in-acf/)

    to connect the locations and events with the people single page , it work fine BUT when i edit the people single page for any single page the field delete the content .

    is there any way to solve this issue or other way to make it work , i want to show on single-people.php the events and locations that the user was on it

  • I have never seen the article that you linked, but I find it very interesting. I had not thought of the work-a-round suggested making bidirectional relationships work in repeaters. However, I do think it would be a little confusing for some.

    The idea is to, for example, you my plugin to create a bidirectional relationship field at the top level. For example a field named “related_events_people”. This relationship is added at the top level of both the events CPT and the people CTP. This filed will hole all of the relationships between these 2 CPTs. The main purpose of a bidirectional relationship field is to easily find the related posts from either site and this would accomplish this. However, in this case this field will not be editable and it’s value will only be updated dynamically.

    then the idea is that when an events post is saved you loop over the repeater and get the values from the relationship field in the repeater and you push the merged values from the repeater into the top level relationship field. Updating an ACF relationship field automatically triggers my plugin to update the top level relationship field on the the related posts.

    
    add_action('acf/save_post', 'repeater_bidirectional_update', 20);
    function repeater_bidirectional_update($post_id) {
      $update_field = 'field_XXXXXXX'; // field key of top level relationship field
      $collected_posts = array();
      if (have_rows('repeater_field_name', $post_id)) {
        while (have_rows('repeater_field_name', $post_id)) {
          the_row();
          // get the value of the relationship sub field
          // 2rd argument is false, do not format value
          // causes only post IDs to be returned
          $values = get_sub_field('relationship_field', false);
          if (!$empty($values)) {
            if (!is_array($value)) {
              // this check insures the value is an array
              // post object fields return a single value
              $values = array($values);
            }
            // loop over related posts and add them to collected posts
            foreach ($values as $value) {
              if (!in_array(intval($value), $collected_posts)) {
                // add if not added before
                $collected_posts[] = intval($value);
              } // end if
            } // end foreach value
          } // end if !empty
        } // end while have_rows
      } // end if have_rows
      
      // update the top level relationship field
      // with collected posts
      update_field($update_field, $collected_posts, $post_id);
      
    } // end function
    

    You’re obviously going to need to do more because you have a nested repeater, so you’ll need a nested loop and you’ll need to collect posts from 2 separate repeagter sub fields and update 2 top level relationship fields.

    The last step I would take, after I am sure everything is working would be to make the top level field not editable by removing it.

    
    // again, field key of top level field
    add_filter('acf/prepare_field/name=related_events_people', 'my_remove_field');
    function my_remove_field($field) {
      return false;
    }
    
  • hello
    thank you for your respond ,

    i make it work with nested repeater and work fine (for now) BUT the issue that when ever i edit any People record the field that get the content from the other filed delete the value auto .

    i try your code

    // again, field key of top level field
    add_filter('acf/prepare_field/name=related_events_people', 'my_remove_field');
    function my_remove_field($field) {
      return false;
    }

    that hide the field but still when i hit save the changes the fields delete any value was have it on database .

    i bit confuse and try to make it work but i don’t know how to make it work and im not that good with PHP

  • There is not a way to update a specific row of a repeater with a relationship. there isn’t any way to know what row to update. This is beyond the ability. bidirectional relationships are for posts not repeater rows.

  • Just to clarify. The main purpose of creating a bidirectional relationship is to make it easy to query and or get those related posts on the front end for display. For example if you want to show a list of related location when showing an event or a list of related events when showing a location. Without the bidirectional relationship you end up needing a complex and slow query to get those the related posts.

    While being able to edit this from either side is a is a nice bonus, it is not, for me the main purpose.

    In this case, yes, it is possible to create a bidirectional relationship to make front end work easier, however, it will never be possible to edit bidirectional relationships from both sides when one or both of those sides involves a repeater.

    I don’t know what you are building this for, but if editing from both sides is a requirement then I would be looking to find a way to do this without using repeater fields.

  • thank you for your respond, really thank you .

    if i need to change the repeater what the best option i need to use ? this is how i need it to work :
    – each event have people on it and each people have different role on this event so as example

    ————-
    | EVENT | ROLE | LOCATION
    | EVENT 2020 | READER | HALL 1
    | EVENT 2021 | ADMIN. | OFFICE 202
    | EVENT 2022 | ORGANIZER | MAIL HALL

    so i need repeater to add all these on one page , i can do that with this single page but the issue i have is i need to show on people page all events he intend with the role and location .

    if you can help me at least fix the issue with deleting the content on the field when edit any people page .

    thank you

  • Again I have to ask:

    Do you need to display this on the people page on the front end of the site?

    Or must this information be visible in the admin of the site?

  • no need to be shown on back end on people page just front end

  • If you only need it to be on the front end that the above solution will work. You can use the hidden relationship field on the person post to get the list of events they are associated with. The you loop over the repeater of the event posts and show the rows that match that person.

  • thank you .

    i use your code and work fine except the same issue that when i go to edit any person page. the data on the field gone .

  • hello

    i make it work with this code

    
    function prevent_save_acf_value($value, $post_id, $field) {
        return get_field('thisongov', $post_id);
    }
    add_filter('acf/update_value/name=thisongov', 'prevent_save_acf_value', 10, 3);
    
    function dorzki_acf_read_only_field( $field ) {
      if( 'thisongov' === $field['name'] ) {
        $field['disabled'] = true;	
      }
      return $field;
    
    }
    
    add_filter( 'acf/load_field', 'dorzki_acf_read_only_field' );
    
    

    thank you ..

    is there any way to add 2 fields values into one as array ?

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

You must be logged in to reply to this topic.